Несколько Unix труб не работают

Этот первый конвейер работает нормально (печать "c"):

echo "a" | sed 's/a/b/' | sed 's/b/c/'

Этот не делает то, что я ожидаю (ничего не печатается, когда я подаю "а" в моем fifo):

mkfifo fifo;
cat fifo | sed 's/a/b/' | sed 's/b/c/' 

Однако, если я удаляю вторую команду "sed" из последнего конвейера, я получаю "b". Я думаю, что мое понимание каналов и перенаправлений должно быть слишком упрощенным. Может кто-нибудь объяснить мне, как исправить второй случай, чтобы я мог выполнить две последовательные команды для содержимого fifo?

(обратите внимание, что это не проблема, специфичная для fifo, то же самое происходит и с netcat. Я опубликовал аналогичный вопрос о netcat, но не получил ответов)

1 ответ

Решение

Использовать -u (--unbuffered) параметр sed, поэтому он записывает свой вывод, а не собирает его сначала для быстрой, большой записи позже.

cat fifo | sed -u 's/a/b/' | sed -u 's/b/c/'

cat всегда небуферизован.

Если это не о sed, но некоторые программы с буферизацией вывода, но без опций для ее отключения, есть инструменты, которые могут помочь отключить буферизацию - смотрите man unbuffer а также man stdbuf,

Если это сценарий оболочки, по умолчанию он должен быть небуферизован: когда команда создает выходные данные в сценарии и завершается, выходные данные сбрасываются. В противном случае вы используете unbuffer внутри сценария оболочки.

Для справки смотрите этот обзор буферизации stdio.

Другие вопросы по тегам