Bash scripting: differenze tra le versioni

risistemazione, aggiunti nuovi esempi, riformulata qualche frase
(risistemazione, aggiunti nuovi esempi, riformulata qualche frase)
Riga 1: Riga 1:
{{Versioni_compatibili}}
{{Versioni_compatibili}}
==Introduzione==
==Introduzione==
In questa sezione verranno elencati alcuni brevi tip per lo scripting Bash. Questa non vuole essere assolutamente una guida completa, ma piuttosto un elenco di costrutti per lo scripting bash particolarmente eleganti, curiosi e/o poco noti.
In questa sezione verranno elencati alcuni brevi tip per lo scripting Bash. Questa non vuole essere assolutamente una guida completa, ma piuttosto un elenco di costrutti per lo scripting bash particolarmente eleganti, curiosi e/o poco noti. Si cercherà anche di fornire consigli utili sui comportamenti più distintivi di Bash, partendo dai più facili da fraintendere.


Per l'uso interattivo si rimanda invece a [[Bash tips]].
Per l'uso interattivo si rimanda invece a [[Bash tips]].
==Variabili speciali==
; <code>$?</code> : contiene il valore di uscita dell'ultimo comando o funzione. Il comando ha successo se restituisce zero, qualsiasi altro valore indica invece un codice di errore;
''Esempio:''
$ cd ..
$ echo $?
0
$ cd ...
$ echo $?
1
; <code>$0</code> : contiene il nome usato per lanciare lo script;
; <code>$#</code> : contiene il numero di argomenti passati allo script (o a una funzione, all'interno di una funzione);
; <code>$1, $2, ...</code>: contengono, se presenti, i parametri passati allo script (o a una funzione);
; <code>$@</code> : contiene la lista di tutti i parametri passati allo script corrente o a una funzione. Ogni parametro viene opportunamente quotato, se questa variabile è quotata, e questo ne permette l'utilizzo nei '''cicli for''' per processare (ad esempio) una lista di nomi di file che possono contenere anche spazi. L'uso di questa variabile è quindi in genere preferito rispetto a <code>'''$*'''</code> che ha la stessa funzione ma, se quotata, non quota i vari parametri ma l'intera stringa;
''Esempio:''
<pre>
for file in "$@"; do
    # Fare quello che si vuole con $file
    echo "$file"
    # ...
done
</pre>
; <code>$$</code> : PID del processo corrente;
; <code>$!</code> : PID dell'ultimo job in background.
''Esempio:''
<pre>
comando &  # lancio un comando in background
pid=$!    # ottengo il PID del comando
...        # eseguo altre operazioni
wait $pid  # riporto il comando in foreground
</pre>


== Variabili e stringhe ==
== Variabili e stringhe ==
Riga 93: Riga 51:


Si noti invece che usando <code>"$ARGUMENT"</code> (quotata) per una variabile contenente la stringa vuota, il comando leggerebbe lo stesso un argomento e potrebbe fallire.
Si noti invece che usando <code>"$ARGUMENT"</code> (quotata) per una variabile contenente la stringa vuota, il comando leggerebbe lo stesso un argomento e potrebbe fallire.
==Variabili speciali==
; <code>$?</code> : contiene il valore di uscita dell'ultimo comando o funzione. Il comando ha successo se restituisce zero, qualsiasi altro valore indica invece un codice di errore;
''Esempio:''
$ cd ..
$ echo $?
0
$ cd ...
$ echo $?
1
; <code>$0</code> : contiene il nome usato per lanciare lo script;
; <code>$#</code> : contiene il numero di argomenti passati allo script (o a una funzione, all'interno di una funzione);
; <code>$1, $2, ...</code>: contengono, se presenti, i parametri passati allo script (o a una funzione);
; <code>$@</code> : contiene la lista di tutti i parametri passati allo script corrente o a una funzione. Ogni parametro viene opportunamente quotato, se questa variabile è quotata, e questo ne permette l'utilizzo nei '''cicli for''' per processare (ad esempio) una lista di nomi di file che possono contenere anche spazi. L'uso di questa variabile è quindi in genere preferito rispetto a <code>'''$*'''</code> che ha la stessa funzione ma, se quotata, non quota i vari parametri ma l'intera stringa;
''Esempio:''
<pre>
for file in "$@"; do
    # Fare quello che si vuole con $file
    echo "$file"
    # ...
done
</pre>
; <code>$$</code> : PID del processo corrente;
; <code>$!</code> : PID dell'ultimo job in background.
''Esempio:''
<pre>
comando &  # lancio un comando in background
pid=$!    # ottengo il PID del comando
...        # eseguo altre operazioni
wait $pid  # riporto il comando in foreground
</pre>


== Manipolazione delle stringhe ==
== Manipolazione delle stringhe ==
Riga 180: Riga 180:
</pre>
</pre>


====Espansione di comando====
==Espansione di comando==


Si effettua racchiudendo un comando tra <code>$(</code> e <code>)</code>, oppure tra due apici gravi <code>`</code> (su tastiera con layout italiano: <code>Alt Gr + '</code>). La prima forma è la più leggibile e quella consigliata.
Si effettua racchiudendo un comando tra <code>$(</code> e <code>)</code>, oppure tra due apici gravi <code>`</code> (su tastiera con layout italiano: <code>Alt Gr + '</code>). La prima forma è la più leggibile e quella consigliata.
Riga 189: Riga 189:
<pre>
<pre>
oggi=$(date +%F) # assegna a oggi la data in formato YYYY_MM_DD
oggi=$(date +%F) # assegna a oggi la data in formato YYYY_MM_DD
# stampa stati
echo "Login name: $(logname); Name: $(whoami); UID: $(id -ur); EUID: $(id -u); Groups: $(groups)"
echo "OS: Debian GNU/Linux $(cat /etc/debian_version) ($(lsb_release -sc))" # uguale a $(lsb_release -sd)
echo "Kernel: $(uname) $(uname -r) ($(uname -v))"
# comando più complesso con pipe che conta il numero di subdirectory
numero_directory=$(find . -type d -print0 | tr -dc '\000' | wc -c)
</pre>
</pre>


==Espansione di tilda e percorso==
==Espansione di tilda e percorso==


Non racchiudere tra virgolette e apici serve a permettere le espansioni di percorso e tilda. È sempre consigliabile racchiudere tutto il resto tra virgolette. I più comuni sono (si ricordi per le espansioni che su ambienti UNIX e Unix-like per file si intende sia un file regolare, sia una directory, un link, una pipe, un socket, un device, ecc...):
{{Box | File | Si ricordi per le espansioni che su ambienti UNIX e Unix-like per file si può intendere sia un file regolare, ma anche una directory, un link simbolico, una pipe, un socket, un device, ecc...}}
** <code>~</code> espande alla home (equivalente alla variabile $HOME, che però può essere quotata);
 
*** <code>~utente</code> espande alla home di un dato utente, ma la stringa utente non può essere quotata né essere una variabile da espandere;
Non racchiudere tra virgolette e apici serve a permettere le espansioni di percorso e tilda. È sempre consigliabile racchiudere tutto il resto tra virgolette, per non permettere espansioni accidentali. In particolare si noti che un'espansione di percorso (ma non di tilda) può avvenire anche in base al contenuto di una variabile, se questa non è quotata.
** <code>?</code> pattern per un singolo carattere di un file;
 
*** <code>nomefile.???</code> combacia con tutti i file con nome "nomefile" e terminanti con tre caratteri qualsiasi per estensione;
Per esempio:
** <code>*</code> pattern per tutti i possibili caratteri di un file (di default tranne quelli inizianti con .):
<pre>
*** <code>*</code> da solo espande a tutti i file non nascosti nella directory corrente. È sempre buona norma far precedere l'asterisco da un ./, che indica la cartella corrente, se è il primo carattere del pattern, per impedire espansioni di file inizianti con "-", che potrebbero essere visti come opzioni da alcuni comandi;
var=*       # assegno * alla variabile
*** <code>./*</code> equivalente a <code>*</code> ma più sicuro; di seguito si aggiunge il prefisso della directory corrente a tutte le espansioni inizianti con <code>*</code>;
var="*"    # è equivalente a sopra
*** <code>./*.txt</code> espande a tutti i file con estensione .txt;
echo "$var" # stampa letteralmente *
*** <code>./*/</code> espande a tutte le directory non nascoste;
echo $var  # stampa la lista di tutti i file non nascosti
*** <code>prefisso*suffisso</code>espande a tutti i file con un dato prefisso e suffisso;
            # nella directory corrente, oppure * se è vuota
*** <code>./*."${estensione}"</code> espande dopo aver espanso la variabile (contrariamente a ~), che può anche essere quotata.
var=~      # assegno ~ alla variabile
echo "$var" # stampa letteralmente ~
echo $var  # equivalente a sopra, nessuna espansione
</pre>
 
Le espansioni più comuni sono:
* <code>~</code> (tilda) espande alla home (equivalente alla variabile $HOME, che però può essere quotata);
** <code>~utente</code> espande alla home di un dato utente, ma la stringa utente non può essere quotata né essere una variabile da espandere;
* <code>?</code> pattern per un singolo carattere di un file;
** <code>nomefile.???</code> combacia con tutti i file con nome "nomefile" e terminanti con tre caratteri qualsiasi per estensione;
* <code>*</code> pattern per tutti i possibili caratteri di un file (di default tranne quelli inizianti con .):
** <code>*</code> da solo espande a tutti i file non nascosti nella directory corrente. È sempre buona norma far precedere l'asterisco da un ./, che indica la cartella corrente, se è il primo carattere del pattern, per impedire espansioni di file inizianti con "-", che potrebbero essere visti come opzioni da alcuni comandi;
** <code>./*</code> equivalente a <code>*</code> ma più sicuro; di seguito si aggiunge il prefisso della directory corrente a tutte le espansioni inizianti con <code>*</code>;
** <code>./*.txt</code> espande a tutti i file con estensione .txt;
** <code>./*/</code> espande a tutte le directory non nascoste;
** <code>prefisso*suffisso</code>espande a tutti i file con un dato prefisso e suffisso;
** <code>./*."${estensione}"</code> espande dopo aver espanso la variabile (contrariamente a ~), che può anche essere quotata.


È importante tenere presente per le espansioni di percorso che, se nessun file combacia con un dato pattern, allora l'espansione *non* viene effettuata e i caratteri mantengono il loro valore originale. Per di più <code>*</code> e <code>?</code> sono caratteri validi per un nome di file. L'esistenza di file ottenuti da tali espansioni va pertanto sempre controllata, per esempio con <code>[ -e "$file" ]</code>:
È importante tenere presente per le espansioni di percorso che, se nessun file combacia con un dato pattern, allora l'espansione *non* viene effettuata e i caratteri mantengono il loro valore originale. Per di più <code>*</code> e <code>?</code> sono caratteri validi per un nome di file. L'esistenza di file ottenuti da tali espansioni va pertanto sempre controllata, per esempio con <code>[ -e "$file" ]</code>:
Riga 296: Riga 320:
|Verificata_da=
|Verificata_da=
:[[Utente:S3v|S3v]] (versione in Bash tips)
:[[Utente:S3v|S3v]] (versione in Bash tips)
:[[Utente:HAL 9000|HAL 9000]] 13:01, 3 lug 2014 (CEST)
:[[Utente:HAL 9000|HAL 9000]] 18:42, 3 lug 2014 (CEST)
|Estesa_da=
|Estesa_da=
:[[Utente:S3v|S3v]] (versione in Bash tips)
:[[Utente:S3v|S3v]] (versione in Bash tips)
:[[Utente:HAL 9000|HAL 9000]] (versione in Bash tips)
:[[Utente:HAL 9000|HAL 9000]]
|Numero_revisori=2
|Numero_revisori=2
}}
}}


[[Categoria:Bash]][[Categoria:Bash_Scripting]]
[[Categoria:Bash]][[Categoria:Bash_Scripting]]
3 581

contributi