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.

Paul
quelle

Antworten:

79

Sie können verwenden tail commandmit -f :

tail -f /var/log/syslog 

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

Persischer Golf
quelle
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.

Volker Siegel
quelle
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.

James Waldby - jwpat7
quelle
8

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

peterph
quelle
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
MLSC
quelle