dimarts, 7 de febrer del 2012

Linux: Programació del Shell

En aquest tercer lliurament d'apunts de Linux antics que vaig trobar en un CD, veiem una introducció a la programació de la shell.

Contingut:
1- Creació de nous comandaments
2 - Paràmetres en els comandaments
3 - Utilitzar la sortida de programes com a paràmetres del nostre programa
4 - Variables de l'entorn

 
1- Creació de nous comandaments
  • Quan tenim una sèrie de comandaments que utilitzem sovint es convenient agrupar los sota un nom apropiat de forma que obtenim un nou comandament.
  • Per exemple, si sovint volem contar els usuaris que estan connectats escriurem:
$ who | wc -l
 
  • Per crear un nou comandament equivalent primer de tot crearem un fitxer de text anomenat cu (de Contar Usuaris) que contingui l'ordre anterior:
$ echo 'who | wc -l' > cu
 
  • Observeu que les cometes són obligatòries. Què obtindríem si no les posem? En el fitxer cu quedaria el nombre d'usuaris connectats en comptes de l'ordre de comptar usuaris.
  • Recordem ara que el shell és un programa que s'està executant, i el seu nom és bash (shell per defecte). Com és un programa, es pot executar i redireccionar la seva entrada.
  • Per exemple, podem executar el shell redireccionant la seva entrada (que per defecte és el teclat) per tal de que sigui el fitxer cu:
$ bash < cu
El resultat serà el mateix que si haguéssim teclejat who | wc -l des del terminal.
  • D'altre banda el shell admet paràmetres, igual que ho fan molts comandaments. Si escrivim:
$ bash cu
    obtindrem el mateix resultat, doncs bash pren la seva entrada d'un fitxer si se'l passa com a paràmetre.
  • Per executar un fitxer de text que conté comandaments, com ara cu, tenim un altre alternativa que és convertir-lo en executable:
$ chmod +x cu
  • Un fitxer executable que conté comandaments del shell s'anomena fitxer d'script del shell o abreviada ment script. Aleshores el podrem executar directament:
$ cu
  • Tal com ho tenim ara cu funcionarà només si està situat en el directori de l'usuari i si aquest directori està en la variable d'entorn PATH. Per fer que funcioni de forma general podem moure'l al nostre directori privat bin i després afegir el camí a la variable PATH:
$ cd                                                       ens situem al nostre directori personal
$ mv cu bin                                            movem cu al nostre directori bin
$ PATH=$PATH:/home/usuari/bin      afegim el nostre bin al camí de cerca
$ echo $PATH                                       comprovem que s'ha afegit correctament
  • Els usuaris d'un script l'executen de la mateixa forma que els altres comandaments i per tant no tenen forma de saber que només conté una simple instrucció, en comptes de ser un complicat programa escrit en 'C'.
  • La forma en que el shell executa un script és creant un nou procés de shell (un subshell) exactament igual que si escrivim $bash cu
  • Per tant bash cu no és el mateix que bash < cu, malgrat el resultat sí ho sigui. En el segon cas no es crea cap subshell.

 

2 - Paràmetres en els comandaments
  • La majoria de comandaments dels shell admeten paràmetres i opcions. Es interessant que els comandaments que nosaltres creem tinguin també aquesta possibilitat.
  • Per exemple volem crear un comandament anomenat fx per fer que un fitxer sigui executable, de forma que sigui equivalent escriure:
$ fx cu
a escriure:
$ chmod +x cu
 
  • Necessitem un fitxer de text que contingui l'ordre chmod. Ja sabem com fer-ho això. El que no sabem és com indicar a fx quin serà el nom del fitxer que farem executable, doncs aquest serà diferent cada cop que executem fx.
  • Quan shell executa un fitxer de comandaments, cada ocurrència de $1 es reemplaça per el primer paràmetre, cada ocurrència de $2 es reemplaça per el segon paràmetre, i així successivament fins el paràmetre $9.
  • Per tant escriurem en el fitxer fx el text chmod +x $1. Veiem el següent exemple:
$ cd; cd bin                                        ens situem en el nostre directori bin personal
$ echo 'chmod +x $1' > fx                 crea el comandament fx
$ bash fx fx                                         el fa executable
$ echo echo "Hola mon" >hola         creem el comandament de proves hola
$ hola                                                  provem hola: no funciona encara
   hola: command not found
$ fx hola                                              fem que hola sigui executable
$ hola                                                  tornem a provar-lo
 
  • Hi tenim també casos en que el nombre de paràmetres és variable, és a dir que de vegades no donarem cap paràmetre en utilitzar el comandament i d'altres en donarem un o més d'un. Per aquests casos tenim l'abreviatura $* que significa "tots els paràmetres". Podríem definir aleshores el comandament fx així:
chmod +x $*
 
  • Exemple: definim el comandament cl per comptar les linies d'un  o més d'un fitxer:
