Ausgabe von Dateiinhalten, während sie sich ändern


47

Ich möchte den Inhalt einer Datei ausgeben, während sie sich ändert. Beispiel foobar:

magic_command foobar

Das aktuelle Terminal sollte den Inhalt der Datei anzeigen und warten, bis, ich weiß nicht, ich ^ C drücke.

Wenn ich dann von einem anderen Terminal aus Folgendes tue:

echo asdf >> foobar

Das erste Terminal sollte die neu hinzugefügte Zeile zusätzlich zum ursprünglichen Dateiinhalt anzeigen (natürlich, da ich nicht ^ C gedrückt habe).

Ich werde dies als Hausaufgabe markieren, da ich Linux erforschen und lernen möchte, aber es ist keine Hausaufgabe, es ist nur eine Kuriosität von mir.


Antworten:


79

Sie können verwenden tail commandmit -f :

tail -f /var/log/syslog 

Es ist eine gute Lösung für Echtzeitshows.


Sie können ein Skript schreiben und Ihre Ausgabe in Ihr Skript umleiten.
— PersianGulf

6
Sie können auch -F(groß f) verwenden, wodurch die Datei erneut geöffnet wird, wenn sie währenddessen entfernt und neu erstellt wird.
— Peterph

19

Wenn Sie eine kurze Datei anzeigen möchten, die auf einen Terminalbildschirm passt, und sich möglicherweise die gesamte Datei ändert, können Sie Folgendes verwenden watch:

watch cat example.txt

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

Some text
another line

Standardmäßig wird die gesamte Datei alle 2 Sekunden angezeigt, einschließlich eines optionalen Headers:

Mit der Option -d( --differences) werden Änderungen gegenüber der vorherigen Version der Ausgabe oder gegenüber der ersten Version hervorgehoben.


9

Wenn ich Dateiänderungen erkennen und etwas anderes als das tun tail -f filenamemuss, habe ich inotifywaitin einem Skript verwendet, um die Änderung zu erkennen und darauf zu reagieren . Ein Anwendungsbeispiel ist unten dargestellt. Siehe man inotifywaitfür andere Ereignisnamen und Schalter. Möglicherweise müssen Sie das inotify-toolsPaket beispielsweise über installieren sudo apt-get install inotify-tools.

Hier ist das Beispielskript mit dem Namen 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

In zwei Konsolen habe ich Befehle wie folgt eingegeben (wobei A> für die Eingabe in Konsole A und B> für die Eingabe in Konsole B steht).

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

Die folgende Ausgabe von wurde cat tin Konsole A angezeigt:

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

Die folgende Ausgabe von wurde exec-on-changein Konsole B angezeigt:

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

Das exec-on-changeSkript beendet , wenn ich rm‚d t.


8

lesshat einen ähnlichen Verfolgungsmodus wie tail -f- drücken FSie einfach, wenn Sie ihn geöffnet haben.


4

Ich habe drei Lösungen:

1) tail -f ist eine gute Idee

2) Wir müssen auch tailfverwenden

3) Das dritte ist ein Bash-Skript:

#!/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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.