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.