Aqui está uma solução que funciona sem instalar programas extras, como multitail .
É muito semelhante ao segundo exemplo da pergunta, mas o comando a usar é grep -F '' --line-buffered
. grep -F
here pode ser substituído por fgrep
para breve. Em relação a grep -F
/ fgrep
versus normal regex grep, usar grep de cadeia fixa é ligeiramente mais rápido do que algo como grep ^ --line-buffered
para o mesmo propósito.
Juntando tudo, uma versão com várias linhas é:
(
trap 'kill 0' EXIT
tail -F a | fgrep '' --line-buffered &
tail -F b | fgrep '' --line-buffered &
wait
)
A subshell (
)
pode não ser necessária se isso estiver ocorrendo em um script de shell. Para transformá-lo em um one-liner, livre-se das quebras de linha e coloque ponto e vírgula ( ;
) no final das linhas que não terminam com um e comercial ( &
).
A solução em profundidade
Na verdade, existem dois problemas que isso lida:
Primeiro, tail -F
consumirá e produzirá os bytes nos arquivos da maneira como eles são exibidos, sem esperar pelo fim da linha. Este é apenas o jeito que é e tail
atualmente não fornece nenhuma maneira de alterar isso. Portanto, não podemos fazer tail -Fq a b
e, em vez disso, usar processos separados para cada arquivo.
Em segundo lugar, depois de fazer tail -F
em cada arquivo, o problema continua sendo que a saída pode ser misturada no buffer do tubo. Como tail
é liberado em bytes arbitrários e não em linhas inteiras, há uma ampla causa para isso. A especificação de stdbuf -oL
para o buffer de linha tail
não altera isso, pois a cauda parece sobrescrever isso.
Para contornar o segundo problema, precisamos usar algo como grep
para esperar em linhas inteiras antes de produzir. Além disso, precisamos especificar --line-buffered
caso contrário, o próprio grep armazenará em buffer sua saída e liberará quando o buffer estiver cheio, o que pode não estar em um limite de linha.
Diversos
Para explicar o que trap 'kill 0' EXIT
... wait
faz, é necessário evitar que tail -F
processos sejam deixados para trás quando algo como Ctrl - C é costumava sair.