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

815
Sridhar-Sarnobat

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

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, но не получил ответов)

7
Ваш код работает для меня. Может быть, вы могли бы более подробно рассказать о том, как вы «кормите« а ») в свою пятерку. John1024 9 лет назад 2
Как сказал @ John1024, [WorksForMe] (http://i.stack.imgur.com/VNrxB.png). Bob 9 лет назад 0
У меня тоже нет проблем вообще. MariusMatutiae 9 лет назад 0
`echo" a "> fifo` Sridhar-Sarnobat 9 лет назад 0
Кажется, это связано с буферизацией. Какую версию sed вы используете? Мой `GNU sed версия 4.2.1` Sridhar-Sarnobat 9 лет назад 0
@ Шридхар-Сарнобат 4.2.2 здесь. Предоставляется пакетом `sed`, версия` 4.2.2-4ubuntu1`. Но это также может быть связано с тем, как производитель (`echo` / оболочка, которую вы используете) сбрасывает свой выходной поток, а не потребитель (sed). Bob 9 лет назад 0

1 ответ на вопрос

8
Volker Siegel

Use the -u (--unbuffered) option of sed, so it writes it's output, instead of collecting it first for a fast, large write later.

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

cat is always unbuffered.

If it's not about sed, but some program with output buffering, but without options to disable it, there are tools that can help to force buffering off - see man unbuffer and man stdbuf.

If it's a shell script, it should be unbuffered by default: when a command creates output in the script, and exits, the output is flushed. Otherwise, you use unbuffer inside the shell script.

For background, see this overview of stdio buffering.

Предположим, вместо sed у меня был свой собственный скрипт. Что бы я сделал в этом случае, чтобы избежать буферизации? Или он должен быть небуферизован по умолчанию? Sridhar-Sarnobat 9 лет назад 0
Еще несколько замечаний - если бы я хотел использовать регулярные выражения perl с буферизацией, он бы выглядел примерно так: `nc -k -l 4458 | perl -ne 's g; $ | ++; печать $ _ '| perl -ne 's g; $ | ++; печать $ _ '` Sridhar-Sarnobat 9 лет назад 0
Да что ты имеешь ввиду? Есть проблема или это пример? О, и вы можете использовать `ssed -R`, если вам нравится` sed` с регулярными выражениями perl. Volker Siegel 9 лет назад 0
Извините, это был не вопрос. Я прошу прощения за то, что не ясно, это был просто еще один пример той же концепции. К сожалению, мне уже поздно редактировать этот комментарий. Я не знал, что sed может понять регулярные выражения Perl. Возможно, я должен начать использовать это вместо этого отныне. Sridhar-Sarnobat 9 лет назад 0
О, нет проблем! Volker Siegel 9 лет назад 0