Saída do conteúdo do arquivo enquanto eles mudam

47

Quero exibir o conteúdo de um arquivo enquanto eles mudam, por exemplo, se eu tenho o arquivo foobare faço:

magic_command foobar

O terminal atual deve exibir o conteúdo do arquivo e aguardar até que eu não saiba, pressione ^ C.

Então, se de outro terminal eu faço:

echo asdf >> foobar

O primeiro terminal deve exibir a linha recém-adicionada, além do conteúdo original do arquivo (é claro, já que eu não pressionei ^ C).

Vou marcar isso como lição de casa, já que quero explorar e aprender Linux, mas não é lição de casa, é apenas uma curiosidade minha.

Paulo
fonte
stackoverflow.com/questions/6143838/…
Ciro Santilli escreveu:

Respostas:

79

Você pode usar tail commandcom -f :

tail -f /var/log/syslog 

É uma boa solução para o show em tempo real.

PersianGulf
fonte
você pode escrever um script e redirecionar sua saída para o seu script.
precisa saber é o seguinte
6
Você também pode usar -F(capital f), que reabrirá o arquivo se ele for removido e recriado ao longo do caminho.
Peterph
19

Se você deseja mostrar um arquivo curto, que caiba na tela de um terminal, e o que está mudando é possivelmente o arquivo inteiro, você pode usar watch:

watch cat example.txt

Every 2.0s: cat example.txt                                Sun Aug  3 15:25:20 2014

Some text
another line

Ele mostra o arquivo inteiro a cada 2 segundos por padrão, incluindo um cabeçalho opcional:

A opção -d( --differences) destacará as alterações da versão anterior da saída ou da primeira versão.

Volker Siegel
fonte
9

Quando preciso detectar alterações no arquivo e fazer algo diferente do que tail -f filenamefaz, usei inotifywaitem um script para detectar a alteração e agir de acordo com ela. Um exemplo de uso é mostrado abaixo. Veja man inotifywaitpara outros nomes de eventos e opções. Pode ser necessário instalar o inotify-toolspacote, por exemplo, via sudo apt-get install inotify-tools.

Aqui está o script de exemplo, chamado exec-on-change:

 #!/bin/sh

# Detect when file named by param $1 changes.
# When it changes, do command specified by other params.

F=$1
shift
P="$*"

# Result of inotifywait is put in S so it doesn't echo
while  S=$(inotifywait -eMODIFY $F 2>/dev/null)
do
  # Remove printf if timestamps not wanted 
  printf "At %s: \n" "$(date)"
  $P
done

Em dois consoles, digitei comandos da seguinte maneira (onde A> significa entrada no console A e B> significa entrada no console B.)

A> rm t; touch t
B> ./exec-on-change t wc t
A> date >>t
A> date -R >>t
A> date -Ru >>t
A> cat t; rm t

A seguinte saída cat tapareceu no console A:

Thu Aug 16 11:57:01 MDT 2012
Thu, 16 Aug 2012 11:57:04 -0600
Thu, 16 Aug 2012 17:57:07 +0000

A seguinte saída de exec-on-changeapareceu no console B:

At Thu Aug 16 11:57:01 MDT 2012: 
 1  6 29 t
At Thu Aug 16 11:57:04 MDT 2012: 
 2 12 61 t
At Thu Aug 16 11:57:07 MDT 2012: 
 3 18 93 t

O exec-on-changeroteiro terminado quando eu rm'd t.

James Waldby - jwpat7
fonte
8

lesstem um modo de acompanhamento semelhante a tail -f- basta clicar Fquando o abrir.

peterph
fonte
4

Eu tenho três soluções:

1) tail -f é uma boa ideia

2) também temos tailfque usar

3) o terceiro é um script bash:

#!/bin/bash

GAP=10     #How long to wait
LOGFILE=$1 #File to log to

if [ "$#" -ne "1" ]; then
    echo "USAGE: `basename $0` <file with absolute path>"
    exit 1
fi


#Get current long of the file
len=`wc -l $LOGFILE | awk '{ print $1 }'`
echo "Current size is $len lines."

while :
do
    if [ -N $LOGFILE ]; then
        echo "`date`: New Entries in $LOGFILE: "
        newlen=`wc -l $LOGFILE | awk ' { print $1 }'`
        newlines=`expr $newlen - $len`
        tail -$newlines $LOGFILE
        len=$newlen
    fi
sleep $GAP
done
exit 0
MLSC
fonte