$ echo "#cl: compta el nombre de línies en els fitxers especificats" > cl
$ echo 'wc -l $*' >>cl
$ fx cl
$ cl /home/usuari/bin/*
  • La primera sentencia crea una línia de comentari en el fitxer cl, identificada per el prefix #. En la segona línia afegim (símbol >>) la instrucció de comptar línies. En la tercera donem drets d'execució al fitxer cl i en l'última el provem comptant les líniesde tots els fitxer del nostre directori bin. També funcionarà el següent exemple en el qual no usem cap paràmetre:
$ ls /home/usuari/bin | cl
En aquest cas comptarà quants fitxers hi han en el directori /home/usuari/bin, doncs ls mostra els fitxers que hi han, els quals es prenen com a entrada del programa cl, el qual compta el nombre de lineas del fitxer d'entrada, és a dir, el nombre de fitxers que proporciona ls.
  • El símbol $0 està reservat per el propi nom del programa en execució. Per exemple si afegim la següent línia al fitxer cl:
echo echo === fi execució de $0 === >>cl
i l'executem, veurem que surt al final del nombre de linies del fitxer la frase:
==== fi execució de cl ====
 
  • També podem passar paràmetres que no siguin noms de fitxers. Per exemple considerem el fitxer agenda:
Pere Pages       977-33-44-00
Joan Pages       977-33-50-00
Marta Pages     977-58-00-00
  • Podem usar grep per buscar en ell.  Creem un comandament busca que cerca qualsevol nombre de textos en aquest fitxer i provem-lo:
$ echo 'grep $* /home/usuari/agenda' >busca
$ fx busca
$ busca Pere
Pere Pages       977-33-44-00
$ busca Pages
Pere Pages       977-33-44-00
Joan Pages       977-33-50-00
Marta Pages     977-58-00-00
$ busca 'Pere Pages'
grep: can't open Pages
 
  • Ens trobem un problema a l'executar $ busca 'Pere Pages'  i es que s'interpreta com si haguéssim escrit $ grep Pere Pages /home/usuari/agenda  que està malament doncs pren Pages com un nom de fitxer. Això és així degut a l'espai en blanc que conté la cadena que busquem. Hauríem de passar tota la cadena 'Pere Pages'  com un únic paràmetre per a grep. La solució serà modificar el comandament busca:
$ echo 'grep "$*" /home/usuari/agenda' >busca
  • Ara el $* serà reemplaçat per els paràmetres com abans, però aquests es passaran a grep com un únic paràmetre malgrat tinguin espais en blanc.

 
3 - Utilitzar la sortida de programes com a paràmetres del nostre programa
  • La sortida de qualsevol programa pot utilitzar-se en un comandament tancant el programa amb cometes invertides (l'accent obert català: ` `).
  • Exemple:
$ echo Data i hora actual `date`
Data i hora actual Sun Dec 31 12:00:00 CET 2000
  • Les cometes invertides poden anar també incloses dintre de les cometes dobles:
$ echo "Data i hora actual `date`"
  • Un altre exemple: volem enviar un mail a una llista d'usuaris els noms dels quals estan en un fitxer de text anomenat llista. El text del mail està en un altre fitxer anomenat carta. Podem fer-ho de la següent forma:
$ cat llista                                    comprovem el contingut del fitxer llista
nom1
nom2
nom3
$ mail `cat llista` < carta          enviem la carta als usuaris de la llista
 
cat mostra el contingut del fitxer llista, és a dir la llista de noms, que es converteixen en paràmetres per a mail gràcies a l'ús de les cometes ``. Es com si haguéssim escrit:
$mail nom1 nom2 nom3 <carta
  • En efecte, quan el shell interpreta la sortida en cometes inverses com a paràmetres tracta als salts de línia com a separadors de paraules.





 

4 - Variables d'entorn

  • El shell proporciona el manteniment del que s'anomena variables de l'entorn
  • Són cadenes de caràcters que representen valors que defineixen l'entorn de treball
  • Hi han variables d'entorn predefinides del sistema i pròpies de l'usuari
  • Podem modificar els valors de qualsevol d'elles (en algunes cal tenir prou privilegis)
  • Existeixen moltes variables predefinides que depenen de cada sistema
  • Les variables s'indiquen de la següent forma (sense espais):
        VARIABLE=valor
  • El nom de la variable pot ser qualsevol cadena de caràcters que no comenci per un número ni contingui el caràcter $ ni espais en blanc.
  • El valor pot ser qualsevol cadena, incloent espais. Si conté espais cal tancar la cadena entre cometes dobles ("")
  • Exemples:
$MIVAR="prova variables"
  • Assigna la cadena "prova variables" a la variable MIVAR. Normalment posem el nom de les variables d'entorn en majúscules per distinguir-les dels noms de fitxers i comandaments.
  • Podem veure el contingut de la variable amb:
$echo $MIVAR
  • Mostrarà el contingut de la variable MIVAR. És obligatori col·locar el signe $ davant del nom.
  • Més exemples:
$XYZ="cat fitxer"
$ $XYZ
  • Aquesta seqüència fa que assigni una ordre a una variable. Després s'executa invocant el nom de la variable. Podem utilitzar-ho per abreviar ordres llargues i d'ús freqüent.

export
 
  • Cada variable es defineix en el Shell actiu. Si canviem de Shell (per exemple creant un subshell) la variable deixa d'existir. Podem provar-ho amb la variable XYZ:

$sh                                            arranca un subshell
$echo $XYZ                               no mostra res
 
  • En aquesta seqüència creem un subshell (sh) i cridem a la variable XYZ que ara estarà buida. Per tornar a l'anterior shell:
$exit
$echo $XYZ
 
  • Per poder disposar de la variable en tots els shells, cal exportar-la:
$export XYZ
$sh
$echo $XYZ
  • Aquest exemple d'exportació només és vàlid si es fa des del shell principal. No podem exportar des d'un subshell al seu superior (proveu-ho).
env
 
  • Mostra la llista completa de les variables d'entorn actualment definides.Algunes variables bàsiques són: PATH, LOGNAME, etc.

set
  • Permet també veure les variables d'entorn fins i tot algunes que no apareixen amb env perquè són utilitzades per el propi shell. Per exemple la variable PS1 que representa el "prompt".
$PS1="Linux:"
  • Farà aparèixer el prompt Linux:


Acotació d'arguments en les variables d'entorn
 
  • El Shell interpreta una cadena de caràcters que contingui espais en blanc com múltiples arguments. Per exemple:
$NOMVAR=prova variables
  • Donarà error perquè interpreta dos arguments: prova queda assignat a la variable d'entorn i el segon l'intenta executar com si sigues un comandament.
  • Això ho sol ventem acotant la cadena entre cometes dobles:
$NOMVAR="prova variables"
 
  • No obstant les variables d'entorn contingudes dintre de les cadenes acotades també són interpretades per el shell. Per exemple:
$MEUNOM="El meu nom d'usuari es $LOGNAME"
$echo $MEUNOM
  • Resultat: El meu nom d'usuari és a0alumne
  • Si volem que el shell no interpreti la variable cal acotar la cadena amb cometes simples:
$MEUNOM='El meu nom d'usuari és $LOGNAME'
$echo $MEUNOM


Més coses sobre variables
 
  • Si volem afegir més camins de cerca a la variable PATH:
$PATH=$PATH:nous camins
  • Per combinar el contingut d'una variable amb constants:
$VAR=hola
$echo ${VAR}s
  • Resultat: holas, mostra el contingut de la variable seguida de la constant. Es diferent que fer:
$echo $VARs
    que mostraria el valor de la variable VARs, si existeix.
     
  • Podem avaluar el valor d'una variable i prendre una decisió segons el valor:
$echo ${BUSTIA:-valor2}
 
  • Si la variable BUSTIA existeix mostrarà el seu valor. En cas contrari mostra valor2 sense assignar res a la variable.
$echo ${BUSTIA:=valor2}
  • Si la variable BUSTIA existeix mostrarà el seu valor. En cas contrari mostra valor2 i aquest valor s'assignarà  a la variable.
unset
 
  • Serveix per esborrar el valor d'una variable:
$unset NOMVAR
  • Equivalentment podem fer:
$NOMVAR=
 
 

Utilitzar variables dintre de fitxers script: pas per valor i per referència
  • Hem vist que el valor d'una variable no es passa automàticament als subshells. Això implica que un comandament creat per nosaltres no podrà canviar el valor d'una variable doncs els fitxers scripts són executats per un subshell.
  • Exemple:
$ echo ´X="Adeu"        Creem un fitxer script de dues lineas per a definir i mostrar X
> echo $X´ >setx
$ cat setx                   Comprovem el contingut
$ X=Hola                   Definim la variable X
$ bash setx                 Executem l'script
Adeu                           X conté Adeu en el subshell
$ echo $X
Hola                           X continua valent Hola en el shell original
 
  • Quan passem variables de l'entorn a un fitxer script ho podem fer de dues formes:
    1. Passar només el valor de la variable, però sense que l'script pugui modificar la variable. Diem que el pas de la variable es fa per valor.
    2. Donar a l'script l'accés complert sobre la variable. Diem que passem la variable per referència.
  • Quan exportem (amb export variable) les variables que l'script necessita estem fent un pas de variables per valor. Exemple:
$ export X                    donem accés al valor d'X per a tots els subshells
$ bash                           arranquem un subshell
$ echo $X                     mostrem el valor d'X
Hola
$ X=Adeu                    modifiquem en el subshell el valor d'X
$ echo $X                    mostrem el nou valor en el subshell
Adeu
$ exit                            tornem al shell original
$ echo $X                    mostrem de nou X
Hola                            el valor torna a ser l'original, no s'ha canviat
  • El shell proporciona el comandament ' . ' (un punt) que força l'execució de l'script en el propi shell en comptes de pasar-ho a un subshell. Això equival a donar a l'script l'accés total sobre la variable (pas per referència). Exemple:
$ . setx                        Executem l'script setx en el shell actual
Adeu                           X conté Adeu durant l'execució de l'script
$ echo $X
Adeu                           X ha estat modificat per l'script
 
  • Quan utilitzem el punt per executar un script el que realment succeeix es que l'entrada estàndard del shell (el teclat) es redirecciona temporalment per prendre-la del fitxer script. Realment l'script no s'està executant, i per tant no necessita tenir permisos d'execució.
  • Hi ha un altre forma de passar només el valor d'una variable del shell a un script (pas per valor) a banda d'usar export que es assignar-li el valor en la mateixa línia en la que cridem a l'script. Per exemple:
$ echo 'echo $X' > veureX     Creem un script
$ chmod +x veureX                Donem permís d'execució a l'script
$ X=Hola  veureX                  Inicialitzem X i cridem a l'script en una mateixa línia d'ordres
Hola                                       La variable X val Hola durant l'execució sense haber-la exportat
 
  • Utilitzarem l'execució amb el punt quan volem modificar permanentment el valor d'una variable i utilitzarem les assignacions en la mateixa línia que l'script o bé l'exportació quan les modificacions siguin temporals (només tenen efecte dins de l'script).
Exercicis


Pràctica: Creació de comandaments i pas de paràmetres

1. Crear un comandament anomenat nfind en el vostre directori personal que executa l'ordre
find . -name fitxer -print
on fitxer és un paràmetre. L'execució del nou comandament tindrà la següent sintaxi:
nfind fitxer
Proveu el comandament amb algun fitxer existent en el vostre directori personal redireccionant l'entrada estàndard del shell.
 
 
 
2. Si el comandament nfind funciona correctament, moveu-lo al vostre directori bin i doneu-li drets d'execució. Torneu-lo a provar però ara com a executable. Recordeu que heu de tenir afegit el vostre directori bin al camí de cerca PATH.
 
 
3. Modifiqueu el programa nfind per tal de que accepti múltiples paràmetres. Per exemple:
nfind fitxer1 fitxer2 fitxer3
 
 
4. Modifiqueu el programa nfind per tal de que abans d'executar l'ordre find mostri les següents línies:
echo "nfind: busca i mostra noms de fitxers en el directori actual"
echo "=========================================="
Utilitzeu el comandament cp (copia de fitxers) i el redireccionament >> per afegir aquestes lineas en el fitxer nfind sense necessitat d'usar un procés de text o rescriure'l.

Pràctica: Variables d'entorn. La sortida de programes com a paràmetres.


1. Anem a modificar el "prompt" del sistema utilitzant la variable
d'entorn PS1. Segueix les següents passes:
1.1 Mostra el contingut actual de la variable PS1
1.2 Fes una còpia del contingut de PS1 en la variable PS
1.3 Modifica PS1 per tal de que mostri el teu nom seguit d'un ">".
Per exemple: Pere>
1.4 Comprova que ha variat el prompt del sistema
1.5 Restaura el prompt al seu valor original, utilitzant la variable PS

2. Obre un subshell amb  $ bash. Defineix la variable PROVA=proves . Exporta-la.
Torna al shell original. Existeix la variable? Perquè?
3. Visualitza la variable PATH. Fes una cópia de seguretat en la variable
PATHC. Esborra la variable PATH. Comproba que està buida.
4. Prova de llistar el teu subdirectori. Què passa? Perquè?
5. Prova de llistar el teu directori indicant el camí complert per l'ordre:
/bin/ls . Què passa? Perquè?
6. Restaura el contingut de la variable PATH.
7. Què val la variable HOME? Què passa si fem $ cd $HOME  ?
8. Comprovar el resultat dels seguents comandaments i explicar-los:
$ RUTA = "El meu directori és $HOME"      ; echo $RUTA
$ RUTA = 'El meu directori és $HOME'      ; echo $RUTA
$ RUTA = 'El meu directori és "$HOME" '   ; echo $RUTA
$ RUTA = "El meu directori és '$HOME' "   ; echo $RUTA
$ RUTA = "El meu directori és \$HOME"     ; echo $RUTA

9. Crea una variable d'entorn anomenada BIN que conté la mateixa ruta de la
variable HOME seguida de "/bin" utilitzant els símbols { } per a concatenar.
Què passa si fem $ cd $BIN?
10. Amb una única ordre, fes un $ cd $BIN tenint en compte que si la variable
BIN no existeix, aleshores el comandament cd ha d'anar al teu directori bin
particular. Utilitza els operadors { } per avaluar el valor de la variable BIN
i prendre una decissió segons el valor. Esborra BIN i comproba que el comandament continúa portant-te al teu directori bin.
11. Fes com en l'exercici anterior peró ara si la variable BIN no existeix, el
comandament li assigna el valor correcte (el camí del teu directori bin
 personal). Utilitza el que has fet en els exercicis 9 i 10.
12. Crea un comandament anomenat lloc que mostra uns missatges informant de
l'usuari amb el que estem connectats i el directori actual. Per saber l'usuari
utilitzeu la variable d'entorn USER i per el directori el comandament pwd.
Exemple d'execució:
 
$ lloc
Ets l'usuari a0sanz
Estas en el directori /treball/home/asi20001/a0sanz/docs

Doneu drets d'execució per tothom sobre el fitxer lloc i proveu_lo.
13. Demaneu a un company que provi el vostre programa lloc. Què passa? Com
solucionar-ho?
 

Linux: l'editor de text vi

En aquest segon lliurament d'apunts antics, li toca a l'editor vi; és útil quan administrem un Linux de forma remota amb telnet, i necessitem editar algun fitxer de configuració.

Contingut:
 



Introducció a l'editor vi
  • En Linux existeixen molts editors de text disponibles, com ara l'ex, l'ed, el vi o l'emacs. L'editor estàndard d'Unix System V és el vi.
  • L'editor vi està pensat per a l'ús dels programadors i no pas com a procés de text d'ús general orientat a usuaris. La seva interfície es poc amigable. En el seu disseny s'ha privilegiat la eficiència i no pas l'aspecte. Principalment l'usarem per a escriure scripts (programes del shell) i programes en 'C'.
  • vi funciona en qualsevol sistema Unix-Linux en modus text. En Linux Red Hat hi ha una versió evolucionada anomenada vim. Quan treballem en l'entorn de finestres (X-Windows) serà més eficient traballar amb l'editor emacs.
  • En principi vi sembla un editor molt senzill, peró descobrirem que té un munt de possibilitats i opcions que no podrem estudiar al complert per manca de temps.
  • Per a utilitzar adecuadament un procés de text hem de tenir correctament configurat el tipus de terminal que usem. Aixó ho fem amb la variable d'entorn TERM. Comproveu el seu valor:
$ echo $TERM
linux
Si TERM no conté la paraula linux, aleshores ho arreglem:
$ TERM=linux
$ export TERM
    En entorns UNIX TERM haurà de contindre la paraula ansi.
     
  • Quan treballem en vi sobre un cert fitxer aquest es manté inalterat ja que es crea una còpia en memòria sobre la que es treballa. Només si al sortir donem l'ordre de grabació es modificarà realment el fitxer original.

Com entrar a l'editor
$ vi
- Entra sense nom de fitxer. Escriurem text i donem el nom del fitxer al sortir.
$ vi fitxer
- Edita el fitxer. Si no existeix, el crea.
$ vi fitxer1 fitxer2
- Obra els dos fitxers. Primer mostra fitxer1. Quan tanquem fitxer1 mostra fitxer2. Si els volem editar els dos alhora caldrà crear finestres independents per cadascun (veure l'apartat de finestres més endavant).
$ vi +10 fitxer
- Obra el fitxer i es sitúa en la línia 10. És útil quan estem compilant el fitxer del text d'un programa i sabem que en la línia 10 hi ha un error.
$ vi + fitxer
- Obra el fitxer i es sitúa en la última línea.
$ vi -r fitxer
- Obra el fitxer en modus "recuperació". Útil només si el sistema s'ha penjat mentre modificavem el fitxer i volem recuperar tot el posible a partir de la últimacòpia de seguretat que ha fet el vi.
Modus de funcionament
  • Hi han dos modus de funcionament: el modus ordre i el el modus edició.
  • El modus ordre permet introduir tot tipus d'ordre dirigides a l'editor, com ara esborrar líneas, gravar els canvis, sortir de l'editor, etc. Quan entrem en vi, sempre estem en modus ordre. En modus ordre no podem introduïr text, només admet comandaments.
  • El modus edició permet treballar amb el text del fitxer. Algunes ordres es poden executar directament des del modus edició combinant la tecla CTRL amb altres.
  • Inicialment entrem al vi en modus ordre, pasem a modus edició per a treballar amb el text i després conmutem entre els modus ordre i text per fer modificacions. Finalment quan sortim del vi ho farem en modus ordre.
Tipus d'ordres
  • Totes les ordres s'ha de introduïr en el modus ordre.
  • Hi han dos tipus d'ordres: les ordres de l'editor (com ara sortir del vi) i els comandaments d'edició (com ara esborrar una línea o una paraula).
  • Les ordres de l'editor sempre comencen per dos punts (:) i es mostren en l'ùltima línea de la finestra de l'editor. Per exemple :q per sortir del vi.
  • Els comandaments d'edició per defecte no es mostren: simplement tecleixem el comandament i vi l'executa directament. Per exemple per esborrar la línea de text en la qual està el cursor piquem dos cops la lletra d (dd).

Canvi de mode de funcionament
  • Per canviar de modus ordre a modus edició premem la lletra i (apareix a l'última línea de la pantalla la paraula insert). Podem aleshores introduïr text.
  • Per canviar de modus edició a modus ordre premem la tecla ESC (escape). Desapareix la paraula insert de la pantalla.
Sortir de vi
  • Sortirem sempre des del modus ordre. Les opcions més interesants són:
:q
- Surt del vi sempre i quan no s'hagi modificat el fitxer
:q!
- Surt del vi sense grabar els canvis
:wq
- Guarda el fitxer i surt. El fitxer ha de tenir un nom assignat abans de sortir. Si el fitxer es nou i no té encara nom, primer l'haurem de donar-ne un abans de sortir. Per exemple:
:w fitxer
:q Executar ordres del shell sense sortir de vi
  • Des del modus ordre del vi podem executar programes i ordres del shell. Per exemple per veure els fitxers del directori actual des del vi escribim:

  • :!ls
  • També podem sortir temporalment al shell amb l'ordre :bash
  • Per tornar al vi després de haber sortit temporalment fem $ exit
 
 
 
Edició bàsica 
Moviment per dintre del text
  • En mode edició podem fer servir les fletxes de moviment estàndard del teclat
  • En mode ordre tenim, per exemple (no donem totes les possibilitats), les següents:

  •   j        moure una línia avall
     k       "            "   "       amunt
     0       anar al principi de la línia actual
     $       anar al final de la línia
     G      anar al final del fitxer
    1G    anar al principi del fitxer
    nG    anar a la línia "n" del fitxer. Exemple: 10G anirà a la línia 10
Suprimir caràcters
  • En vi quan suprimim caràcters, paraules o línies el que fem es passar-los a un buffer d'edició, es a dir que de fet no els esborrem sinó que els "retallem".
  • En mode edició, premem la tecla Supr.
  • En mode ordre tenim el comandament x que esborra el caràcter on està el cursor. Podem esborrar un número de caràcters indicant-lo abans. Per exemple 4x esborra quatre caràcters.
Suprimir paraules (modus ordre)
  • Amb el cursor situat en la primera lletra de la paraula premem dw (delete word). Si la paraula acaba en un signe de puntuació (coma, punt i coma, punt, etc) i també el volem esborrar junt amb la paraula premem dW
  • Podem suprimir un número de paraules. Per exemple per suprimir 3 paraules premem 3dw
Suprimir línies (mode ordre)
  • Situem el cursor en qualsevol punt de la línia i premem dd. Per esborrar un nombre de  línies premem 3dd (esborrar 3 línies).
Copiar text (mode ordre)
  • Per copiar la línia actual al buffer premem yy
  • Per copiar "n" línies començant per l'actual premem nyy
  • Per copiar des de la posició del cursor fins el final de la paraula premem yw
Moure text (mode ordre)
  • Primer copiem o esborrem el text, el qual en els dos casos quedarà copiat en el buffer d'edició, i després el recuperem amb el comandament p (paste).
Cerca i substitució de text (mode ordre)
  • Per buscar la propera aparició de la paraula "exemple" premem /exemple
  • Per seguir buscant la següent aparició premem n
  • Per buscar l'anterior aparició de la paraula "exemple" premem ?exemple
  • Per seguir buscant l'anterior aparició premem N
  • Per substituir text utilitzem un ordre de l'editor (recordem que les ordres de l'editor comencen per dos punts) amb la següent sintaxi:
    • :inici,final s/text1/text2/opcions
    - inici és la primera línia del fitxer des d'on comencem a executar l'ordre
    - final és la ultima línia del fitxer que quedarà afectada per l'ordre
    - s és l'ordre de substitució de text
    - text1 és el text a buscar i reemplaçar
    - text2 és el text que reemplaça a text1
    - opcions són paràmetres optatius. El més important és el paràmetre g (la g de global) que indica que efectúe totes les substitucions. Cas de no indicar-lo només efectuaria una substitució per cada línia del text.
    - Exemple: per substituir la paraula gener per febrer des de la línia 10 fins la 20 fem
    :10,20 s/gener/febrer/g
    - Per fer el mateix en tot el fitxer escriurem
    :1,$ s/gener/febrer/gInserir una línia
  • En mode edició premem Intro al principi o al final d'una de les línies existents.
  • Em mode ordre premem la lletra o
Repetició de pulsacions de tecles
  • Si escrivim unes línies (en modus edició) i després les volem repetir, passem a mode ordre (amb ESC) i premem . (punt) amb la qual cosa vi repetirà tot el que hem escrit anteriorment.

Cancel.lació i repetició de l'ùltima acció (modus ordre)
  • Premem la lletra u (undo, desfer acció).
  • Per desfer els canvis efectuats només en una línia premem U
  • Per repetir l'ùltima acció premem . (punt)

 
Buffers 
  • A banda del buffer estàndard d'edició (recordem, buffer: zona de memòria reservada per un programa per realitzar certes operacions habituals) vi en disposa d'altres: els buffers numerats i els buffers alfabètics. Tots ells s'accedeixen des del mode ordre.
  • Els buffers numerats van de l'u al nou. Formen un històric del buffer estàndard d'edició. Quan copiem alguna cosa en el buffer d'edició el seu contingut anterior no es perd sinó que es passa al buffer numerat 1. Si tornem a copiar un altre cosa en el d'edició aleshores el contingut d'u es passa al buffer dos i el d'edició es passa a l'u. Etc.
  • Per recuperar el contingut del buffer n premem, en modus ordre, np
  • Si només volem veure el contingut del buffer n primer premem np (copiar) i després u (desfer)
  • Els buffers alfabètics són d'ús particular de l'usuari. Hi han 26, des de l'a fins el z.
  • Per accedir a un buffer tenim la següent sintaxi: "xOrdre
- "           és el prefix que indica que accedim a un buffer alfabètic
- x           és la lletra que identifica al buffer
- ordre    indica qué és el que fem amb el buffer
  • Exemples d'ús dels buffers alfabètics:

  • - Per copiar (ordre Y) la línia actual al buffer a premem "aY
    - Per recuperar (ordre p) el contingut del buffer b premem "bp
    - Per esborrar la línia actual (ordre dd) i copiar-la en el buffer c premem "cdd 
    - Per esborrar la paraula actual (ordre dw) i copiar-la en el buffer z premem "zdw



 
Finestres
  • Podem dividir la finestra de l'editor en dues o més subfinestres que poden mostrar el mateix fitxer o bé diferents fitxers. És útil quan volem copiar part del contingut d'un fitxer en un altre (per exemple per aprofitar una part d'un programa en un altre). Habitualment no treballarem amb més de dues subfinestres.
  • Els comandaments de finestres s'accedeixen amb la combinació de tecles CTRL simultàniament amb la lletra w ( de windows, finestra en anglès). Abreviadament: CTRL + w (el signe + no es part del comandament, simplement indica que hem de prémer les dues tecles simultàniament).
  • Cada comandament tindrà, doncs, la sintaxi CTRL + w comandament
  • Per dividir la finestra actual en dues subfinestres idèntiques premem CTRL + w s  (la s vé de split, partir en anglès)
  • Per anar a la finestra superior premem CTRL + w j
  • Per anar a la finestra inferior premem CTRL + w k
  • Per tancar la finestra actual fem com si sortíssim del vi, premem :q o bé :wq o bé :q!
  • Per iniciar vi amb dues finestres: $ vi -o 2
  • Per editar un fitxer anomenat text en la finestra actual premem :e text

 
 
Opcions. Inicialització i configuració de l'editor
  • vi permet personalitzar el seu comportament modificant el valor de les seves variables d'entorn. Algunes d'aquestes variables són de tipus lògic: estàn activades o desactivades. Per canviar el valor de les variables tenim el comandament :set variable
  • Per veure totes les possibles opcions (hi han moltes!) premem :set all
  • Amb set all es mostren totes les opcions numèriques, de text i només les lògiques que estiguin activades
  • Per activar una opció lògica premem :set opció
  • Exemple: el mode edició s'indica per la paraula Insert degut a que la variable showmode està activada.

  • - Per desactivar-la premem :set noshowmode
    - Per tornar-la a activar premem :set showmode
  • Una opció interesant és la que activa la visualització dels comandaments d'edició que per defecte no es mostren mentre els premem. Per activar la visualització fem :set showcmd i per desactivar-la fem :set noshowcmd
  • Els canvis fets amb set no són permanents sinó que per el contrari només valen per la sessió actual d'edició. En surtir del vi es perden.
  • Si volem que una opció duri tota la nostre sessió (des de l'inici de la nostra connexió fins que fem exit per sortir) la definirem en la variable d'entorn EXINIT. Per exemple:

  • $ EXINIT='set showcmd'
    $ export EXINIT
  • Amb EXINIT les opcions es perden quan ens desconnectem del sistema.
  • Quan volem que les opcions siguin permanents, o bé tenim moltes opcions personalitzades, utilitzarem el fitxer d'inici del vi anomenat .exrc (els noms de fitxers que comencin per un punt solen estar reservats per fitxers d'inicialització com a norma). Per exemple des de la línia d'ordres del shell fem:
$ cat >.exrc            creem el fitxer d'inici del vi
set showcmd           opció 1: mostrar comandaments de l'editor
set visualbell          opció 2: quan passem del final del text la finestra farà "pampallugues"
set noshowmode     opció 3: no mostra Insert en el mode edició
CTRL+d                  fi del fitxer
$ vi                          entrem en vi per comprovar
:set all                    comproveu els valors de les opcions anteriors
  • Quan utilitzem simultàniament EXINIT i .exrc hem de tenir en compte que s'exclouen un a l'altre. En alguns sistemes el primer anul·la al segon (cas del Linux Red Hat per exemple) i en altres es a l'inrevés (cas de l'Unix System V).

 
 
L'ajuda de vi
  • vi té un sistema d'ajuda prou complert, malauradament està en anglès
  • Per accedir a l'ajuda en general premem en mode ordre :help
  • Per demanar ajuda sobre un comandament premem en mode ordre :help comandament
  • En una de les primeres pàgines de l'ajuda trobem un índex on les paraules temàtiques estan entre signes <,>.
  • Per "saltar" a l'ajuda sobre un tema situem el cursor sobre el tema i premem CTRL + ]
  • Per tornar enrere premem CTRL + t
  • Per sortir de l'ajuda premem :q



 Exercicis

  Pràctica: Introducció a vi


1. Crea en el teu directori personal un subdirectori docs per enmagatzemar fitxers de text. Situat dintre d'aquest subdirectori.
 
  2. Entra a l'editor sense especificar cap nom de fitxer. Introdueix el següent text, prement INTRO al final de cada línea:
L'editor estàndard d'UNIX es diu vi
L'editor vi és una evolució de l'editor ex
ex és un editor de líneas mentre que vi és un editor de pantalla
 
 
3. Guarda el fitxer al disc amb el nom primer.doc i surt del vi.
 
4. Comprova el contingut del text amb el comandament cat.
 
5. Torna a entrar en vi per modificar el fitxer primer.doc situant-te en l'ùltima línea. Afegeix el següent text després de l'ùltima línea:
vim és la versió Linux de l'editor estàndard vi
 
6. Sense sortir del vi, fes una còpia del fitxer primer.doc en el fitxer segon.doc
 
 
7. Salva el fitxer i surt del vi.
 
8. Comprova el contingut dels fitxer primer.doc i segon.doc . Són iguals? Perquè?

Pràctica: Edició bàsica en vi


1. Obre el fitxer docs/primer.doc
  2. Amb l'ordre corresponent, situat al final de la línia 3 del text
 
3. En la línia anterior i sense sortir del mode ordre, suprimeix la paraula pantalla
 
4. Copia el contingut de la línia 3 a la línia 1
 
5. Ves a la línia 4 i afegeix al final de la línia tres asteriscs "***"
 
6. Amb l'ordre corresponent, cerca totes les aparicions en el text de la paraula vi
 
7. Amb l'ordre corresponent, substitueix la paraula vi per la paraula vim en el text des de la
línia 1 fins la 3
 
8. Desfés els canvis realitzats en l'anterior exercici
 
9. Còpia les 3 primeres línies del fitxer al final del text
 
10. Guarda el text i surt del vi.
 
Pràctica: buffers i finestres de vi



1. Obre el vi per editar el fitxer primer.doc amb dues finestres
  2. Activa la segona finestra i obre en ella el fitxer segon.doc
 
3. Activa la primera finestra.
 
4. Còpia les línies primera i segona de primer.doc en el buffer alfabètic a
 
5. Activa la finestra de segon.doc
 
6. Ves a l'ùltima línia. Recupera el contingut del buffer alfabètic a
 
7. Ves a la primera línia de segon.doc i esborra-la.
 
8. Activa la finestra de primer.doc
 
9. Ves directament a la segona línia i recupera la línia que has esborrat en segon.doc
 
10. Guarda primer.doc i tanca la seva finestra
 
11. Surt de segon.doc sense guardar els canvis
 
 

Linux: comandaments relacionats amb fitxers

Remenant CD's hi trobat una còpia de seguretat dels apunts que vaig prepara per una assignatura de sistemes operatius, ja fa temps, però els comandaments de Linux encara són els mateixos. Per aixo, faré alguns posts on recuperaré aquest material i el poso a disposició de la xarxa.


mkdir
 
  • Crear directoris. Sintaxi: mkdir directori
  • Exemples:

  • $mkdir dades
    - Crea el directori dades en el directori actual
    $mkdir dades/textes
    - Crea el directori textes dintre del directori dades
rm
 
  • Esborrar fitxers.
  • Exemples:

  • $rm dades/textes/agenda
    - Esborra el fitxer agenda que està en el directori textes, que a la seva vegada està dintre de dades.
    $rm dades/textes -r
    - Esborra el directori dades/textes i tots els fitxers que contingui. Ull! no demana confirmació!
    $rm dades -f
    - Esborra el fitxer dades i demana confirmació abans de fer-ho (opció -f)
rmdir
 
  • Esborrar directoris
  • El directori que anem a esborrar ha de estar buit
  • Exemples:

  • $rmdir dades/textes
    - Esborra el directori dades/textes si està buit, altrament dóna error
    $rmdir dades -p
    - Esborra el directori dades i tots els directoris que contingui, sempre i quan no continguin fitxer
cp
  • Copiar fitxers. Sintaxi: cp [opcions] origen destí
  • Exemples:

  • $cp fitxer1 fitxer2
    - Còpia exacta del fitxer1 al fitxer2. Si fitxer2 no existeix, el crea.
    $cp fitxer1 fitxer2 dir1
    - Còpia fitxer1 i fitxer2 dins el directori dir1. El directori ha d'existir.
    $cp dir1/* .
    - Copia tots els fitxers de dir1 en el directori actual. No es pot posar el nom
       del directori sense posar els fitxers, en aquest cas tots (/*)
       
mv
  • Moure fitxers. Sintaxi: mv [opcions] origen destí
  • Exemples:

  • $mv fitxer1 fitxer2
    - Equival a canviar de nom fitxer1. Si fitxer2 ja existía, quedarà sobreescrit.
    $mv fitxer3 dir1
    - Mou fitxer3 al directori dir1. Despareix fitxer3 del directori actual.

more
  • Veure fitxers paginats
  • Al final de la pantalla mostra el percentatge de fitxer mostrat. Podem seguir amb

  • ENTER per moure línia a línia i amb ESPAI per moure pantalla a pantalla.
    Podem sortir amb q.
  • Exemples:

  • $more fitxer5
    - Mostrar el contingut de fitxer5 paginat.
    $more -c fitxer5
    - Mostrar fitxer5 esborrant la pantalla cada salt de pàgina
    $more -5 fitxer5
    - Mostrar fitxer5 amb 5 líneas per pàgina
    $more +10 fitxer5
    - Mostrar fitxer5 a partir de la línia 10
    $more -5 +10 fitxer5
    - Mostrar fitxer5 a partir de la línia 10 amb 5 líneas per pàgina

cat
  • Mostrar contingut, crear i concatenar fitxers
  • Exemples:

  • $cat -v fitxer5
    - Mostrar el contingut de fitxer5. Si fitxer5 és un fitxer executable amb l'opció -v no
      s'executarà. En cas contrari, sí.
    $cat fitxer5 fitxer6 >fitxer7
    - Concatena fitxer5 i fitxer6 dins fitxer7. Si fitxer7 existeix, es sobreescriurà.
file
  • Mostrar tipus del fitxer indicat (de text, programa executable, directori, etc.)
  • Exemple:

  • $file nota
    - Indica quin tipus de fitxer és nota

find
  • Localitzar un fitxer en l'estructura de directoris segons les opcions de recerca indicades
  • Exemples:

  • $find nota -print
    - Busca el fitxer nota en el directori actual. Si el trova, mostra el seu nom gràcies a l'acció -print.
      En Linux Red Hat, per defecte sempre es mostra el nom malgrat no indiquem -print.
    $find . -name nota -print
    - Busca el fitxer nota en el directori actual i tots els seus subdirectoris.
    $find .. -name nota -print
    - Busca el fitxer nota en el directori superior a l'actual i en els seus fills
    $find / -name -print
    - Busca el fitxer nota començant per el directori arrel en tot el sistema (li costa molt!). Cal tenir permís
      de lectura del directori arrel. Podem aturar la recerca amb CTRL + C
    $find / -group bin -print
    - Busca els fitxers que pertanyen al grup d'usuaris bin començant per el directori arrel.
    $find . -user alumne -print
    - Busca els fitxers que pertanyen a l'usuari alumne en el directori actual i els seus subdirectoris
    $find . -type d -print
    - Busca els fitxers de tipus "d" (directoris) en el directori actual i els mostra. Podem fer servir:
                            "d" per directoris
                            "b" fitxers de blocs de bytes
                            "c" fitxers de caracters (textes)
    $find . -perm 755 -print
    - Busca els fitxers que tinguin els permisos 7 per el propietari del fitxer, 5 per al grup i 5 per la resta
      d'usuaris. És a dir, aquells que al fer un ls -l tendrían els permisos rwxr_xr_x. La nomenclatura seguida és:
                            4  -> permís de lectura (r)
                            2  -> permís d'escriptura (w)
                            1  -> permís d'execució (x)
    La suma dels anteriors valors dóna els permisos efectius. Per exemple, 7 = 4 + 2 +1 equival a tenir els permisos
    rwx (tots) mentre que 5 = 4 + 1 equival a tenir els permisos r_x (lectura i execució).
    $find . -name nota -print -ok rm {} \;
    - Busca el fitxer nota en el directori actual i tots els seus subdirectoris. Si el troba, el mostra (-print) i demana
    permís per executar el comandament rm (esborrar fitxer). Aquesta sol.licitud (que haurem de respondre amb
    "y" o "n") la produeix el paràmetre -ok. Els espais en blanc s'han de respectar.
    Aquestes sentències s'han d'acabar amb {} \;
    Aixó significa: {} substitueix el nom del fitxer indicat en find, i els signes \; produeixen una "sequència d'escape"
    per tornar a l'indicador del shell ($).
    $find / -name cal -print -ok cal \;
    - Busca des de l'arrel el fitxer anomenat cal i quan el troba demana permís per a executar-lo (-ok) . La senténcia
    acaba amb la sequència d'escape \; però sense el símbol {} doncs el comandament cal no necesita paràmetres.
    Cal tenir permís de lectura en el directori arrel.
    find /treball/home/jcuesta/bin -name cal -print -ok cal \;
    - Igual que abans però busca el fitxer cal en el directori /treball/home/jcuesta/bin.
    find /treball/home/jcuesta/bin -name cal -print -ok {} \;
    - Igual que l'anterior: {} substitueix el nom del fitxer cal.
    find /treball/home/jcuesta/bin -name cal -print -exec cal \;
    - Igual que l'anterior però no demana conformitat. L'executa directament.
grep (introducció)
     
  • Busca patrons (paraula o conjunts de paraules, signes, etc) dins d'un o més d'un fitxer.
  • Encara que no és sempre necesari, és convenient tancar el patrò entre cometes simples ' '
  • Exemples (per fer proves crear un fitxer anomenat fitxer1 amb la frase: hola, estic matriculat en ASI)

  • $grep 'hola' fitxer1
    - Busca la paraula hola en el fitxer fitxer1, si el troba mostra la línia sencera que conté la paraula. Si no la troba
      no diu res.
    $grep -c 'hola' fitxer1
    - Compta les línies de fitxer1 que continguin la cadena hola.
  • Altres opcions:

  • -v    Busca les líneas que no continguin la cadena
    -l    Indica quins fitxers tenen el patró. Només surten els noms del fitxers
    -i    No discrimina entre majúscules-minúscules
  • Podem utilitzar els metacaracters per a formar expressions regulars (descripcions de cadenes de text

  • que permeten comparacions molt potents). Els metacaracters són els següents:
         Representa qualsevol caràcter o caràcters en el lloc on estigui.
            Exemple:
            $grep mat. fitxer1
            - Mostra les línies que continguin paraules que comencin per  mat  dins de fitxer1. Si tenim la paraula
            mat en el fitxer1, no la mostrarà ja que no hi ha cap caràcter després de la cadena mat. En canvi sí
            mostrarà matricula, mata, matorral, etc. *      Representa zero o més ocurrències d'un caràcter o una cadena.
            Exemple:
            $grep mat* fitxer1
            - Mostra les línies que comencin per ma seguit de zero o més "t"
    ^      Coincidència al principi de línia.
            Exemple:
            $grep '^hola' fitxer1
            - busca les línies que comencim per hola
    $      Coincidència al final de la línia.
            Exemple:
            $grep 'hola$' fitxer1
            - Mostra les línies que acabin en hola
    []      Coincidència amb un rang.
            Exemples:
            $grep '^[a-z]12' fitxer1
            - Busca les línies que comencin per una lletra minúscula ( [a-z] ) seguides dels dígits 12
               dins el fitxer fitxer1.
            $grep '^[^a-z]' fitxer1
            - Busca les línies que no comencin per lletra minúscula. Aixó ho fa el símbol ^ dintre dels []
    \       Caràcter d'anul.lació. S'utilitza per anul.lar el significat especial dels metacaràcters. Per exemple
            si volem cercar un punt dins una cadena hem de posar  \.
            Exemple:
            $grep '\.$' fitxer1
            - busca les línies que acabin en un punt
     
     
     
fgrep
  • Variant de grep que només accepta una cadena simple, no admet expressions regulars ni $, ni ^.

  • En canvi permet la recerca de múltiples patrons.
  • Exemple:

  • $fgrep "hola
    >que
    >tal" fitxer
    - Busca els tres patrons hola, que, tal per separat dins de fitxer
egrep
  • Variant de grep encara més potent, permet recerques més complexes.És però més lent que grep.
  • Exemples:

  • $egrep "hola|que|tal" fitxer
    - Busca els tres patrons dins de fitxer
    $egrep "([0-9]+ab)*1234" fitxer2
    - Busca les cadenes que comencin per 1 o més dígits ([0-9]+), seguits d' "ab", seguit d'un altre seqüència d'un o
      més dígits seguits d' "ab", etc. fins que trobi una cadena "1234" en fitxer2.
     
Vincles simbòlics i fitxers vinculats
  • Són fitxers que estan vinculats a altres
  • Permet que diversos usuaris comparteixen un únic fitxer físic
  • Quan s'obre un vincle simbòlic a un fitxer, només llegeix el camí del fitxer i després obra aquest
  • No es poden vincular fitxers de diferents File System (particions)
  • Quan obrim i modifiquem un fitxer vinculat, les modificacions afecten també al fitxer original
  • Si fem ls -l els fitxers que són vincles simbòlics es marquen amb una l en el primer caracter dels permisos

  • (bit de tipus de fitxer) i s'indica també el fitxer al que apunten.
  • Exemples:
$ln -s dades vincle.dades
- Crea un vincle simbòlic (opció -s) anomenat vincle.dades que apunta al fitxer vincle
$ln dades dades2
- Crea una còpia del fitxer dades en dades2 i vincula els dos fitxers 

Exercicis
1. Crea dins del teu directori inicial la següent estructura de directoris. Cal crear també els fitxers docu1, docu2, docu3.
 

 
 
2. Comprova, amb les ordres corresponents, si s'ha creat correctament l'estructura i els fitxers.
3. Situar-se al directori dir11 i esborrar el directori dir111.
4. Situar-se al directori inicial. Comprovar-ho.
5. Situar-se al directori dir22. Esborrar el fitxer docu3.
6. Situar-se al directori dir2. Comprovar.
7. Torna al directori propi. Esborra tota la branca corresponent a dir2.
8. Llista tots els fitxers del directori damunt del teu utilitzant els dos punts (..) amb el comandament ls.
9. Quins dels següents noms de fitxers són vàlids?
    123.***          .prova        '.'.prova        ##.***
 

Gestió d'usuaris i grups en Linux

Usuaris i grups Linux  Els comptes de Linux són com els comptes de Windows o MacOS; però els detalls no, així que cal explicar alguns detall...