Wyjściowa zawartość pliku podczas ich zmiany


47

Chcę wyprowadzić zawartość pliku, gdy się zmieniają, na przykład jeśli mam plik foobari robię:

magic_command foobar

Bieżący terminal powinien wyświetlać zawartość pliku i czekać, aż, nie wiem, nacisnę ^ C.

Następnie, jeśli z innego terminala:

echo asdf >> foobar

Pierwszy terminal powinien wyświetlać nowo dodaną linię oprócz oryginalnej zawartości pliku (oczywiście biorąc pod uwagę, że nie nacisnąłem ^ C).

Oznaczę to jako pracę domową, ponieważ chcę odkrywać i uczyć się Linuksa, ale to nie jest praca domowa, to tylko moja ciekawość.


Odpowiedzi:


79

Możesz używać tail commandz -f :

tail -f /var/log/syslog 

To dobre rozwiązanie do pokazów w czasie rzeczywistym.


możesz napisać skrypt i przekierować wyniki na swój skrypt.
PersianGulf

6
Możesz także użyć -F(wielkich liter f), które ponownie otworzą plik, jeśli zostanie on usunięty i ponownie utworzony po drodze.
peterph

19

Jeśli chcesz pokazać krótki plik, który mieści się na jednym ekranie terminala, a zmieniający się jest prawdopodobnie cały plik, możesz użyć watch:

watch cat example.txt

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

Some text
another line

Domyślnie pokazuje cały plik co 2 sekundy, w tym opcjonalny nagłówek:

Opcja -d( --differences) podświetli zmiany od poprzedniej wersji danych wyjściowych lub od pierwszej wersji.


9

Kiedy muszę wykryć zmiany w plikach i zrobić coś innego niż to tail -f filename, co robiłem, użyłem inotifywaitskryptu do wykrycia zmiany i działania na jej podstawie. Przykład zastosowania pokazano poniżej. Zobacz man inotifywaitinne nazwy zdarzeń i przełączniki. Może być konieczne zainstalowanie inotify-toolspakietu, na przykład przez sudo apt-get install inotify-tools.

Oto przykładowy skrypt o nazwie 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

W dwóch konsolach wprowadziłem następujące polecenia (gdzie A> oznacza wpis w konsoli A, a B> oznacza wpis w konsoli 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

W cat tkonsoli A pojawiły się następujące dane wyjściowe :

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

Następujące dane wyjściowe exec-on-changepojawiły się w konsoli 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

exec-on-changeSkrypt zakończony kiedy rm„D t.


8

lessma tryb śledzenia podobny do tail -f- wystarczy nacisnąć, Fgdy jest otwarty.


4

Mam trzy rozwiązania:

1) tail -f to dobry pomysł

2) musimy również tailfskorzystać

3) trzeci to skrypt bashowy:

#!/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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.