Como faço para “catear e seguir” um arquivo?

27

Um arquivo está sendo baixado sequencialmente por wget .

Se eu começar a desempacotá-lo com cat myfile.tar.bz2 | tar -xj , ele poderá ser descompactado corretamente ou falhar com "EOF inesperado", dependendo do que for mais rápido.

Como "cat e seguir" um arquivo, ou seja, conteúdo de saída do arquivo para stdout, mas não sair no EOF, em vez disso, manter inscrito nesse arquivo e continuar a saída de novas partes dos dados, saindo apenas se o arquivo é fechado pelo escritor e não reaberto dentro de N segundos.

Eu criei um script cat_and_follow baseado em @ arielCo's answer que também finaliza o tail quando o arquivo não está sendo aberto para gravação.

    
por Vi. 30.06.2014 / 02:59

3 respostas

19
tail +1f file

Eu testei no Ubuntu com o tarball de fonte do LibreOffice enquanto wget estava baixando:

tail +1f libreoffice-4.2.5.2.tar.xz | tar -tvJf -

Ele também funciona no Solaris 10, RHEL3, AIX 5 e Busybox 1.22.1 no meu telefone Android (use tail +1 -f file com o Busybox).

    
por 30.06.2014 / 04:59
11

O problema é que cat não está ciente de que o arquivo ainda está sendo anexado. Assim que cat encontrar o final (atual) do arquivo, ele será encerrado.

Você precisa fazer wget escrever em um pipe (ou FIFO) para evitar isso.

wget -O - http://... | tar -xjf -
    
por 30.06.2014 / 03:19
5

Para ler e seguir um arquivo desde o início até ser interrompido:

tail -fn +1 file

Para demonstrar isso, tente isso (assumindo o Bash com o GNU Coreutils):

(while true; do printf . >> /tmp/file; sleep 1; done)&
tail -fn +1 /tmp/file  # (Ctrl-C to interrupt, of course, or otherwise kill it.)
kill %  # Kills the while-loop.

(Nota: O +1f mencionado por outros é interpretado como um nome de arquivo, pelo menos no comando tail do GNU.)

O acima funciona para um único arquivo. A concatenação de múltiplos arquivos não seria capaz de seguir todos de forma determinista, sem depender do primeiro. Para ' cat e seguir ', seguindo somente o último arquivo, pode-se usar substituição de processos . Aqui está outra demonstração:

printf file1 > /tmp/file1; printf file2 > /tmp/file2
(while true; do printf . | tee -a /tmp/file{1,2} > /dev/null; sleep 1; done)&
cat /tmp/file1 <(tail -fn +1 /tmp/file2)  # (Interrupt or kill it.)
kill %  # Kills the while-loop.
    
por 04.08.2015 / 04:21