Orden de sustitución de procesos `tee` y `bash`

Orden de sustitución de procesos `tee` y `bash`

Habría supuesto que este código se habría impreso "uf" primero:

echo foo | tee >(rev) | ( sleep 1 ; cat ; )

Producción:

foo
oof

Aumentar el sleeptiempo no cambia el orden. ¿Por qué eso no funciona?


Tenga en cuenta que otras herramientashacerfunciona como se supone,p.ej: echo foo | pee rev 'sleep 1 ; cat'.

Respuesta1

En

echo foo | tee >(rev) | (sleep 1; cat)

En bashlike in ksh, pero a diferencia de zsh, la salida estándar de revalso es la tubería a (sleep 1; cat).

echo, teey revel (...)subshell se inician al mismo tiempo, pero teeescriben foo\nen la salida estándarantesla tubería a rev, por lo que, en cualquier caso, revescribirá oofen la tubería después de teeescribir foo, por lo que oofsolo puede ser el último. El retraso catno tiene incidencia.

Si quisieras la salida derev nopara pasar por la tubería hasta (sleep 1; cat), usarías zsho harías:

{ echo foo 3>&- | tee >(rev >&3 3>&-) 3>&- | (sleep 1; cat) 3>&-; } 3>&1

Tenga en cuenta que zshtambién tiene una función incorporada tee, multiospor lo que puede hacer:

echo foo > >(rev) > >(sleep 1; cat)

Sin embargo en:

echo foo > >(rev) | (sleep 1; cat)

La salida de revpasaría cat(confusamente considerando que no es así en el echo foo >(echo bar) | (sleep 1; cat)caso).

Respuesta2

Usar dos bashsustituciones de procesos (en lugar de solo uno, luego una tubería) y luego volcar el STDOUT a /dev/null funciona como se esperaba:

echo foo | tee >(rev) >( sleep 1 ; cat ; ) > /dev/null ; sleep 1

Producción:

oof
foo

Notas:

  • el2do sleeppreviene "foo" se imprima después del símbolo del sistema.
  • reducir el sleepnúmero de retraso a un nivel óptimo debería ser mejor, pero no estoy seguro de cuál debería ser ese número. 1es un poco lento, pero siempre parece funcionar; .01no siempre funciona (es decir, la salida a veces está en el orden incorrecto), .1parece funcionar bien.

información relacionada