Bash
Proceso de sustitución
Buscar..
Observaciones
La sustitución de procesos es una forma de redirección donde la entrada o salida de un proceso (alguna secuencia de comandos) aparece como un archivo temporal.
Compara dos archivos de la web.
Lo siguiente compara dos archivos con diff
mediante la sustitución de procesos en lugar de crear archivos temporales.
diff <(curl http://www.example.com/page1) <(curl http://www.example.com/page2)
Alimenta un bucle while con la salida de un comando
Esto alimenta un while
de bucle con la salida de un grep
comando:
while IFS=":" read -r user _
do
# "$user" holds the username in /etc/passwd
done < <(grep "hello" /etc/passwd)
Con comando de pegar
# Process substitution with paste command is common
# To compare the contents of two directories
paste <( ls /path/to/directory1 ) <( ls /path/to/directory1 )
Concatenando archivos
Es bien sabido que no puede usar el mismo archivo para entrada y salida en el mismo comando. Por ejemplo,
$ cat header.txt body.txt >body.txt
no hace lo que tu quieres Para cuando el cat
lee body.txt
, ya se ha truncado por la redirección y está vacío. El resultado final será que body.txt
contendrá los contenidos de header.txt
.
Uno podría pensar para evitar esto con la sustitución de procesos, es decir, que el comando
$ cat header.txt <(cat body.txt) > body.txt
forzará que los contenidos originales de body.txt
se guarden de alguna manera en algún búfer en algún lugar antes de que el archivo sea truncado por la redirección. No funciona El cat
entre paréntesis comienza a leer el archivo solo después de que se hayan configurado todos los descriptores de archivo, al igual que el externo. No tiene sentido intentar usar la sustitución de procesos en este caso.
La única forma de anteponer un archivo a otro es crear uno intermedio:
$ cat header.txt body.txt >body.txt.new
$ mv body.txt.new body.txt
que es lo que hacen sed
o perl
o programas similares bajo la alfombra cuando se les llama con una opción de edición en el lugar (generalmente -i
).
Transmitir un archivo a través de múltiples programas a la vez
Esto cuenta la cantidad de líneas en un archivo grande con wc -l
mientras se comprime simultáneamente con gzip
. Ambos corren concurrentemente.
tee >(wc -l >&2) < bigfile | gzip > bigfile.gz
Normalmente, tee
escribe su entrada en uno o más archivos (y stdout). Podemos escribir comandos en lugar de archivos con tee >(command)
.
Aquí el comando wc -l >&2
cuenta las líneas leídas desde el tee
(que a su vez se lee desde el bigfile
). (El recuento de líneas se envía a stderr ( >&2
) para evitar que se mezcle con la entrada a gzip
). La tee
estándar de tee
se alimenta simultáneamente a gzip
.
Para evitar el uso de un sub-shell
Un aspecto importante de la sustitución de procesos es que nos permite evitar el uso de un sub-shell al canalizar los comandos desde el shell.
Esto se puede demostrar con un simple ejemplo a continuación. Tengo los siguientes archivos en mi carpeta actual:
$ find . -maxdepth 1 -type f -print
foo bar zoo foobar foozoo barzoo
Si canalizo a un bucle while
/ read
que incrementa el contador de la siguiente manera:
count=0
find . -maxdepth 1 -type f -print | while IFS= read -r _; do
((count++))
done
$count
ahora no contiene 6
, porque se modificó en el contexto de sub-shell. Cualquiera de los comandos que se muestran a continuación se ejecutan en un contexto de sub-shell y el alcance de las variables utilizadas dentro se pierde después de que finaliza el sub-shell.
command &
command | command
( command )
La sustitución del proceso resolverá el problema al evitar el uso de la tubería |
operador como en
count=0
while IFS= read -r _; do
((count++))
done < <(find . -maxdepth 1 -type f -print)
Esto mantendrá el valor de la variable de count
ya que no se invocan sub-shells.