Ricerca…


Osservazioni

La sostituzione del processo è una forma di reindirizzamento in cui l'input o l'output di un processo (alcune sequenze di comandi) vengono visualizzati come un file temporaneo.

Confronta due file dal web

Quanto segue mette a confronto due file con diff utilizzando la sostituzione di processo invece di creare file temporanei.

diff <(curl http://www.example.com/page1) <(curl http://www.example.com/page2)

Alimenta un ciclo while con l'output di un comando

Questo alimenta un ciclo while con l'output di un comando grep :

while IFS=":" read -r user _
do
    # "$user" holds the username in /etc/passwd
done < <(grep "hello" /etc/passwd)

Con comando incolla

# Process substitution with paste command is common
# To compare the contents of two directories
paste <( ls /path/to/directory1 ) <( ls /path/to/directory1 )

Concatenazione di file

È risaputo che non è possibile utilizzare lo stesso file per input e output nello stesso comando. Per esempio,

$ cat header.txt body.txt >body.txt

non fa quello che vuoi Nel momento in cui cat legge body.txt , è già stato troncato dal reindirizzamento ed è vuoto. Il risultato finale sarà che body.txt manterrà solo il contenuto di header.txt .

Si potrebbe pensare di evitare questo con la sostituzione del processo, cioè il comando

$ cat header.txt <(cat body.txt) > body.txt

costringerà i contenuti originali di body.txt a essere in qualche modo salvati in qualche buffer da qualche parte prima che il file venga troncato dal reindirizzamento. Non funziona. Il cat tra parentesi inizia a leggere il file solo dopo che tutti i descrittori di file sono stati impostati, proprio come quello esterno. Non ha senso cercare di utilizzare la sostituzione del processo in questo caso.

L'unico modo per anteporre un file a un altro file è crearne uno intermedio:

$ cat header.txt body.txt >body.txt.new
$ mv body.txt.new body.txt

che è ciò che sed perl o programmi simili fanno sotto il tappeto quando vengono chiamati con un'opzione edit-in-place (di solito -i ).

Trasmetti in streaming un file attraverso più programmi contemporaneamente

Conta il numero di linee in un file grande con wc -l e contemporaneamente lo comprime con gzip . Entrambi corrono contemporaneamente.

tee >(wc -l >&2) < bigfile | gzip > bigfile.gz

Normalmente tee scrive il suo input su uno o più file (e stdout). Possiamo scrivere sui comandi invece dei file con tee >(command) .

Qui il comando wc -l >&2 conta le righe lette da tee (che a sua volta sta leggendo da bigfile ). (Il conteggio delle righe viene inviato a stderr ( >&2 ) per evitare di mescolare con l'input a gzip .) Lo stdout di tee viene simultaneamente inserito in gzip .

Per evitare l'uso di una sub-shell

Uno degli aspetti principali della sostituzione del processo è che ci consente di evitare l'utilizzo di una sub-shell durante il piping dei comandi dalla shell.

Questo può essere dimostrato con un semplice esempio qui sotto. Ho i seguenti file nella mia cartella attuale:

$ find . -maxdepth 1 -type f -print
foo bar zoo foobar foozoo barzoo 

Se eseguo il pipe su un ciclo while / read che incrementa un contatore come segue:

count=0
find . -maxdepth 1 -type f -print | while IFS= read -r _; do
    ((count++))
done

$count ora non contiene 6 , perché è stato modificato nel contesto della sub-shell. Qualsiasi comando mostrato di seguito viene eseguito in un contesto di sub-shell e l'ambito delle variabili utilizzate all'interno viene perso dopo la terminazione della sub-shell.

command &
command | command 
( command )

La sostituzione del processo risolverà il problema evitando l'uso del tubo | operatore come in

count=0
while IFS= read -r _; do
    ((count++))
done < <(find . -maxdepth 1 -type f -print)

Ciò manterrà il valore della variabile count quanto non viene invocato alcun sub-shell.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow