Hay algunos comandos que filtran o actúan en la entrada, y luego la pasan como salida, creo que generalmente stdout
, pero algunos comandos simplemente tomarán stdin
y harán lo que hagan con ella, y no generarán nada.
Estoy más familiarizado con OS X, por lo que hay dos que se me ocurren de inmediato pbcopy
y pbpaste
, que son medios para acceder al portapapeles del sistema.
De todos modos, sé que si quiero tomar stdout y escupir la salida para ir a ambos stdout
y a un archivo, entonces puedo usar el tee
comando. Y sé un poco sobre eso xargs
, pero no creo que eso sea lo que estoy buscando.
Quiero saber cómo puedo dividir stdout
para ir entre dos (o más) comandos. Por ejemplo:
cat file.txt | stdout-split -c1 pbcopy -c2 grep -i errors
Probablemente haya un mejor ejemplo que ese, pero realmente estoy interesado en saber cómo puedo enviar stdout a un comando que no lo retransmite y mientras evito que stdout
sea "silenciado": no estoy preguntando cómo hacer cat
un archivo y grep
parte de él y cópielo en el portapapeles; los comandos específicos no son tan importantes.
Además, no estoy preguntando cómo enviar esto a un archivo y stdout
esta puede ser una pregunta "duplicada" (lo siento), pero busqué un poco y solo pude encontrar otras similares que preguntaban cómo dividir entre stdout y un archivo - y las respuestas a esas preguntas parecían ser tee
, lo cual no creo que funcione para mí.
Finalmente, puede preguntar "¿por qué no hacer que pbcopy sea lo último en la cadena de tuberías?" y mi respuesta es 1) ¿qué pasa si quiero usarlo y aún así ver el resultado en la consola? 2) ¿Qué pasa si quiero usar dos comandos que no salen stdout
después de que procesan la entrada?
Ah, y una cosa más: me doy cuenta de que podría usar tee
una tubería con nombre ( mkfifo
), pero esperaba que esto se pudiera hacer en línea, de manera concisa, sin una configuración previa :)
Respuestas:
Puede usar
tee
y procesar la sustitución para esto:Esto enviará toda la salida de
cat file.txt
apbcopy
, y solo obtendrá el resultadogrep
en su consola.Puede poner múltiples procesos en la
tee
parte:fuente
pbcopy
, pero vale la pena mencionar en general: cualquiera que sea la salida de sustitución del proceso también se ve en el siguiente segmento de tubería, después de la entrada original; por ejemplo:seq 3 | tee >(cat -n) | cat -e
(cat -n
numera las líneas de entrada,cat -e
marca nuevas líneas con$
; verá quecat -e
se aplica tanto a la entrada original (primero) como (luego) a la salida decat -n
). La salida de múltiples sustituciones de proceso llegará en un orden no determinista.>(
único funciona enbash
. Si intenta eso usando, por ejemplosh
, no funcionará. Es importante hacer este aviso.dash
, que actúa comosh
en Ubuntu, no lo admite, e incluso Bash desactiva la función cuando se invocash
cuandoset -o posix
está vigente. Sin embargo, no es solo Bash el que admite las sustituciones de procesos:ksh
y también laszsh
admite (no estoy seguro acerca de los demás).bash
yksh
,zsh
aparentemente, no envía la salida de las sustituciones del proceso de salida a través de la tubería (posiblemente, eso es preferible , porque no contamina lo que se envía al siguiente segmento de tubería) todavía se imprime ). Sin embargo, en todos los shells mencionados, generalmente no es una buena idea tener una sola tubería en la que se mezclen la salida estándar y la salida de las sustituciones del proceso: el orden de salida no será predecible, de una manera que solo puede surgir con poca frecuencia o con grandes conjuntos de datos de salida.Puede especificar varios nombres de archivo
tee
y, además, la salida estándar se puede canalizar en un comando. Para enviar la salida a múltiples comandos, debe crear varias tuberías y especificar cada una de ellas como una salida detee
. Hay varias maneras de hacer esto.Proceso de sustitución
Si su shell es ksh93, bash o zsh, puede usar la sustitución de procesos. Esta es una manera de pasar una tubería a un comando que espera un nombre de archivo. El shell crea la tubería y pasa un nombre de archivo como
/dev/fd/3
al comando. El número es el descriptor de archivo al que está conectada la tubería. Algunas variantes de Unix no son compatibles/dev/fd
; en estos, se usa una tubería con nombre en su lugar (ver más abajo).Descriptores de archivo
En cualquier shell POSIX, puede usar múltiples descriptores de archivo explícitamente. Esto requiere una variante de Unix que admita
/dev/fd
, ya que todas menos una de las salidas detee
deben especificarse por nombre.Tubos con nombre
El método más básico y portátil es utilizar tuberías con nombre . La desventaja es que necesita encontrar un directorio de escritura, crear las tuberías y limpiar después.
fuente
tee "$tmp_dir/f1" "$tmp_dir/f2" | command3
seguramente debería sercommand3 | tee "$tmp_dir/f1" "$tmp_dir/f2"
, como quieres stdout decommand3
tuberíatee
, ¿no? Probé su versióndash
ytee
bloquea indefinidamente la espera de entrada, pero cambiar el orden produjo el resultado esperado.command
,command2
ycommand3
.<command> | bash -c 'tee >(command1) >(command2) | command3'
. Ayudó en mi caso.Solo juega con la sustitución del proceso.
grep
son dos binarios que tienen el mismo resultadomycommand_exec
que su entrada específica del proceso.fuente
Si está utilizando
zsh
, puede aprovechar el poder de laMULTIOS
función, es decir, deshacerse deltee
comando por completo:solo escribirá la salida de
uname
dos archivos diferentes:file1
yfile2
, lo que es equivalente auname | tee file1 >file2
De manera similar, la redirección de entradas estándar
es equivalente a
cat file1 file2 | wc -l
(tenga en cuenta que esto no es lo mismo quewc -l file1 file2
, el último cuenta el número de líneas en cada archivo por separado).Por supuesto, también puede usarlo
MULTIOS
para redirigir la salida, no a archivos, sino a otros procesos, mediante la sustitución de procesos, por ejemplo:fuente
MULTIOS
es una opción que está activada de forma predeterminada (y se puede desactivar conunsetopt MULTIOS
).Para una salida razonablemente pequeña producida por un comando, podemos redirigir la salida a un archivo temporal y enviar esos archivos temporales a los comandos en bucle. Esto puede ser útil cuando el orden de los comandos ejecutados puede ser importante.
El siguiente script, por ejemplo, podría hacer eso:
Prueba de ejecución en Ubuntu 16.04 con
/bin/sh
comodash
shell:fuente
Capture el comando
STDOUT
en una variable y reutilícelo tantas veces como desee:Si necesita capturar
STDERR
también, use2>&1
al final del comando, así:fuente
Esto puede ser útil: http://www.spinellis.gr/sw/dgsh/ (shell de gráfico dirigido) Parece un reemplazo de bash que admite una sintaxis más fácil para los comandos "multipipe".
fuente
Aquí hay una solución parcial rápida y sucia, compatible con cualquier shell incluido
busybox
.El problema más estrecho que resuelve es: imprimir el completo
stdout
en una consola y filtrarlo en otra, sin archivos temporales ni canalizaciones con nombre.tty
. Vamos a suponer/dev/pty/2
.the_program | tee /dev/pty/2 | grep ImportantLog:
Obtiene un registro completo y uno filtrado.
fuente