Una buena manera de detectar la diferencia entre ellos es experimentar un poco en la línea de comando. A pesar de la similitud visual en el uso del <personaje, hace algo muy diferente a una redirección o canalización.
Usemos el datecomando para probar.
$ date | cat
Thu Jul 21 12:39:18 EEST 2011
Este es un ejemplo inútil, pero muestra que cataceptó la salida de dateSTDIN y la volvió a escupir. Los mismos resultados se pueden lograr mediante la sustitución del proceso:
$ cat <(date)
Thu Jul 21 12:40:53 EEST 2011
Sin embargo, lo que sucedió detrás de escena fue diferente. En lugar de recibir una transmisión STDIN, en catrealidad se le pasó el nombre de un archivo que necesitaba abrir y leer. Puede ver este paso utilizando en echolugar de cat.
$ echo <(date)
/proc/self/fd/11
Cuando cat recibió el nombre del archivo, leyó el contenido del archivo. Por otro lado, echo solo nos mostró el nombre del archivo que se pasó. Esta diferencia se vuelve más obvia si agrega más sustituciones:
$ cat <(date) <(date) <(date)
Thu Jul 21 12:44:45 EEST 2011
Thu Jul 21 12:44:45 EEST 2011
Thu Jul 21 12:44:45 EEST 2011
$ echo <(date) <(date) <(date)
/proc/self/fd/11 /proc/self/fd/12 /proc/self/fd/13
Es posible combinar la sustitución del proceso (que genera un archivo) y la redirección de entrada (que conecta un archivo a STDIN):
$ cat < <(date)
Thu Jul 21 12:46:22 EEST 2011
Se ve más o menos igual, pero esta vez a cat se le pasó la transmisión STDIN en lugar de un nombre de archivo. Puedes ver esto probándolo con echo:
$ echo < <(date)
<blank>
Como echo no lee STDIN y no se pasó ningún argumento, no obtenemos nada.
Las canalizaciones y las redirecciones de entrada introducen contenido en la secuencia STDIN. La sustitución de procesos ejecuta los comandos, guarda su salida en un archivo temporal especial y luego pasa ese nombre de archivo en lugar del comando. Cualquier comando que esté usando lo trata como un nombre de archivo. Tenga en cuenta que el archivo creado no es un archivo normal, sino una tubería con nombre que se elimina automáticamente una vez que ya no es necesario.
[[ -p <(date) ]] && echo true. Esto producetruecuando lo ejecuto con bash 4.4 o 3.2.Supongo que está hablando de
bashalgún otro shell avanzado, porque el shell posix no tiene sustitución de proceso .bashinformes de la página del manual:En otras palabras, y desde un punto de vista práctico, puede usar una expresión como la siguiente
como nombre de archivo para otros comandos que requieren un archivo como parámetro. O puede usar la redirección para dicho archivo:
Volviendo a su pregunta, me parece que la sustitución de procesos y las tuberías no tienen mucho en común.
Si desea canalizar en secuencia la salida de varios comandos, puede utilizar uno de los siguientes formularios:
pero también puede usar la redirección en la sustitución del proceso
finalmente, si
command3acepta un parámetro de archivo (en sustitución de stdin)fuente
Aquí hay tres cosas que puede hacer con la sustitución de procesos que de otra manera serían imposibles.
Múltiples entradas de proceso
Simplemente no hay forma de hacer esto con tuberías.
Preservando STDIN
Digamos que tiene lo siguiente:
Y quieres ejecutarlo directamente. Lo siguiente falla miserablemente. Bash ya está utilizando STDIN para leer el script, por lo que otra entrada es imposible.
Pero de esta manera funciona perfectamente.
Sustitución de proceso de salida
También tenga en cuenta que la sustitución de procesos también funciona a la inversa. Entonces puedes hacer algo como esto:
Ese es un ejemplo un poco complicado, pero envía stdout a
/dev/null, mientras canaliza stderr a un script sed para extraer los nombres de los archivos para los que se mostró un error de "Permiso denegado", y luego envía LOS resultados a un archivo.Tenga en cuenta que el primer comando y la redirección stdout están entre paréntesis ( subshell ) para que solo se envíe el resultado de ESE comando
/dev/nully no se meta con el resto de la línea.fuente
diffejemplo es posible que desee que se preocupan por el caso en que elcdpuede fallar:diff <(cd /foo/bar/ && ls) <(cd /foo/baz && ls).Si un comando toma una lista de archivos como argumentos y procesa esos archivos como entrada (o salida, pero no comúnmente), cada uno de esos archivos puede ser una tubería con nombre o un pseudoarchivo / dev / fd proporcionado de forma transparente por la sustitución del proceso:
Esto "canalizará" la salida de los tres comandos para ordenar, ya que ordenar puede tomar una lista de archivos de entrada en la línea de comandos.
fuente
<(), como muchas funciones avanzadas de shell, originalmente era una función ksh y fue adoptada por bash y zsh.psubes específicamente una función de peces, nada que ver con POSIX.Cabe señalar que la sustitución del proceso no se limita al formulario
<(command), que utiliza la salida decommandcomo un archivo. También puede tener el formato>(command)que alimenta un archivo como entradacommand. Esto también se menciona en la cita del manual bash en la respuesta de @ enzotib.Para el
date | catejemplo anterior, un comando que usa la sustitución de proceso del formulario>(command)para lograr el mismo efecto sería,Tenga en cuenta que lo
>anterior>(cat)es necesario. Esto puede ser nuevamente ilustrado claramenteechocomo en la respuesta de @ Caleb.Entonces, sin el extra
>,date >(cat)sería lo mismodate /dev/fd/63que imprimirá un mensaje en stderr.Supongamos que tiene un programa que solo toma nombres de archivos como parámetros y no procesa
stdinnistdout. Usaré el script simplificadopsub.shpara ilustrar esto. El contenido depsub.shesBásicamente, prueba que sus dos argumentos son archivos (no necesariamente archivos regulares) y, si este es el caso, escriba el primer campo de cada línea
"$1"para"$2"usar awk. Entonces, un comando que combina todo lo mencionado hasta ahora es,Esto imprimirá
y es equivalente a
pero lo siguiente no funcionará, y tenemos que usar la sustitución del proceso aquí,
o su forma equivalente
Si
./psub.shtambién se leestdinademás de lo mencionado anteriormente, entonces no existe una forma equivalente, y en ese caso no hay nada que podamos usar en lugar de la sustitución del proceso (por supuesto, también puede usar una tubería con nombre o un archivo temporal, pero ese es otro historia).fuente