Я бы предположил, что этот код выведет "уф" первый:
echo foo | tee >(rev) | ( sleep 1 ; cat ; )
Выход:
foo
oof
Увеличение sleep
времени не меняет порядок. Почему это не работает?
Обратите внимание, что другие инструментыделатьработать как положено,например: echo foo | pee rev 'sleep 1 ; cat'
.
решение1
В
echo foo | tee >(rev) | (sleep 1; cat)
В bash
похоже на ksh
, но в отличие от zsh
, стандартный вывод rev
также является каналом к (sleep 1; cat)
.
echo
, tee
, rev
и (...)
подоболочка запускаются одновременно, но tee
пишут foo\n
в stdoutдоканал в rev
, так что в любом случае, rev
будет писать oof
в канал после tee
writes foo
, так что oof
может быть только последним. Задержка cat
не имеет инцидентности.
Если вы хотели получить результатrev
нетчтобы пройти по каналу к (sleep 1; cat)
, вы бы использовали zsh
или сделали:
{ echo foo 3>&- | tee >(rev >&3 3>&-) 3>&- | (sleep 1; cat) 3>&-; } 3>&1
Обратите внимание, что в нем zsh
также есть встроенная функция, поэтому вы можете сделать следующее:tee
multios
echo foo > >(rev) > >(sleep 1; cat)
Однако в:
echo foo > >(rev) | (sleep 1; cat)
Вывод rev
будет пройден cat
(что сбивает с толку, учитывая, что в данном случае этого не происходит echo foo >(echo bar) | (sleep 1; cat)
).
решение2
Использование двух bash
подстановок процессов (вместо одной, а затем конвейера) с последующим сбросом STDOUT в /dev/null работает так, как и ожидалось:
echo foo | tee >(rev) >( sleep 1 ; cat ; ) > /dev/null ; sleep 1
Выход:
oof
foo
Примечания:
- the 2-й
sleep
предотвращает "фу" не печатается после командной строки. - Уменьшение
sleep
числа задержек до некоторого оптимального значения должно быть лучше, но я не уверен, каким должно быть это число.1
немного медленно, но, похоже, всегда работает;.01
не всегда работает (то есть выходные данные иногда находятся в неправильном порядке),.1
похоже, работает хорошо.