Обычно я использую command1 | command2 | command3
много в Linux, но большинство из них имеют дело с определенным контентом.
Когда я попробовал это с бесконечным потоком cat | sed '' | sed ''
, который, как я надеюсь, имитирует бесконечный поток, это не сработало, пока я не завершил его с помощью Ctrl-D. Я могу решить проблему с помощью cat | sed -e '' -e ''
, но я хотел бы знать, почему первый вариант не работает. cat | cat | cat
работает просто отлично. Это как-то связано с sed
, если да, то в чем проблема?
Я попытался обдумать эту проблему, и единственное, что я обнаружил, это то, что когда я нажимаю cat
клавишу, Enterона делает что-то особенное, чего не происходит в первом примере sed ''
выше?
Может ли кто-нибудь подсказать, как заставить трубу работать без сбоев при бесконечном потоке пара?
решение1
Каналы соединяют выход левой команды с входом правой команды. Это не имеет никакого отношения к длине потока. Однако каждая команда в конвейере по-прежнему имеет свои правила буферизации. Если вы не активируете их в каждой команде, вы не увидите их на конечном выходе.
решение2
Это по сути дубликатмой ответ на SO. Однако, поскольку никто не упомянул stdbuf
здесь эту команду, я посчитал нужным добавить и ее здесь.
===============
По сути, процесс, считывающий данные из канала, может потреблять данные байт за байтом, как только они становятся доступны в канале. Однако, пока программы используют функции std io библиотеки libc, такие как чтение, запись и т. д., библиотека libc будет буферизировать ввод/вывод этих программ в зависимости от того, пишет ли программа в терминал или нет.
По умолчанию, если программа пишет на терминал, libc буферизует вывод построчно, если же вывод не на терминал, то буферизует поблочно.
В Linux, имея glibc, вы можете повлиять на это поведение с помощью stdbuf
команды, например:
stdbuf -oL cat | stdbuf -ioL sed '' | stdbuf -iL sed ''
Я использую построчный буфер вывода для cat
команды, построчный буфер ввода и вывода для первой sed
команды и построчный буфер ввода для последней sed
команды.
решение3
Для минимизации буферизации можно использовать -u
опцию sed:
cat | sed -u '' | sed ''