Questo si chiama sostituzione del processo.
Il <(list)
la sintassi è supportata da entrambi, bash
e zsh
. Fornisce un modo per passare l'output di un comando (list
) a un altro comando quando si usa una pipe (|
) non è possibile. Ad esempio quando un comando semplicemente non supporta l'input da STDIN
oppure hai bisogno dell'output di più comandi:
diff <(ls dirA) <(ls dirB)
<(list)
connette l'output di list
con un file in /dev/fd
, se supportato dal sistema, altrimenti viene utilizzata una named pipe (FIFO) (che dipende anche dal supporto del sistema; nessuno dei due manuali dice cosa succede se entrambi i meccanismi non sono supportati, presumibilmente si interrompe con un errore). Il nome del file viene quindi passato come argomento sulla riga di comando.
zsh
supporta inoltre =(list)
come possibile sostituto di <(list)
. Con =(list)
viene utilizzato un file temporaneo invece del file in /dev/fd
o un FIFO. Può essere utilizzato in sostituzione di <(list)
se il programma deve cercare nell'output.
Secondo il manuale ZSH potrebbero esserci anche altri problemi con come <(list)
funziona:
Il
=
è utile sia come/dev/fd
e l'implementazione della named pipe di<(...)
avere degli svantaggi. Nel primo caso, alcuni programmi potrebbero chiudere automaticamente il descrittore di file in questione prima di esaminare il file sulla riga di comando, in particolare se ciò è necessario per motivi di sicurezza, ad esempio quando il programma sta eseguendo setuid. Nel secondo caso, se il programma non apre effettivamente il file, la subshell che tenta di leggere o scrivere nella pipe si bloccherà (in un'implementazione tipica, diversi sistemi operativi possono avere un comportamento diverso) per sempre e dovrà essere terminata in modo esplicito . In entrambi i casi, la shell fornisce effettivamente le informazioni utilizzando una pipe, in modo che i programmi che si aspettano di eseguire lseek (vedere la pagina manlseek(2)
) sul file non funzionerà.
Nota, questa è una risposta bash, non zsh.
Ci sono casi in bash in cui non puoi usare pipe:
some_command | some_other_command
poiché le pipe introducono subshell per ogni componente della pipeline, quando le subshell escono, qualsiasi effetto collaterale su cui si faceva affidamento scomparirebbe. Ad esempio, questo esempio artificioso:
cat file | while read line; do ((count++)); done
echo $count
visualizzerà una riga vuota, perché $count
variabile non esiste nella shell corrente.
Una sostituzione del processo bash ti consente di evitare questo enigma permettendoti di leggere dall'output "some_command" come faresti da un file
while read line; do ((count++)); done < <(cat file)
# ....................................1.2
echo $count # the variable *does* exist in the current shell
(1) è un normale reindirizzamento dell'input. (2) è l'inizio del <()
sintassi di sostituzione del processo.