Guida avanzata di scripting Bash: Un'approfondita esplorazione dell'arte dello scripting di shell | ||
---|---|---|
Indietro | Avanti |
La sostituzione di processo è analoga alla sostituzione di comando. La sostituzione di comando imposta una variabile al risultato di un comando, come elenco_dir=`ls -al` o xref=$( grep parola filedati). La sostituzione di processo, invece, invia l'output di un processo ad un altro processo (in altre parole, manda il risultato di un comando ad un altro comando).
Struttura della sostituzione di processo
>(comando)
<(comando)
Queste istanze danno inizio alla sostituzione di processo. Per inviare i risultati del processo tra parentesi ad un altro processo, vengono usati i file /dev/fd/<n>. [1]
Non vi è nessuno spazio tra "<" o ">" e le parentesi. Se ce ne fosse uno verrebbe visualizzato un messaggio d'errore. |
bash$ echo >(true) /dev/fd/63 bash$ echo <(true) /dev/fd/63 |
Con la sostituzione di processo si possono confrontare gli output di due diversi comandi, o anche l'output di differenti opzioni dello stesso comando.
bash$ comm <(ls -l) <(ls -al) total 12 -rw-rw-r-- 1 bozo bozo 78 Mar 10 12:58 File0 -rw-rw-r-- 1 bozo bozo 42 Mar 10 12:58 File2 -rw-rw-r-- 1 bozo bozo 103 Mar 10 12:58 t2.sh total 20 drwxrwxrwx 2 bozo bozo 4096 Mar 10 18:10 . drwx------ 72 bozo bozo 4096 Mar 10 17:58 .. -rw-rw-r-- 1 bozo bozo 78 Mar 10 12:58 File0 -rw-rw-r-- 1 bozo bozo 42 Mar 10 12:58 File2 -rw-rw-r-- 1 bozo bozo 103 Mar 10 12:58 t2.sh |
Utilizzare la sostituzione di processo per confrontare il contenuto di due directory (per verificare quali file sono presenti nell'una, ma non nell'altra):
diff <(ls $prima_directory) <(ls $seconda_directory) |
Alcuni altri usi ed impieghi della sostituzione di processo
cat <(ls -l) # Uguale a ls -l | cat sort -k 9 <(ls -l /bin) <(ls -l /usr/bin) <(ls -l /usr/X11R6/bin) # Elenca tutti i file delle 3 directory principali 'bin' e li ordina. # Notate che a 'sort' vengono inviati tre (contateli) distinti comandi. diff <(comando1) <(comando2) # Fornisce come output le differenze dei comandi. tar cf >(bzip2 -c > file.tar.bz2) $nome_directory # Richiama "tar cf /dev/fd/?? $nome_directory" e "bzip2 -c > file.tar.bz2". # # A causa della funzionalità di sistema di /dev/fd/<n>, # non occorre che la pipe tra i due comandi sia una named pipe. # # Questa può essere emulata. # bzip2 -c < pipe > file.tar.bz2& tar cf pipe $nome_directory rm pipe # oppure exec 3>&1 tar cf /dev/fd/4 $nome_directory 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&- exec 3>&- # Grazie Stépane Chazelas. |
Un lettore ci ha inviato il seguente, interessante esempio di sostituzione di processo.
# Frammento di script preso dalla distribuzione SuSE: while read des what mask iface; do # Alcuni comandi ... done < <(route -n) # Per verificarlo, facciamogli fare qualcosa. while read des what mask iface; do echo $des $what $mask $iface done < <(route -n) # Output: # Kernel IP routing table # Destination Gateway Genmask Flags Metric Ref Use Iface # 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo # Come ha puntualizzato Stéphane Chazelas, una forma analoga, più facile da comprendere, è: route -n | while read des what mask iface; do # Le variabili vengono impostate #+ con l'output della pipe. echo $des $what $mask $iface done # Produce lo stesso output del precedente. # Tuttavia, come rileva Ulrich Gayer . . . #+ questa forma semplificata usa una subshell per il ciclo while #+ e, quindi, le variabili scompaiono quando la pipe termina. # Filip Moritz fa notare, comunque, che esiste una sottile differenza #+ tra i due esempi precedenti, come viene mostrato di seguito. ( route -n | while read x; do ((y++)); done echo $y # $y risulta ancora non impostata while read x; do ((y++)); done < <(route -n) echo $y # $y contiene il numero delle righe dell'output di route -n ) Più in generale ( : | x=x # sembra dare inizio ad una subshell come : | ( x=x ) # mentre x=x < <(:) # no ) # È utile per la verifica di csv* e operazioni analoghe. # Ed è quello che, in effetti, fa il frammento di codice originale SuSE. #* Comma Separated Values - Valori separati da virgole [N.d.T.] |
[1] | Ha lo stesso effetto di una named pipe (file temporaneo) che, infatti, una volta erano usate nella sostituzione di processo. |