<Precedenti | Contenuti | Succ.>
Sostituzione del processo
Sebbene sembrino simili e possano essere entrambi utilizzati per combinare flussi per il reindirizzamento, esiste un'importante differenza tra comandi di gruppo e subshell. Mentre un comando di gruppo esegue tutti i suoi comandi nella shell corrente, una subshell (come suggerisce il nome) esegue i suoi comandi in una copia figlia della shell corrente. Ciò significa che l'ambiente viene copiato e assegnato a una nuova istanza della shell. Quando la subshell si chiude, la copia dell'ambiente viene persa, quindi anche tutte le modifiche apportate all'ambiente della subshell (inclusa l'assegnazione delle variabili) vengono perse. Pertanto, nella maggior parte dei casi, a meno che uno script non richieda una subshell, i comandi di gruppo sono preferibili alle subshell. I comandi di gruppo sono più veloci e richiedono meno memoria.
Abbiamo visto un esempio del problema dell'ambiente subshell nel Capitolo 28, quando abbiamo scoperto che un read comando in una pipeline non funziona come potremmo intuitivamente aspettarci. Riassumendo, se costruiamo una pipeline come questa:
echo "foo" | leggi echo $REPLY
echo "foo" | leggi echo $REPLY
Il contenuto di REPLY la variabile è sempre vuota perché la read il comando viene eseguito in una subshell e la sua copia di REPLY viene distrutto quando la sottoshell termina.
Poiché i comandi nelle pipeline vengono sempre eseguiti in sottoshell, qualsiasi comando che assegni variabili incontrerà questo problema. Fortunatamente, la shell fornisce una forma esotica di espansione chiamata sostituzione del processo che può essere utilizzato per aggirare questo problema.
La sostituzione del processo è espressa in due modi: Per i processi che producono output standard:
<(stratagemma)
oppure, per i processi che accettano input standard:
>(stratagemma)
where stratagemma è un elenco di comandi.
Per risolvere il nostro problema con read, possiamo utilizzare la sostituzione del processo in questo modo:
leggi < <(echo "foo") echo $REPLY
leggi < <(echo "foo") echo $REPLY
La sostituzione di processo ci consente di trattare l'output di una subshell come un file ordinario ai fini del reindirizzamento. Infatti, poiché si tratta di una forma di espansione, possiamo esaminarne il valore reale:
[me@linuxbox ~]$ echo <(echo "pippo")
/dev/fd/63
[me@linuxbox ~]$ echo <(echo "pippo")
/dev/fd/63
Utilizzando eco per visualizzare il risultato dell'espansione, vediamo che l'output della subshell viene fornito da un file denominato /dev/fd/63.
La sostituzione del processo è spesso utilizzata con cicli contenenti readEcco un esempio di un
ciclo di lettura che elabora il contenuto di un elenco di directory creato da una subshell:
#! / Bin / bash
# pro-sub: dimostrazione della sostituzione del processo
mentre leggi attr link proprietario gruppo dimensione data ora nome file; fai cat <<- EOF
Nome file: $filename Dimensione: $size
Proprietario: $owner
Gruppo: $group Modificato: $date $time Collegamenti: $links Attributi: $attr
EOF
fatto < <(ls -l | tail -n +2)
#! / Bin / bash
# pro-sub: dimostrazione della sostituzione del processo
mentre leggi attr link proprietario gruppo dimensione data ora nome file; fai cat <<- EOF
Nome file: $filename Dimensione: $size
Proprietario: $owner
Gruppo: $group Modificato: $date $time Collegamenti: $links Attributi: $attr
EOF
fatto < <(ls -l | tail -n +2)
Il ciclo viene eseguito read per ogni riga di un elenco di directory. L'elenco stesso viene prodotto nell'ultima riga dello script. Questa riga reindirizza l'output della sostituzione di processo nello standard input del ciclo. coda Il comando è incluso nella pipeline di sostituzione del processo per eliminare la prima riga dell'elenco, che non è necessaria.
Una volta eseguito, lo script produce un output simile al seguente:
[io@linuxbox~]$ pro-sub | testa -n 20
Nome file: addresses.ldif Dimensione: 14540
Proprietario: io
Gruppo: io
Modified: 2009-04-02 11:12
[io@linuxbox~]$ pro-sub | testa -n 20
Nome file: addresses.ldif Dimensione: 14540
Proprietario: io
Gruppo: io
Modified: 2009-04-02 11:12
Collegamento:
1
Collegamento:
Attributi: -rw-r--r--
Nome file: bin
Dimensione: 4096
Proprietario: io
Gruppo: io
Modified: 2009-07-10 07:31
Collegamenti: 2
Attributi: drwxr-xr-x
Nome file: bookmarks.html Dimensione: 394213
Proprietario: io
Gruppo: io
Attributi: -rw-r--r--
Nome file: bin
Dimensione: 4096
Proprietario: io
Gruppo: io
Modified: 2009-07-10 07:31
Collegamenti: 2
Attributi: drwxr-xr-x
Nome file: bookmarks.html Dimensione: 394213
Proprietario: io
Gruppo: io