Tail -f quebra quando o arquivo é truncado

1

Estou usando tail -f (no Terminal no Mac OS X el capitan) para visualizar as alterações ativas em meu arquivo (os resultados de extrair dados de um banco de dados usando um script PERL). No entanto, às vezes, o script Perl truncará o arquivo e adicionará novos dados a ele. Às vezes, quando isso acontece, isso me dá essa mensagem:

tail: test.txt: file truncated

E depois não mostra nenhum conteúdo do arquivo depois. Isso parece acontecer apenas quando estou substituindo um arquivo por linhas MENOS do que antes. Quando as novas linhas são maiores do que antes de executar o script, eu não recebo esse erro e o tail -f continua a funcionar. Confirmei que existem, de fato, dados no arquivo que tail -f não está mostrando depois de receber essa mensagem (erro?).

Eu vi essa pergunta semelhante: Suprimir 'arquivo truncado' mensagens ao usar a cauda

tail -f test.txt 2> /dev/null

Mas isso apenas suprime a mensagem e ainda é interrompido; ela não continua a mostrar o conteúdo do arquivo mais curto e truncado.

Existe um comando melhor para usar para exibir as alterações no arquivo? Ou um sinalizador para tail -f para não se importar quando o arquivo é truncado?

    
por ProGrammar 10.05.2017 / 17:12

3 respostas

3

Como outros apontaram, o comando tail que vem com o OS X não possui a opção --retry . No entanto, você poderia simplesmente instalar a versão GNU da cauda que tem essa opção; faz parte do GNU coreutils . Por exemplo, se você usar MacPorts, poderá instalá-los executando sudo port install coreutils .

Uma alternativa para assistir a um arquivo ao vivo é o comando watch , que infelizmente também não é fornecido com o OS X. No entanto, você pode usar esta solução simples .

    
por 10.05.2017 / 18:19
1

Aqui está um script tail-F . Demora um único argumento - o arquivo a cauda. Provavelmente existem opções melhores (como a instalação do GNU tail ), mas está aqui para demonstrar que versões simples de ferramentas podem ser construídas a partir das partes disponíveis.

#!/bin/bash
#
file="$1"
size=$(stat -c '%s' "$file" 2>/dev/null)
test -z "$size" && echo "No file '$file'" >&2

while sleep 1
do
    n_size=$(stat -c '%s' "$file" 2>/dev/null)

    if [[ -n "$n_size" ]]
    then
        if [[ 0 == "$size" ]]
        then
            # Output whole file (so far)
            dd bs=1K if="$file" 2>/dev/null
            size="$n_size"

        elif [[ "$n_size" > "${size:-0}" ]]
        then
            # Output new part of file
            dd bs="$size" skip=1 if="$file" 2>/dev/null
            size="$n_size"

        elif [[ -z "$size" ]]
        then
            echo "New file '$file'" >&2
            size=0

        elif [[ "$n_size" < "${size:-0}" ]]
        then
            echo "Rewinding file '$file'" >&2
            size=0
        fi
    fi
done
    
por 10.05.2017 / 19:25
-1

O comando a seguir mantém a repetição do arquivo, mesmo que seja removido ou inacessível. Ele novamente imprimirá o conteúdo depois de criá-lo.

tail -F filename --retry
    
por 10.05.2017 / 17:31

Tags