'tee' e 'bash' processo de substituição

3

Eu suponho que este código teria impresso " oof " primeiro:

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

Saída:

foo
oof

Aumentar o tempo de sleep não altera a ordem. Por que isso não funciona?

Note que outras ferramentas do funcionam como supostas, por exemplo. : echo foo | pee rev 'sleep 1 ; cat' .

    
por agc 22.11.2017 / 16:54

2 respostas

7

Em

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

Em bash como em ksh , mas ao contrário de zsh , o stdout de rev também é o canal para (sleep 1; cat) .

echo , tee , rev e o (...) subshell são iniciados ao mesmo tempo, mas tee escreve foo\n para stdout antes do pipe para rev , portanto, em qualquer caso, rev gravará oof no canal depois de tee gravar foo , portanto, oof só pode vir por último. Atrasar cat não tem incidência.

Se você quiser que a saída de rev não passe pelo canal até (sleep 1; cat) , use zsh ou faça:

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

Tenha em atenção que zsh também possui uma tee incorporada na funcionalidade multios , pelo que pode:

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

No entanto, em:

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

A saída de rev passará por cat (considerando, de forma confusa, que não está no caso echo foo >(echo bar) | (sleep 1; cat) ).

    
por 22.11.2017 / 17:21
0

Parece que usar duas substituições do processo bash (em vez de apenas uma, depois um canal) funciona como esperado:

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

Saída:

oof
foo

Observe que o 2nd sleep impede que " foo " seja impresso após o prompt de comando.

    
por 12.02.2018 / 05:15