leitura contínua do pipe nomeado (cat ou tail -f)

15

Eu configurei rsyslog para registrar determinados eventos de log em /dev/xconsole :

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

/dev/xconsole é um canal nomeado ( fifo ). Se eu quiser ver o que está sendo registrado, posso fazer cat /dev/xconsole . Eu estou surpreso em ver que o comando cat /dev/xconsole não termina depois de ler o arquivo, mas age como tail -f . Em outras palavras, os dois comandos se comportam da mesma maneira:

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

Alguém pode, por favor, explicar por que isso acontece?

Existe alguma diferença entre os dois?

    
por Martin Vegter 27.06.2014 / 11:47

3 respostas

17

cat continua lendo até obter EOF. Um pipe produz EOF na saída somente quando recebe EOF na entrada. O daemon de logging está abrindo o arquivo, escrevendo para ele, e mantendo-o aberto - como faz para um arquivo regular - portanto, o EOF nunca é gerado na saída. cat apenas continua lendo, bloqueando sempre que exaure o que está atualmente no canal.

Você pode fazer isso manualmente:

$ mkfifo test
$ cat test

E em outro terminal:

$ cat > test
hello

Haverá saída no outro terminal. Então:

world

Haverá mais saída no outro terminal. Se você agora Ctrl-D a entrada, então o outro cat terminará também.

Nesse caso, a única diferença observável entre cat e tail -f será se o daemon de log for encerrado ou reiniciado: cat será interrompido permanentemente quando a extremidade de gravação do canal for fechada, mas tail -f irá continuar (reabrindo o arquivo) quando o daemon for reiniciado.

    
por 27.06.2014 / 12:11
1

Há também uma diferença no buffer entre cat e tail -f . Você pode verificar isso:

Criar canal: mkfifo pipe

Inicie o canal de leitura usando cat em segundo plano: cat pipe &

Abra o canal e escreva para ele a cada segundo: perl -MFcntl -we 'sysopen(my $fh, "pipe", O_WRONLY | O_NONBLOCK); while() {warn "written: " . syswrite($fh, "hello\n"); sleep 1}'

Agora, tente isso com tail -f pipe & em vez de cat . Assim, você pode ver que cat imprime linhas assim que elas são gravadas no pipe por script perl, enquanto tail -f as armazena em buffer até 4kb antes de imprimir no stdout.

    
por 12.02.2018 / 17:56
-2

cat mostra todo o arquivo quando tail -f mostra apenas as últimas linhas e segue. Então, se o arquivo é curto, eles se comportam da mesma forma, mas se o arquivo for grande (mais de 100 linhas), você pode ver uma clara diferença entre eles.

Informações adicionais sobre esses comandos:

tail link

cat link

    
por 27.06.2014 / 12:07

Tags