Entrada estándar múltiple? ¿Cómo?

36

De esta publicación commandlinefu :

$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)

Parece que hay múltiples entradas estándar, pero --- si recuerdo mi curso de programación de Linux correctamente --- esto no puede ser. Pensé que, por definición, la entrada estándar era una secuencia.

Tal vez esto tiene mucho que ver con stdin? ¿Alguien puede explicarme esto? tal vez proporcione enlaces a la documentación.

Bonificación: ¿Cómo manejaría un script estas múltiples transmisiones? Si alguien pudiera proporcionar un ejemplo de Python o Perl, sería muy útil.

Belmin Fernandez
fuente
1
Buena pregunta. En caso de que no lo sepa, hay un sitio de preguntas y respuestas sobre unix / linux: unix.stackexchange.com
Matt Ellen el
2
Documentación para sustituciones de procesos: gnu.org/software/bash/manual/bashref.html#Process-Substitution
glenn jackman
Nota: en Bash es <(…); en el proceso Zsh la sintaxis de sustitución es =(…).
Kamil Maciorowski

Respuestas:

27

Esto no es entrada estándar múltiple. Este es un bashismo que se llama 'Proceso de sustitución' http://tldp.org/LDP/abs/html/process-sub.html

Crea un pseudo archivo ( /dev/fd/something) para cada sustitución. Es bastante útil El comando solo puede leerse como una secuencia, lo que significa que no puede ir y venir con fseek. Necesita leerlo como una secuencia de bytes, como una tubería.

BONUS Respuesta

No necesita hacer demasiado para usar esto. En lo que respecta a su script, obtiene un nombre de archivo válido en la línea de comando, que se puede abrir () ed como cualquier otra cosa. Como otros han dicho, ya verías diff /dev/fd/XX /dev/fd/YY. Si hace una estadística () en cualquiera de estos pseudo-archivos, verá que es una tubería con nombre, y debe tratarla con una semántica de tubería, es decir, sin fseek () o ftell (). Si hace una prueba stat () para ver explícitamente si se trata de un archivo (por ejemplo [ -f $1 ]), esto se romperá; después de todo, esto se implementa como una canalización con nombre.

Rich Homolka
fuente
Otra buena referencia para la sustitución del proceso bash - wiki.bash-hackers.org/syntax/expansion/proc_subst
studgeek
¿Y cuál es el uso recomendado de esta función? ¿Lo admite siempre que su programa pueda funcionar razonablemente con una secuencia en lugar de requerir un archivo con acceso aleatorio?
masterxilo
7

<(...)hace substitución proceso en bash. La salida del proceso en los padres se envía a un descriptor de archivo adicional más allá de los 3 normales, y se devuelve un nombre de archivo correspondiente a ese descriptor de archivo. De esta manera, la salida de un comando puede tratarse como un nombre de archivo para pasar a otro comando.

Ignacio Vazquez-Abrams
fuente
7

Hay uno stdiny uno stdout para cada proceso . Por lo general, están conectados al terminal, pero se pueden redirigir por separado uno del otro.

En el ejemplo, hay dos wgetprocesos involucrados, cada uno de los cuales tiene su propio stdiny stdout. Cada wgetproceso escribe -, que es su stdout. Luego bash, la sustitución del proceso <(...)conecta el stdoutproceso a un pseudo-archivo único, desde el cual diffpuede leer. ¡Tenga en cuenta que las dos sustituciones de proceso producen dos pseudo-archivos diferentes! Por lo tanto, diffve algo como:

diff /dev/fd/XX /dev/fd/YY

donde el stdoutde wget -q -O - URL1está conectado /dev/fd/XXy el stdoutde wget -q -O - URL2a /dev/fd/YY.

musiphil
fuente