Eu teria suposto que esse código teria impresso "ah" primeiro:
echo foo | tee >(rev) | ( sleep 1 ; cat ; )
Saída:
foo
oof
Aumentar o sleep
tempo não altera a ordem. Por que isso não funciona?
Observe que outras ferramentasfazertrabalhar como deveria,por exemplo: echo foo | pee rev 'sleep 1 ; cat'
.
Responder1
Em
echo foo | tee >(rev) | (sleep 1; cat)
Assim bash
como em ksh
, mas ao contrário de zsh
, o stdout de rev
também é o canal para (sleep 1; cat)
.
echo
, tee
e rev
o (...)
subshell são iniciados ao mesmo tempo, mas tee
gravam foo\n
em stdoutanteso pipe to rev
, portanto, em qualquer caso, rev
escreverá oof
no pipe depois de tee
writes foo
, portanto oof
só pode vir por último. Atrasar cat
não tem incidência.
Se você quisesse a saída derev
nãopara passar pelo cano até (sleep 1; cat)
, você usaria zsh
ou faria:
{ echo foo 3>&- | tee >(rev >&3 3>&-) 3>&- | (sleep 1; cat) 3>&-; } 3>&1
Observe que zsh
também possui um recurso integrado tee
, multios
para que você possa fazer:
echo foo > >(rev) > >(sleep 1; cat)
No entanto em:
echo foo > >(rev) | (sleep 1; cat)
A saída de rev
passaria cat
(o que é confuso, considerando que não é o echo foo >(echo bar) | (sleep 1; cat)
caso).
Responder2
Usar duas bash
substituições de processo (em vez de apenas uma e depois um canal) e depois despejar o STDOUT em /dev/null funciona conforme o esperado:
echo foo | tee >(rev) >( sleep 1 ; cat ; ) > /dev/null ; sleep 1
Saída:
oof
foo
Notas:
- o2º
sleep
impede "foo" seja impresso após o prompt de comando. - reduzir o
sleep
número de atraso para um valor ideal deveria ser melhor, mas não tenho certeza de qual deveria ser esse número.1
é um pouco lento, mas sempre parece funcionar;.01
nem sempre funciona (ou seja, a saída às vezes está na ordem errada).1
parece funcionar bem.