534
contributi
mNessun oggetto della modifica |
m (Correzione maiuscola-minuscola) |
||
(7 versioni intermedie di 3 utenti non mostrate) | |||
Riga 1: | Riga 1: | ||
{{ | {{Bash scripting}} | ||
__TOC__ | |||
I comandi introdotti in questa sezione sono descritti solo limitatamente alla loro sintassi base, così che il loro impiego nelle sezioni successive possa essere facilmente compreso. | I comandi introdotti in questa sezione sono descritti solo limitatamente alla loro sintassi base, così che il loro impiego nelle sezioni successive possa essere facilmente compreso. | ||
La lettura della sezione può essere tralasciata, se si hanno già nozioni basilari di '''bash''', ma la parte sui comandi di output serve anche a giustificare la scelta di <code>printf</code> in luogo del più noto <code>echo</code> come unico comando di output e a spiegarne brevemente la sintassi, almeno per le invocazioni più comuni. | La lettura della sezione può essere tralasciata, se si hanno già nozioni basilari di '''bash''', ma la parte sui comandi di output serve anche a giustificare la scelta di <code>printf</code> in luogo del più noto <code>echo</code> come unico comando di output e a spiegarne brevemente la sintassi, almeno per le invocazioni più comuni. | ||
==Comandi di output: echo e printf== | == Comandi di output: echo e printf == | ||
Il comando <code>echo</code> è largamente diffuso in Bash per stampare delle stringhe su schermo, perché ha una sintassi più semplice di <code>printf</code> e non risente delle stesse limitazioni della shell sh (''POSIX''), che interpreta ed espande i caratteri di escape (si legga la sezione dedicata) senza che ci sia un modo di stampare letteralmente una stringa (non nota a priori). | Il comando <code>echo</code> è largamente diffuso in Bash per stampare delle stringhe su schermo, perché ha una sintassi più semplice di <code>printf</code> e non risente delle stesse limitazioni della shell sh (''[[POSIX]]''), che interpreta ed espande i caratteri di escape (si legga la sezione dedicata) senza che ci sia un modo di stampare letteralmente una stringa (non nota a priori). | ||
Tuttavia negli script l'uso di <code>echo</code> non è sempre possibile, rendendo necessaria la conoscenza almeno basilare di <code>printf</code>. In particolare, se si vuole stampare il contenuto di $var, '''non''' è sempre corretto scrivere: | Tuttavia negli script l'uso di <code>echo</code> non è sempre possibile, rendendo necessaria la conoscenza almeno basilare di <code>printf</code>. In particolare, se si vuole stampare il contenuto di $var, '''non''' è sempre corretto scrivere: | ||
Riga 19: | Riga 19: | ||
In questa guida d'ora in poi si farà riferimento soltanto a <code>printf</code>. | In questa guida d'ora in poi si farà riferimento soltanto a <code>printf</code>. | ||
===Uso di printf=== | === Uso di printf === | ||
Sintassi: <code>printf formato [ "stringa" ... ]</code> | Sintassi: <code>printf formato [ "stringa" ... ]</code> | ||
Riga 69: | Riga 69: | ||
</pre> | </pre> | ||
====Stampa di messagi d'errore==== | ==== Stampa di messagi d'errore ==== | ||
Per i messaggi di errore, benché sia possibile stamparli assieme ai messaggi normali (sullo ''standard output''), è conveniente utilizzare lo ''standard error'' che ne permette la gestione separata. Se nessuna redirezione è specificata, saranno comunque stampati a schermo a prescindere dall'uso di ''standard output'', che è implicito, o ''standard error''. | Per i messaggi di errore, benché sia possibile stamparli assieme ai messaggi normali (sullo ''standard output''), è conveniente utilizzare lo ''standard error'' che ne permette la gestione separata. Se nessuna redirezione è specificata, saranno comunque stampati a schermo a prescindere dall'uso di ''standard output'', che è implicito, o ''standard error''. | ||
Riga 79: | Riga 79: | ||
</pre> | </pre> | ||
====Sovrascrivere echo==== | ==== Sovrascrivere echo ==== | ||
Se non si riesce a fare a meno di <code>echo</code> si può sovrascriverlo per gli usi più basilari, così da utilizzare al suo posto <code>printf</code> in modo trasparente, mettendo queste definizioni in cima allo script subito dopo lo ''shebang'': | Se non si riesce a fare a meno di <code>echo</code> si può sovrascriverlo per gli usi più basilari, così da utilizzare al suo posto <code>printf</code> in modo trasparente, mettendo queste definizioni in cima allo script subito dopo lo ''shebang'': | ||
<pre> | <pre> | ||
Riga 111: | Riga 111: | ||
</pre> | </pre> | ||
==Condizioni== | == Condizioni == | ||
Le condizioni nella shell dipendono dal valore di uscita (exit status) di un comando. Si considera successo un exit status corrispondente a 0, ed è equivalente a una condizione vera/soddisfatta, mentre fallimento un exit status con valori diversi da zero, e sono equivalenti a una condizione falsa/non soddisfatta. | Le condizioni nella shell dipendono dal valore di uscita (exit status) di un comando. Si considera successo un exit status corrispondente a 0, ed è equivalente a una condizione vera/soddisfatta, mentre fallimento un exit status con valori diversi da zero, e sono equivalenti a una condizione falsa/non soddisfatta. | ||
Riga 129: | Riga 129: | ||
</pre> | </pre> | ||
===Espressioni booleane=== | === Espressioni booleane === | ||
Le espressioni booleane più basilari, ereditate da ''POSIX'', si possono esprimere con i comandi <code>test</code> e <code>[</code>. L'unica differenza tra i due è che il secondo richiede <code>]</code> come ultimo argomento, ed è preferibile per questioni di leggibilità del codice. D'ora in poi infatti si considera soltanto <code>[ ... ]</code>, e in questa sezione vengono descritte solo le forme più basilari. Per tutte le opzioni supportate si rimanda all'aiuto integrato (<code>help test</code>). | Le espressioni booleane più basilari, ereditate da ''POSIX'', si possono esprimere con i comandi <code>test</code> e <code>[</code>. L'unica differenza tra i due è che il secondo richiede <code>]</code> come ultimo argomento, ed è preferibile per questioni di leggibilità del codice. D'ora in poi infatti si considera soltanto <code>[ ... ]</code>, e in questa sezione vengono descritte solo le forme più basilari. Per tutte le opzioni supportate si rimanda all'aiuto integrato (<code>help test</code>). | ||
Riga 161: | Riga 161: | ||
Confronti unari con stringhe contenenti percorsi di file (percorso di default: directory corrente, se mancante): | Confronti unari con stringhe contenenti percorsi di file (percorso di default: directory corrente, se mancante): | ||
* <code>[ -b "$var" ]</code>: vero se il file è un dispositivo a blocchi; | |||
* <code>[ -c "$var" ]</code>: vero se il file è un dispositivo a caratteri; | |||
* <code>[ -d "$var" ]</code>: vero se il file esiste ed è una directory; | |||
* <code>[ -e "$var" ]</code>: vero se il file (file regolare, directory, link simbolico, fifo, socket, ... ) esiste; | * <code>[ -e "$var" ]</code>: vero se il file (file regolare, directory, link simbolico, fifo, socket, ... ) esiste; | ||
* <code>[ -f "$var" ]</code>: vero se il file esiste ed è un file regolare; | * <code>[ -f "$var" ]</code>: vero se il file esiste ed è un file regolare; | ||
* <code>[ - | * <code>[ -g "$var" ]</code>: vero se è impostato il bit sgid; | ||
* <code>[ -G "$var" ]</code>: vero se l’id di gruppo del file è uguale al vostro; | |||
* <code>[ -h "$var" ]</code>: vero se il file esiste ed è un link simbolico; | |||
* <code>[ -k "$var" ]</code>: vero se è impostato lo “sticky bit”; | |||
* <code>[ -L "$var" ]</code>: vero se il file esiste ed è un link simbolico; | |||
* <code>[ -N "$var" ]</code>: vero se il file è stato modificato dall’ultima lettura; | |||
* <code>[ -O "$var" ]</code>: vero se si è il proprietario del file; | |||
*<code>[ -p "$var" ]</code>: vero se il file è una pipe (FIFO); | |||
* <code>[ -r "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di lettura; | * <code>[ -r "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di lettura; | ||
*<code>[ -s "$var" ]</code>: vero se il file non è vuoto; | |||
* <code>[ -S "$var" ]</code>: vero se il file è un socket; | |||
* <code>[ -t "$var" ]</code>: vero se il file è associato a un terminale; | |||
* <code>[ -u "$var" ]</code>: vero se è impostato il bit suid; | |||
* <code>[ -w "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di scrittura; | * <code>[ -w "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di scrittura; | ||
* <code>[ -x "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di esecuzione (o accesso per le directory). | * <code>[ -x "$var" ]</code>: vero se il file esiste e l'utente corrente ha il permesso di esecuzione (o accesso per le directory). | ||
Confronti binari con stringhe contenenti percorsi di file: | |||
* <code>[ "$var1" -nt "$var2" ]</code>: vero se il file $var1 è più recente di $var2; | |||
*<code>[ "$var1" -ot "$var2" ]</code>: vero se il file $var1 è più vecchio di $var2; | |||
* <code>[ "$var1" -et "$var2" ]</code>: vero se i file $var1 e $var2 sono degli hard link allo stesso file; | |||
Con il punto esclamativo <code>!</code> (NOT) si inverte il senso dei precedenti confronti. | |||
===Esecuzione condizionata=== | === Esecuzione condizionata === | ||
Per eseguire un blocco di comandi soltanto se una condizione è soddisfatta si utilizza <code>if</code>, solitamente in combinazione con <code>[...]</code>. | Per eseguire un blocco di comandi soltanto se una condizione è soddisfatta si utilizza <code>if</code>, solitamente in combinazione con <code>[...]</code>. | ||
Riga 194: | Riga 215: | ||
</pre> | </pre> | ||
====Controllo degli errori==== | ==== Controllo degli errori ==== | ||
Si ricordi che <code>if</code> accetta un comando qualsiasi come condizione, valutandone l'exit status ed eseguendo il ramo <code>then</code> se ha successo, e quello <code>elif</code>/<code>else</code> immediatamente successivo (se presente) altrimenti. Quindi è un ottimo strumento anche per controllare che un comando venga eseguito senza errori, permettendo anche la terminazione immediata dello script: | Si ricordi che <code>if</code> accetta un comando qualsiasi come condizione, valutandone l'exit status ed eseguendo il ramo <code>then</code> se ha successo, e quello <code>elif</code>/<code>else</code> immediatamente successivo (se presente) altrimenti. Quindi è un ottimo strumento anche per controllare che un comando venga eseguito senza errori, permettendo anche la terminazione immediata dello script: | ||
<pre> | <pre> |