непрерывное чтение из именованного канала (cat или tail -f)

непрерывное чтение из именованного канала (cat или tail -f)

Я настроил rsyslogрегистрацию определенных событий журнала в /dev/xconsole:

*.*;cron.!=info;mail.!=info      |/dev/xconsole

/dev/xconsoleявляется именованным каналом ( fifo). Если я хочу увидеть, что регистрируется, я могу сделать cat /dev/xconsole. Я удивлен, увидев, что команда cat /dev/xconsoleне завершается после чтения файла, а вместо этого действует как tail -f. Другими словами, две команды ведут себя одинаково:

cat /dev/xconsole
tail -f /dev/xconsole

Может ли кто-нибудь объяснить, почему это так?

Есть ли между ними разница?

решение1

catпродолжает читать, пока не получит EOF. Канал выдает EOF на выходе только тогда, когда получает EOF на входе. Демон регистрации открывает файл, записывает в него,и держать его открытым— так же, как и для обычного файла — поэтому EOF никогда не генерируется на выходе. catПросто продолжает чтение, блокируясь, когда исчерпывается то, что в данный момент находится в канале.

Вы можете попробовать сделать это самостоятельно вручную:

$ mkfifo test
$ cat test

И в другом терминале:

$ cat > test
hello

В другом терминале будет вывод. Затем введите:

world

Будетболеевывод в другом терминале. Если вы сейчас нажмете Ctrl-D на ввод, то другой catтоже прервется.

В этом случае единственное заметное различие между catи tail -fбудет заключаться в том, будет ли демон ведения журнала остановлен или перезапущен: catостановится навсегда, когда будет закрыт конец записи канала, но tail -fпродолжит работу (повторно открыв файл) при перезапуске демона.

решение2

Также есть разница вбуферизациямежду catи tail -f. Вы можете проверить это:

Создать трубу:mkfifo pipe

Запустить чтение канала catв фоновом режиме:cat pipe &

Открываем канал и пишем в него каждую секунду:perl -MFcntl -we 'sysopen(my $fh, "pipe", O_WRONLY | O_NONBLOCK); while() {warn "written: " . syswrite($fh, "hello\n"); sleep 1}'

Теперь попробуйте это с tail -f pipe &. catТак что вы можете видеть, что он catпечатает строки сразу после того, как они записываются в конвейер скриптом Perl, при этом tail -f буферизуя их до 4 Кб перед печатью в stdout.

решение3

catпоказывает вам весь файл, когда tail -fпоказывает только последние строки и последующие. Так что если файл короткий, они ведут себя одинаково, но если файл большой (100+ строк), вы можете увидеть четкую разницу между ними двумя.

Дополнительная информация об этих командах:

tail http://www.computerhope.com/unix/utail.htm

cat http://www.computerhope.com/unix/ucat.htm

Связанный контент