Guida avanzata di scripting Bash: Un'approfondita esplorazione dell'arte dello scripting di shell | ||
---|---|---|
Indietro | Avanti |
Caratteri speciali che si trovano negli script e non solo
Commenti. Le righe che iniziano con # (con l'eccezione di #!) sono considerate commenti.
# Questa riga è un commento. |
I commenti possono anche essere posti dopo un comando.
echo "Seguirà un commento." # Qui il commento. # ^ Notate lo spazio prima del # |
Sono considerati commenti anche quelli che seguono uno o più spazi posti all'inizio di una riga.
# Questo commento è preceduto da un carattere di tabulazione. |
Non è possibile inserire, sulla stessa riga, un comando dopo un commento. Non esiste alcun metodo per terminare un commento in modo che si possa inserire del "codice eseguibile" sulla stessa riga. È indispensabile porre il comando in una nuova riga. |
Naturalmente, un # preceduto da un carattere di escape in un enunciato echo non verrà considerato come un commento. Inoltre, il # compare in alcuni costrutti di sostituzione di parametro e nelle espressioni con costanti numeriche.
|
Anche alcune operazioni di ricerca di corrispondenza utilizzano il #.
Separatore di comandi [punto e virgola]. Permette di inserire due o più comandi sulla stessa riga.
echo ehilà; echo ciao if [ -x "$nomefile" ]; then # Notate che "if" e "then" hanno bisogno del #+ punto e virgola. Perché? echo "Il file $nomefile esiste."; cp $nomefile $nomefile.bak else echo "$nomefile non trovato."; touch $nomefile fi; echo "Verifica di file completata." |
Si faccia attenzione che ";", talvolta, deve essere preceduto da un carattere di escape.
Delimitatore in un'opzione case [doppio punto e virgola].
case "$variabile" in abc) echo "\$variabile = abc" ;; xyz) echo "\$variabile = xyz" ;; esac |
Comando "punto" [punto]. Equivale a source (vedi Esempio 14-21). È un builtin bash.
"punto", componente dei nomi dei file. Quando si ha a che fare con i nomi dei file si deve sapere che il punto è il prefisso dei file "nascosti", file che un normale comando ls non visualizza.
bash$ touch .file_nascosto bash$ ls -l total 10 -rw-r--r-- 1 bozo 4034 Jul 18 22:04 data1.addressbook -rw-r--r-- 1 bozo 4602 May 25 13:58 data1.addressbook.bak -rw-r--r-- 1 bozo 877 Dec 17 2000 employment.addressbook bash$ ls -al total 14 drwxrwxr-x 2 bozo bozo 1024 Aug 29 20:54 ./ drwx------ 52 bozo bozo 3072 Aug 29 20:51 ../ -rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.addressbook -rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.addressbook.bak -rw-r--r-- 1 bozo bozo 877 Dec 17 2000 employment.addressbook -rw-rw-r-- 1 bozo bozo 0 Aug 29 20:54 .file_nascosto |
Se si considerano i nomi delle directory, un punto singolo rappresenta la directory di lavoro corrente, mentre due punti indicano la directory superiore.
bash$ pwd /home/bozo/projects bash$ cd . bash$ pwd /home/bozo/projects bash$ cd .. bash$ pwd /home/bozo/ |
Il punto appare spesso come destinazione (directory) nei comandi di spostamento di file.
bash$ cp /home/bozo/current_work/junk/* . |
"punto" corrispondenza di carattere. Nella ricerca di caratteri, come parte di una espressione regolare, il "punto" verifica un singolo carattere.
quoting parziale [doppio apice]. "STRINGA" preserva (dall'interpretazione della shell) la maggior parte dei caratteri speciali che dovessero trovarsi all'interno di STRINGA. Vedi anche Capitolo 5.
quoting totale [apice singolo]. 'STRINGA' preserva (dall'interpretazione della shell) tutti i caratteri speciali che dovessero trovarsi all'interno di STRINGA. Questa è una forma di quoting più forte di ". Vedi anche Capitolo 5.
operatore virgola. L'operatore virgola concatena una serie di operazioni aritmetiche. Vengono valutate tutte, ma viene restituita solo l'ultima.
let "t2 = ((a = 9, 15 / 3))" # Imposta "a = 9" e "t2 = 15 / 3". |
escape [barra inversa]. Strumento per il quoting di caratteri singoli.
\X "preserva" il carattere X. Equivale ad effettuare il "quoting" di X, vale a dire 'X'. La \ si utilizza per il quoting di " e di ', affinché siano interpretati letteralmente.
Vedi Capitolo 5 per una spiegazione approfondita dei caratteri di escape.
Separatore nel percorso dei file [barra]. Separa i componenti del nome del file (come in /home/bozo/projects/Makefile).
È anche l'operatore aritmetico di divisione.
sostituzione di comando. Il costrutto `comando` rende disponibile l'output di comando per l'assegnamento ad una variabile. È conosciuto anche come apice inverso o apostrofo inverso.
comando null [due punti]. È l'equivalente shell di "NOP" (no op, operazione non-far-niente). Può essere considerato un sinonimo del builtin di shell true. Il comando ":" è esso stesso un builtin Bash, ed il suo exit status è "true" (0).
: echo $? # 0 |
Ciclo infinito:
while : do operazione-1 operazione-2 ... operazione-n done # Uguale a: # while true # do # ... # done |
Istruzione nulla in un costrutto if/then:
if condizione then : # Non fa niente e salta alla prossima istruzione else fa-qualcosa fi |
Fornisce un segnaposto dove è attesa un'operazione binaria, vedi Esempio 8-2 e parametri predefiniti.
: ${nomeutente=`whoami`} # ${nomeutente=`whoami`} Senza i : iniziali dà un errore, # tranne se "nomeutente" è un comando o un builtin ... |
Fornisce un segnaposto dove è atteso un comando in un here document. Vedi Esempio 18-10.
Valuta una stringa di variabili utilizzando la sostituzione di parametro (come in Esempio 9-15).
: ${HOSTNAME?} ${USER?} ${MAIL?} # Visualizza un messaggio d'errore se una, o più, delle variabili #+ fondamentali d'ambiente non è impostata. |
Espansione di variabile / sostituzione di sottostringa.
In combinazione con >, l'operatore di redirezione, azzera il contenuto di un file, senza cambiarne i permessi. Se il file non esiste, viene creato.
: > data.xxx # Ora il file "data.xxx" è vuoto. # Ha lo stesso effetto di cat /dev/null > data.xxx # Tuttavia non viene generato un nuovo processo poiché ":" è un builtin. |
In combinazione con l'operatore di redirezione >> non ha alcun effetto su un preesistente file di riferimento (: >> file_di_riferimento). Se il file non esiste, viene creato.
Si utilizza solo con i file regolari, non con con le pipe, i link simbolici ed alcuni file particolari. |
Può essere utilizzato per iniziare una riga di commento, sebbene non sia consigliabile. Utilizzando # si disabilita la verifica d'errore sulla parte restante di quella riga, così nulla verrà visualizzato dopo il commento. Questo non succede con :.
: Questo è un commento che genera un errore, (if [ $x -eq 3] ). |
I ":" servono anche come separatore di campo nel file /etc/passwd e nella variabile $PATH.
bash$ echo $PATH /usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games |
inverte (o nega) il senso di una verifica o di un exit status [punto esclamativo]. L'operatore ! inverte l'exit status di un comando a cui è stato anteposto (vedi Esempio 6-2). Cambia anche il significato di un operatore di verifica. Può, per esempio, cambiare il senso di "uguale" ( = ) in "non uguale" ( != ). L'operatore ! è una parola chiave Bash.
In un contesto differente, il ! appare anche nelle referenziazioni indirette di variabili.
Ancora, da riga di comando il ! invoca il meccanismo della cronologia di Bash (vedi Appendice J). È da notare che, all'interno di uno script, il meccanismo della cronologia è disabilitato.
carattere jolly [asterisco]. Il carattere * serve da "carattere jolly" per l'espansione dei nomi dei file nel globbing. Da solo, ricerca tutti i file di una data directory.
bash$ echo * abs-book.sgml add-drive.sh agram.sh alias.sh |
L' * rappresenta anche tutti i caratteri (o nessuno) in una espressione regolare.
operatore aritmetico. Nell'ambito delle operazioni aritmetiche, l' * indica l'operatore di moltiplicazione.
Il doppio asterisco, **, è l'operatore di elevamento a potenza.
operatore di verifica. In certe espressioni, il ? indica la verifica di una condizione.
In un costrutto parentesi doppie, il ? viene utilizzato come operatore ternario in stile C. Vedi Esempio 9-31.
Nella sostituzione di parametro, il ? verifica se una variabile è stata impostata.
carattere jolly. Il carattere ? serve da "carattere jolly" per un singolo carattere, nell'espansione dei nomi dei file nel globbing, così come rappresenta un singolo carattere in una espressione regolare estesa.
Sostituzione di variabile (contenuto di una variabile).
var1=5 var2=23skidoo echo $var1 # 5 echo $var2 # 23skidoo |
Il $ davanti al nome di una variabile rimanda al valore contenuto nella variabile stessa.
fine-riga. In una espressione regolare, il "$" rinvia alla fine della riga di testo.
variabile exit status. La variabile $? contiene l'exit status di un comando, di una funzione o dello stesso script.
variabile ID di processo. La variabile $$ contiene l'ID di processo [1] dello script in cui appare.
gruppo di comandi.
(a=ciao; echo $a) |
Un elenco di comandi racchiuso da parentesi dà luogo ad una subshell. Le variabili all'interno delle parentesi, appartenenti quindi alla subshell, non sono visibili dallo script. Il processo genitore, lo script, non può leggere le variabili create nel processo figlio, la subshell.
|
inizializzazione di array.
Array=(elemento1 elemento2 elemento3) |
cat {file1,file2,file3} > file_unico # Concatena i file file1, file2 e file3 in file_unico. cp file22.{txt,backup} # Copia "file22.txt" in "file22.backup" |
Il comando agisce sull'elenco dei file, separati da virgole, specificati tra le parentesi graffe. [2] L'espansione dei nomi dei file (il globbing) viene applicata a quelli elencati tra le parentesi.
Non è consentito alcuno spazio dentro le parentesi, tranne il caso in cui si utilizzi il "quoting" o se preceduto da un carattere di escape. echo {file1,file2}\ :{\ A," B",' C'} file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C |
Espansione multipla estesa.
echo {a..z} # a b c d e f g h i j k l m n o p q r s t u v w x y z # Visualizza tutti i caratteri tra a e z. echo {0..3} # 0 1 2 3 # Visualizza tutti i caratteri tra 0 e 3. |
Il costrutto {a..z}, espansione multipla estesa, è una funzionalità introdotta nella versione 3 di Bash.
Blocco di codice [parentesi graffe]. Conosciuto anche come gruppo inline, questo costrutto crea una funzione anonima (una funzione senza un nome). Tuttavia, a differenza di una "normale" funzione, le variabili presenti all'interno del blocco rimangono visibili alla parte restante dello script.
bash$ { local a; a=123; } bash: local: can only be used in a function |
a=123 { a=321; } echo "a = $a" # a = 321 (valore di a nel blocco di codice) # Grazie, S.C. |
La porzione di codice racchiusa tra le parentesi graffe può avere l'I/O rediretto da e verso se stessa.
Esempio 3-1. Blocchi di codice e redirezione I/O
#!/bin/bash # Legge le righe del file /etc/fstab. File=/etc/fstab { read riga1 read riga2 } < $File echo "La prima riga di $File è:" echo "$riga1" echo echo "La seconda riga di $File è:" echo "$riga2" exit 0 # Ora, come sarebbe possibile verificare i diversi campi di ciascuna riga? # Suggerimento: usate awk. |
Esempio 3-2. Salvare i risultati di un blocco di codice in un file
#!/bin/bash # rpm-check.sh # Interroga un file rpm per visualizzarne la descrizione ed il #+contenuto, verifica anche se può essere installato. # Salva l'output in un file. # # Lo script illustra l'utilizzo del blocco di codice. SUCCESSO=0 E_ERR_ARG=65 if [ -z "$1" ] then echo "Utilizzo: `basename $0` file-rpm" exit $E_ERR_ARG fi { echo echo "Descrizione Archivio:" rpm -qpi $1 # Richiede la descrizione. echo echo "Contenuto dell'archivio:" rpm -qpl $1 # Richiede il contenuto. echo rpm -i --test $1 # Verifica se il file rpm può essere installato. if [ "$?" -eq $SUCCESSO ] then echo "$1 può essere installato." else echo "$1 non può essere installato." fi echo } > "$1.test" # Redirige l'output di tutte le istruzioni del blocco #+ in un file. echo "I risultati della verifica rpm si trovano nel file $1.test" # Vedere la pagina di manuale di rpm per la spiegazione delle opzioni. exit 0 |
segnaposto per testo. Usate dopo xargs
-i
(opzione sostituzione
stringhe). Le doppie parentesi graffe
{} sostituiscono l'output di un testo.
ls . | xargs -i -t cp ./{} $1 # ^^ ^^ # Dall'esempio "ex42.sh" (copydir.sh). |
Il ";" termina la
sintassi dell'opzione |
verifica.
Verifica l'espressione tra [ ]. È da notare che [ è parte del builtin di shell test (ed anche suo sinonimo), non un link al comando esterno /usr/bin/test.
verifica.
Verifica l'espressione tra [[ ]]. Questa è una parola chiave di shell.
Vedi la disamina sul costrutto [[ ... ]].
elemento di un array.
Nell'ambito degli array, le parentesi quadre vengono impiegate nell'impostazione dei singoli elementi di quell'array.
Array[1]=slot_1 echo ${Array[1]} |
intervallo di caratteri.
Come parte di un'espressione regolare, le parentesi quadre indicano un intervallo di caratteri da ricercare.
espansione di espressioni intere.
Espande e valuta l'espressione intera tra (( )).
Vedi la disamina sul costrutto (( ... )).
nome_script >nome_file redirige l'output di nome_script nel file nome_file. Sovrascrive nome_file nel caso fosse già esistente.
comando &>nome_file redirige sia lo stdout che lo stderr di comando in nome_file.
comando >&2 redirige lo stdout di comando nello stderr.
nome_script >>nome_file accoda l'output di nome_script in nome_file. Se nome_file non esiste, viene creato.
[i]<>nome_file apre il file nome_file in lettura e scrittura, e gli assegna il descrittore di file i. Se nome_file non esiste, viene creato.
(comando)>
<(comando)
In un altro ambito, i caratteri "<" e ">" vengono utilizzati come operatori di confronto tra stringhe.
In un altro ambito ancora, i caratteri "<" e ">" vengono utilizzati come operatori di confronto tra interi. Vedi anche Esempio 15-9.
redirezione utilizzata in un here document.
redirezione utilizzata in una here string.
veg1=carote veg2=pomodori if [[ "$veg1" < "$veg2" ]] then echo "Sebbene nel dizionario $veg1 preceda $veg2," echo "questo non intacca le mie preferenze culinarie." else echo "Che razza di dizionario stai usando?" fi |
bash$ grep '\<il\>' filetesto
pipe. Passa l'output del comando che la precede come input del comando che la segue, o alla shell. È il metodo per concatenare comandi.
echo ls -l | sh # Passa l'output di "echo ls -l" alla shell, #+ con lo stesso risultato di "ls -l". cat *.lst | sort | uniq # Unisce ed ordina tutti i file ".lst", dopo di che cancella le righe doppie. |
Una pipe, metodo classico della comunicazione tra processi, invia lo stdout di un processo allo stdin di un altro. Nel caso tipico di un comando, come cat o echo, collega un flusso di dati da elaborare ad un "filtro" (un comando che trasforma il suo input). cat $nome_file1 $nome_file2 | grep $parola_da_cercare |
L'output di uno o più comandi può essere collegato con una pipe ad uno script.
#!/bin/bash # uppercase.sh : Cambia l'input in caratteri maiuscoli. tr 'a-z' 'A-Z' # Per l'intervallo delle lettere deve essere utilizzato il "quoting" per #+ impedire di creare file aventi per nome le singole lettere dei nomi #+ dei file. exit 0 |
bash$ ls -l | ./uppercase.sh -RW-RW-R-- 1 BOZO BOZO 109 APR 7 19:49 1.TXT -RW-RW-R-- 1 BOZO BOZO 109 APR 14 16:48 2.TXT -RW-R--R-- 1 BOZO BOZO 725 APR 20 20:56 DATA-FILE |
In una pipe, lo stdout di ogni processo deve essere letto come stdin del successivo. Se questo non avviene, il flusso di dati si blocca. La pipe non si comporterà come ci si poteva aspettare.
Una pipe viene eseguita come processo figlio e quindi non può modificare le variabili dello script.
Se uno dei comandi della pipe abortisce, questo ne determina l'interruzione prematura. Chiamata pipe interrotta, questa condizione invia un segnale SIGPIPE. |
forza la redirezione (anche se è stata impostata l'opzione noclobber) . Ciò provoca la sovrascrittura forzata di un file esistente.
operatore logico OR. In un costrutto condizionale, l'operatore || restituirà 0 (successo) se almeno una delle condizioni di verifica valutate è vera.
Esegue un lavoro in background. Un comando seguito da una & verrà eseguito in background (sullo sfondo).
bash$ sleep 10 & [1] 850 [1]+ Done sleep 10 |
In uno script possono essere eseguiti in background sia i comandi che i cicli .
Esempio 3-3. Eseguire un ciclo in background
#!/bin/bash # background-loop.sh for i in 1 2 3 4 5 6 7 8 9 10 # Primo ciclo. do echo -n "$i " done & # Esegue questo ciclo in background. # Talvolta verrà eseguito, invece, il secondo ciclo. echo # Questo 'echo' alcune volte non verrà eseguito. for i in 11 12 13 14 15 16 17 18 19 20 # Secondo ciclo. do echo -n "$i " done echo # Questo 'echo' alcune volte non verrà eseguito. # ====================================================== # Output atteso: # 1 2 3 4 5 6 7 8 9 10 # 11 12 13 14 15 16 17 18 19 20 # Talvolta si potrebbe ottenere: # 11 12 13 14 15 16 17 18 19 20 # 1 2 3 4 5 6 7 8 9 10 bozo $ # (Il secondo 'echo' non è stato eseguito. Perché?) # Occasionalmente anche: # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # (Il primo 'echo' non è stato eseguito. Perché?) # Molto raramente qualcosa come: # 11 12 13 1 2 3 4 5 6 7 8 9 10 14 15 16 17 18 19 20 # Il ciclo in primo piano (foreground) ha la precedenza su #+ quello in background. exit 0 # Per divertirsi veramente, #+ Nasimuddin Ansari suggerisce l'aggiunta di sleep 1 #+ dopo i comandi echo -n "$i" delle righe 6 e 14. |
Un comando eseguito in background all'interno di uno script può provocarne l'interruzione, in attesa che venga premuto un tasto. Fortunatamente, per questa eventualità esiste un rimedio. |
operatore logico AND . In un costrutto condizionale, l'operatore && restituirà 0 (successo) solo se tutte le condizioni verificate sono vere.
opzione, prefisso. Prefisso di opzione di un comando o di un filtro. Prefisso di un operatore.
COMANDO -[Opzione1][Opzione2][...]
ls -al
sort -dfu $nomefile
set -- $variabile
if [ $file1 -ot $file2 ] then echo "Il file $file1 è più vecchio di $file2." fi if [ "$a" -eq "$b" ] then echo "$a è uguale a $b." fi if [ "$c" -eq 24 -a "$d" -eq 47 ] then echo "$c è uguale a 24 e $d è uguale a 47." fi |
(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -) # Sposta l'intero contenuto di una directory in un'altra # [cortesia di Alan Cox <a.cox@swansea.ac.uk>, con una piccola modifica] # 1) cd /source/directory Directory sorgente, dove sono contenuti i file che # devono essere spostati. # 2) && "lista And": se l'operazione 'cd' ha successo, # allora viene eseguito il comando successivo. # 3) tar cf - . L'opzione 'c' del comando di archiviazione 'tar' # crea un nuovo archivio, l'opzione 'f' (file), # seguita da '-' designa come file di destinazione # lo sdtout, e lo fa nella directory corrente ('.'). # 4) | Collegato a... # 5) ( ... ) subshell # 6) cd /dest/directory Cambia alla directory di destinazione. # 7) && "lista And", come sopra # 8) tar xpvf - Scompatta l'archivio ('x'), mantiene i permessi e # le proprietà dei file ('p'), invia messaggi # dettagliati allo stdout ('v'), leggendo i dati # dallo stdin ('f' seguito da '-') # Attenzione: 'x' è un comando, # mentre 'p', 'v' ed 'f' sono opzioni. # Whew! # Più elegante, ma equivalente a: # cd source-directory # tar cf - . | (cd ../dest/directory; tar xpvf -) # # Ottengono lo stesso rirultato anche: # cp -a /source/directory/* /dest/directory # Oppure: # cp -a /source/directory/* /source/directory/.[^.]* /dest/directory # Nel caso ci siano file nascosti in /source/directory. |
bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf - # --decomprime il file tar -- | --quindi lo passa a "tar"-- # Se "tar" non è stato aggiornato per trattare "bunzip2", #+ occorre eseguire l'operazione in due passi successivi utilizzando una pipe. # Lo scopo dell'esercizio è di decomprimere i sorgenti del kernel #+ compressi con "bzip". |
Va notato che, in questo contesto, il "-" non è, di per sé un operatore Bash, ma piuttosto un'opzione riconosciuta da alcune utility UNIX che scrivono allo stdout, come tar, cat, ecc.
bash$ echo "qualsiasi cosa" | cat - qualsiasi cosa |
Dove è atteso un nome di file, il - redirige l'output allo stdout (talvolta con tar cf), o accetta l'input dallo stdin, invece che da un file. È un metodo per utilizzare l'utility come filtro in una pipe.
bash$ file Usage: file [-bciknvzL] [-f filename] [-m magicfiles] file... |
Occorre aggiungere il "-" per un migliore risultato. L'esempio seguente fa sì che la shell attenda l'input dall'utente.
bash$ file - abc standard input: ASCII text bash$ file - #!/bin/bash standard input: Bourne-Again shell script text executable |
Il "-" può essere utilizzato per collegare lo stdout ad altri comandi. Ciò permette alcune acrobazie, come aggiungere righe all'inizio di un file.
Utilizzare diff per confrontare un file con la sezione di un altro:
grep Linux file1 | diff file2 -
Infine, un esempio concreto di come usare il - con tar.
Esempio 3-4. Backup di tutti i file modificati il giorno precedente
#!/bin/bash # Salvataggio di tutti i file della directory corrente che sono stati #+ modificati nelle ultime 24 ore in un archivio "tarball" (file trattato #+ con tar e gzip). FILEBACKUP=backup-$(date +%d-%m-%Y) # Inserisce la data nel nome del file di salvataggio. # Grazie a Joshua Tschida per l'idea. archivio=${1:-$FILEBACKUP} # Se non viene specificato un nome di file d'archivio da riga di comando, #+ questo verrà impostato a "backup-GG-MM-AAAA.tar.gz." tar cvf - `find . -mtime -1 -type f -print` > $archivio.tar gzip $archivio.tar echo "Directory $PWD salvata nel file \"$archivio.tar.gz\"." # Stephane Chazelas evidenzia che il precedente codice fallisce l'esecuzione #+ se incontra troppi file o se un qualsiasi nome di file contiene caratteri #+ di spaziatura. # Suggerisce, quindi, le seguenti alternative: # ------------------------------------------------------------------- # find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archivio.tar" # utilizzando la versione GNU di "find". # find . -mtime -1 -type f -exec tar rvf "$archivio.tar" '{}' \; # portabile su altre versioni UNIX, ma molto più lento. # ------------------------------------------------------------------- exit 0 |
Nomi di file che iniziano con "-" possono provocare problemi quando vengono utilizzati con il "-" come operatore di redirezione. Uno script potrebbe verificare questa possibilità ed aggiungere un prefisso adeguato a tali nomi, per esempio ./-NOMEFILE, $PWD/-NOMEFILE o $PATHNAME/-NOMEFILE. Anche il valore di una variabile che inizia con un - potrebbe creare problemi.
|
directory di lavoro precedente. Il comando cd - cambia alla directory di lavoro precedente. Viene utilizzata la variabile d'ambiente $OLDPWD.
Non bisogna confondere il "-" utilizzato in questo senso con l'operatore di redirezione "-" appena discusso. L'interpretazione del "-" dipende dal contesto in cui appare. |
Meno. Segno meno in una operazione aritmetica.
Uguale. Operatore di assegnamento
a=28 echo $a # 28 |
In un contesto differente, il simbolo di "=" è l'operatore di confronto tra stringhe.
Più. Operatore aritmetico di addizione.
In un contesto differente, il simbolo + è un operatore di Espressione Regolare.
Opzione. Opzione per un comando o un filtro.
Alcuni comandi e builtin utilizzano il segno + per abilitare certe opzioni ed il segno - per disabilitarle.
modulo. Modulo (resto di una divisione) , operatore aritmetico.
In un contesto differente, il simbolo % è l'operatore di ricerca di corrispondenza.
directory home [tilde]. Corrisponde alla variabile interna $HOME. ~bozo è la directory home di bozo, e ls ~bozo elenca il suo contenuto. ~/ è la directory home dell'utente corrente e ls ~/ elenca il suo contenuto.
bash$ echo ~bozo /home/bozo bash$ echo ~ /home/bozo bash$ echo ~/ /home/bozo/ bash$ echo ~: /home/bozo: bash$ echo ~utente-inesistente ~utente-inesistente |
directory di lavoro corrente. Corrisponde alla variabile interna $PWD.
directory di lavoro precedente. Corrisponde alla variabile interna $OLDPWD.
verifica di espressione regolare. Questo operatore è stato introdotto con la versione 3 di Bash.
inizio-riga. In una espressione regolare, un "^" rinvia all'inizio di una riga di testo.
modificano il comportamento di un terminale o la visualizzazione di un testo. Un carattere di controllo è la combinazione di CONTROL + tasto (premuti contemporaneamente). Un carattere di controllo può anche essere scritto in notazione ottale o esadecimale, preceduta da un carattere di escape.
Normalmente, i caratteri di controllo, inseriti in uno script, non sono utili.
Ctl-B
Backspace (ritorno non distruttivo).
Ctl-C
Interruzione. Termina un'applicazione in primo piano.
Ctl-D
Uscita dalla shell (simile a exit).
"EOF" (end of file). Anch'esso termina l'input dallo stdin.
Durante la digitazione di un testo in una console o in una finestra xterm, Ctl-D cancella il carattere che si trova sotto al cursore. Quando non ci sono più caratteri, Ctl-D determina la prevista uscita dalla sessione. In una finestra xterm, questo ha come effetto la chiusura della finestra stessa.
Ctl-G
"SEGNALE ACUSTICO" (beep). Su alcune vecchie telescriventi faceva suonare veramente una campanella
Ctl-H
Backspace (ritorno distruttivo). Cancella i caratteri che si trovano sotto al cursore nel suo spostamento a ritroso.
#!/bin/bash # Inserire Ctl-H in una stringa. a="^H^H" # Due Ctl-H (backspace). echo "abcdef" # abcdef echo -n "abcdef$a " # abcd f # Spazio finale ^ ^ Doppio backspace echo -n "abcdef$a" # abcdef # Nessuno spazio alla fine Non viene seguito il backspace (perch´?) # I risultati possono essere piuttosto diversi da #+ ciò che ci si aspetta. echo; echo |
Ctl-I
Tabulazione orizzontale.
Ctl-J
Nuova riga (line feed). In uno script, può anche essere espresso in forma ottale -- '\012' o esadecimale -- '\x0a'.
Ctl-K
Tabulazione verticale.
Durante la digitazione di un testo in una console o in una finestra xterm, Ctl-K cancella i caratteri a partire da quello che si trova sotto al cursore (compreso) fino alla fine della riga. In uno script, Ctl-K potrebbe comportarsi in modo diverso, come nel successivo esempio di Lee Maschmeyer.
Ctl-L
Formfeed (pulisce lo schermo del terminale). Ha lo stesso effetto del comando clear. Se inviato ad una stampante, Ctl-L provoca un avanzamento fino alla fine del foglio.
Ctl-M
A capo.
#!/bin/bash # Grazie a Lee Maschmeyer per l'esempio. read -n 1 -s -p $'Control-M sposta il cursore all'inizio della riga. Premi Invio. \x0d' # Naturalmente, '0d' è l'equivalente esadecimale di Control-M. echo >&2 # '-s' non visualizza quello che viene digitato, #+ quindi è necessario andare a capo esplicitamente. read -n 1 -s -p $'Control-J sposta il cursore alla riga successiva. \x0a' # '0a' è l'equivalente esadecimale di Control-J (linefeed). echo >&2 ### read -n 1 -s -p $'E Control-K\x0b lo sposta direttamente in basso.' echo >&2 # Control-K indica la tabulazione verticale. # Un esempio migliore dell'effetto di una tabulazione verticale è il seguente: var=$'\x0aQuesta è la riga finale\x0bQuesta è la riga iniziale\x0a' echo "$var" # Stesso risultato dell'esempio precedente. Tuttavia: echo "$var" | col # Questo provoca l'inversione nella visualizzazione delle righe. # Inoltre spiega il motivo per cui sono stati posti dei line feed all'inizio e #+ alla fine della riga: evitare una visualizzazione confusa. # La spiegazione di Lee Maschmeyer: # -------------------------------- # Nel primo esempio [di tabulazione verticale] . . . questa esegue #+ una semplice visualizzazione alla riga inferiore senza il ritorno a capo. # Ma questo vale solo per i dispositivi, quali la console Linux, #+ che non consentono di andare "in senso inverso." # Il vero scopo della TV è quello di andare in SÙ, non in giù. # Ciò può essere sfruttato per stampare dei soprascritti. # L'utility col può essere usata per simulare il corretto comportamento #+ di una TV. exit 0 |
Ctl-Q
Ripristino (XON).
Ripristina lo stdin di un terminale.
Ctl-S
Sospensione (XOFF).
Congela lo stdin di un terminale. (Si usi Ctl-Q per ripristinarlo.)
Ctl-U
Cancella una riga di input, a partire dal cursore in senso inverso fino all'inizio della riga. In alcune impostazioni, Ctl-U cancella l'intera riga di input, indipendentemente dalla posizione del cursore.
Ctl-V
Durante la digitazione di un testo, Ctl-V consente l'inserimento di caratteri di controllo. Ad esempio, le due righe seguenti si equivalgono:
echo -e '\x0a' echo <Ctl-V><Ctl-J> |
Ctl-V è particolarmente utile in un editor di testo.
Ctl-W
Durante la digitazione di un testo in una console o in una finestra xterm, Ctl-W cancella a partire dal carattere che si trova sotto al cursore all'indietro fino al primo spazio incontrato. In alcune impostazioni, Ctl-W cancella all'indietro fino al primo carattere non alfanumerico.
Ctl-Z
Sospende un'applicazione in primo piano.
serve come divisore, separando comandi o variabili. La spaziatura è formata da spazi, tabulazioni, righe vuote, o una loro qualsiasi combinazione. [4] In alcuni contesti, quale l'assegnamento di variabile, la spaziatura non è consentita e produce un errore di sintassi.
Le righe vuote non hanno alcun affetto sull'azione dello script, sono quindi molto utili per separare visivamente le diverse sezioni funzionali.
$IFS, è la speciale variabile dei separatori dei campi di input per determinati comandi. Il carattere preimpostato è lo spazio.
Per preservare gli spazi presenti in una stringa o in una variabile, si usi il quoting.
[1] | Il PID, o ID di processo, è un numero assegnato al processo in esecuzione. È possibile visualizzare i PID dei processi in esecuzione con il comando ps. Definizione: un processo è un programma in esecuzione, talvolta chiamato job. | |
[2] | È la shell che esegue l'espansione delle parentesi graffe. Il comando agisce sul risultato dell'espansione. | |
[3] | Eccezione: una porzione di codice tra parentesi graffe come parte di una pipe potrebbe essere eseguita come subshell.
| |
[4] | Anche il linefeed ("a_capo") è un carattere di spaziatura. Questo spiega perché una riga vuota, essendo generata semplicemente da un a_capo, viene considerata una spaziatura. |