Eu tenho um arquivo temporário ( não um fifo / pipe) que precisa ser assistido por vários scripts de leitura. Cada script usa um processo em segundo plano para assistir ao arquivo temporário usando este código:
function file_relay {
# $1 is a regular file to read from
local bg_file
bg_file="$1"
# $2 is a fifo to relay to
local outfile
outfile="$2"
tail -f "$bg_file" | while read -r line
do
[[ ! -z "$line" ]] && { printf "%s" "$line" >>"$outfile"; }
done
}
Eles precisam ler o arquivo inteiro quando iniciam e, em seguida, procurar por novas linhas, que a função acima faz:
file_relay /tmp/examplefile /tmp/examplefifo &
Cada script irá gerar linhas para este arquivo também. Portanto, é uma situação de vários gravadores e vários leitores.
O problema é que, às vezes, tail -f
não espera que uma linha completa esteja disponível, embora eu esteja usando printf
para redirecionar para o arquivo e tenho novas linhas no final das sequências. Isso faz com que as linhas lidas sejam corrompidas, com a primeira palavra da última linha sendo acrescentada no final da anterior, então eu recebo:
This is one lineThis
em vez de
This is one line
This is another line
Eu tentei contornar o armazenamento em buffer de printf
, o buffer de tail -f
, bem como usar sync
em torno de gravações no arquivo (o arquivo é somente leitura na função acima e eu não saber como forçar tail
a executar sync
antes de tentar ler a linha inteira). stdbuf
parece não ter nenhum efeito em lugar nenhum, nem usar -z
para tail
ou terminar strings com $'sync
'
ou qualquer outra coisa. A única coisa que impede que isso aconteça imediatamente é um único while
antes do início do loop tail -f
, mas isso não impede que isso aconteça depois disso.
Existe alguma maneira de forçar o %code% a ler somente as linhas completas?