2 votos

¿Hay alguna forma de dividir comandos sin usar tee?

Tee imprime la entrada a un comando y a stdout. Me gustaría dividir la entrada pero sin que los contenidos se envíen a stdout.

como

command1 | tee >(command2) >(command3)

intenté

command1 | >(command2) >(command3)

pero esto no reenvía la salida de command1 ni a command2 ni a command3

5voto

David Anderson Puntos 2189

La respuesta fue probada usando zsh versión 5.7.1 y bash versión 3.2.57. La versión de macOS era Catalina (10.15.7). Una buena referencia es la Cheat Sheet de Redirecciones de Bash, la cual asumo (¿en su mayoría?) funciona con zsh.

Una respuesta de zsh

Evidentemente, zsh tiene una característica de multios. Esto permite que una redirección se pueda utilizar múltiples veces, lo cual puede eliminar la necesidad de usar el comando tee.

En tu caso, solo quieres redireccionar la salida estándar dos veces, por lo que la sintaxis de uno de esos métodos sería la siguiente.

comando1 > >(comando2) | comando3

Nota que la línea de arriba ejecuta comando1 y comando2 en subshells. La línea debajo logra las mismas redirecciones, pero en lugar de eso ejecuta comando2 y comando3 en subshells.

comando1 > >(comando2) > >(comando3)

De hecho, zsh puede redirigir la salida hacia tantos comandos como descriptores de archivo estén disponibles. Por ejemplo, si quisieras cuatro, entonces la sintaxis sería la siguiente.

comando1 > >(comando2) > >(comando3) > >(comando4) > >(comando5)

Dos respuestas de bash y zsh

Si buscas algo que sea compatible con tanto bash como zsh, entonces puedes usar el comando tee. Gordon Davisson ya ha publicado un comentario sugiriendo la siguiente respuesta. Aquí, el descriptor de archivo asociado con el pipe usado como entrada estándar para comando2 se elige automáticamente. Con bash, los descriptores de archivo asignados automáticamente comienzan en 63 y disminuyen en valor. Con zsh, los descriptores de archivo asignados automáticamente comienzan en 11 y aumentan en valor.

comando1 | tee >(comando2) | comando3

Si quisieras cuatro, entonces la sintaxis sería la siguiente.

comando1 | tee >(comando2) >(comando3) >(comando4) | comando5

Mi respuesta implica indicar explícitamente qué descriptor de archivo usar, como se muestra a continuación.

comando1 | tee /dev/fd/3 3> >(comando2) | comando3

Si quisieras cuatro, entonces la sintaxis sería la siguiente.

comando1 | tee /dev/fd/3 /dev/fd/4 /dev/fd/5 3> >(comando2) 4> >(comando3) 5> >(comando4) | comando5

Equivalencia entre las dos respuestas de bash y zsh

Como se mencionó anteriormente, la línea de abajo funciona tanto en bash como en zsh.

comando1 | tee >(comando2) >(comando3) >(comando4) | comando5

En bash, la línea sería equivalente a la siguiente (asumiendo que los descriptores de archivo no están siendo utilizados.)

comando1 | tee /dev/fd/63 /dev/fd/62 /dev/fd/61 63> >(comando2) 62> >(comando3) 61> >(comando4) | comando5

Esto se puede confirmar ingresando las líneas de comandos dadas abajo.

fun(){ echo $@ >&2;}
:|fun >(:) >(:) >(:)|: 

En zsh, la línea sería equivalente a la siguiente (asumiendo que los descriptores de archivo no están siendo utilizados).

comando1 | tee /dev/fd/14 /dev/fd/15 /dev/fd/16 14> >(comando2) 15> >(comando3) 16> >(comando4) | comando5

Esto se puede confirmar ingresando las mismas dos líneas de comandos dados para confirmar en bash.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X