tail: Info über Löschung der Datei

P

pygo

Jungspund
Hallo!

Zuerst einmal bin ich mir leider nicht sichter, ob ich hier in die richtige Rubrik poste, aber sie erschien mir doch am sinnvollsten. Vermutlich fehlt es mir am Unix-Verständnis mehr als an der Programmierung selbst.

Zu meinem Problem:
Ich habe ein Perl-Script, das mit tail -f ein logfile ausliest und weiter verarbeitet. Prinzipiell geht das auch schon ganz gut. Allerdings wüde ich jetzt gerne noch mitkriegen, wenn das logfile nicht mehr verfügbar ist. Leider bleibt der tail da aber recht stur und wartet auf die nächste Zeile in der Datei.
Gibt es da irgendeine Möglichkeit für mein Script, das zu wissen? Bisherige Suchen haben mich da nicht weitergebracht, weiss allerdings natürlich nicht, ob ich richtig gesucht habe (wenn man nicht genau weiss, was man sucht, findet man meist nicht die richtigen Worte...)

Herzlichen Danke schon mal!
Pygo
 
evtl mal mit einer if-schleife vorher prüfen?
beispiel:
Code:
if [ -f /tmp/file.txt ]; then
        rm /tmp/file.txt
else
   echo "nix...."
fi
 
Hallo,

Ich hoffe, ich hab Dich jetzt nicht falsch verstanden: Du schlägst mir doch vor, vor dem Löschen der Datei die if-Abfrage durchzuführen?! Leider lösche ich diese Datei nicht. Es ist vielmehr so, dass der Server, der das logfile schreibt sich runterfährt und es deshalb nicht mehr verfügbar ist. Es müsste also schon irgendwas sein, dass ich direkt auf der tail-Seite erfahren kann.

Gruss - Pygo
 
pygo schrieb:
Hallo,

Ich hoffe, ich hab Dich jetzt nicht falsch verstanden: Du schlägst mir doch vor, vor dem Löschen der Datei die if-Abfrage durchzuführen?! Leider lösche ich diese Datei nicht.
ja, hast mich falsch verstanden :D
ich wollte dir damit nur zeigen wie man mit einer if-schleife auf existenz einer datei (in deinem fall logfile) prüfen kann.
du kannst ja das rm durch eben deinen tail befehl ersetzten. aber tail selber funktioniert doch auch gar nicht wenn die ge'tail'te datei gar nix existiert :think:
pygo schrieb:
Es ist vielmehr so, dass der Server, der das logfile schreibt sich runterfährt und es deshalb nicht mehr verfügbar ist. Es müsste also schon irgendwas sein, dass ich direkt auf der tail-Seite erfahren kann.
ist das logfile auf einem anderen server als den wo du den tail aufrufst?
evtl. wäre dein bisheriges skript hier hilfreich um überhaupt den sinn und das ziel zu verstehen was du erreichen möchtest :]
 
pygo schrieb:
Hallo!

Zuerst einmal bin ich mir leider nicht sichter, ob ich hier in die richtige Rubrik poste, aber sie erschien mir doch am sinnvollsten. Vermutlich fehlt es mir am Unix-Verständnis mehr als an der Programmierung selbst.

Zu meinem Problem:
Ich habe ein Perl-Script, das mit tail -f ein logfile ausliest
Wenn es wirklich ein Perlskript ist ( was ich irgendwie nicht so recht glaube ;) ), bist du hier nicht richtig.
Natürlich ist es möglich innerhalb eines Perlskriptes einen systemcall mit tail zu machen, aber in diesem fall wohl eher ungewöhnlich.

pygo schrieb:
und weiter verarbeitet. Prinzipiell geht das auch schon ganz gut. Allerdings wüde ich jetzt gerne noch mitkriegen, wenn das logfile nicht mehr verfügbar ist. Leider bleibt der tail da aber recht stur und wartet auf die nächste Zeile in der Datei.
Gibt es da irgendeine Möglichkeit für mein Script, das zu wissen?
Kann es sein, dass das ein Shellscript ist?
Was genau willst du mit der Information machen, wenn das Skript feststellt, dass die Datei nicht mehr lesbar ist?

Bisherige Suchen haben mich da nicht weitergebracht, weiss allerdings natürlich nicht, ob ich richtig gesucht habe (wenn man nicht genau weiss, was man sucht, findet man meist nicht die richtigen Worte...)

Herzlichen Danke schon mal!
Pygo

Die richtige Formulierung des Problemes ist entscheident für die erfolgreiche Suche nach Lösungen.
Deshalb sollte man sich dafür etwas Zeit nehmen. Oft sieht man das Problem auf den ersten Blick an der falschen Stelle.

Also zu tail:
man tail sagt mir, dass ich für diese Zwecke die Option


--max-unchanged-stats=N
mit --follow=name, DATEI erneut öffnen, wenn sie nach N Iterationen (Voreinst.: 5) unverändert ist, um
zu sehen, ob sie gelöscht oder umbenannt wurde (das ist der Fall bei rotierten Logdateien)...


Mit --follow (-f) verfolgt tail den Datei-Deskriptor. Dies bedeutet, dass auch im Falle einer Umbenennung tail
das Ende verfolgen wird. Dieses Verhalten ist nicht erwünscht, wenn man wirklich den derzeitigen Namen der
Datei verfolgen will und nicht den Datei-Deskriptor (z. B. bei Log-Rotation). Benutzen Sie in diesem Fall
--follow=name. Dies bewirkt, das tail die Datei immer wieder schließt und öffnet, um zu sehen, ob die Datei
gelöscht und von einem anderen Programm neuangelegt wurde.
...



benutzen kann.
also statt -f mal die Option --follow=dateiname verwenden.
Welche Konsequenzen dein Skript daraus ziehen soll, hast du nicht gesagt.

HTH

Gruß Wolfgang
 
Zuletzt bearbeitet:
Hallo damager,

Ups ok, sorry - bin wohl doch noch nicht so wach wie erhofft ;)

Mein Code - hm. Ist leider sehr lang und deshalb hier mal nur der Teil, den ich für relevant halte:
Code:
my $server = $_[0];
$pipe_log->writer();
	
my $logfile = "/cluster/".$server."/log/log_".$server;
open(LOGFILE, "rsh perforce$server -l perforce tail +0f $logfile |") || die("cannot open logfile: $!\n");
	
while(my $actual_line = <LOGFILE>){
	if($actual_line =~ /Perforce server info/){
		next;
	}	

	elsif($actual_line =~ /(\d{4}\/\d{2}\/\d{2}) (\d{2}:\d{2}:\d{2}) pid (\d+) server starting/){
	# und so weiter und so fort...
}

Also ich starte den tail auch, solange die Datei verfügbar ist. Nur möchte ich eben verhindern, dass nach einem Serverneustart mit meinem Lesen nichts mehr passiert. Was im Moment definitiv der Fall ist.
Der Serve ist (wie man jetzt sicher sieht) ein anderer als der, wo mein Script läuft.

Hab auch eben kurz drüber nachgedacht, ob ich in der Schleife die Existenz prüfen kann, wird aber wohl nicht gehen, weil es ja in dem <LOGFILE> hängt...

Gruss - Pygo
 
Die Lösung ist, glaube ich, viel simpler. Einfach mal statt -f den Parameter -F benutzen, der Unterschied ist wie folgt:

Code:
$ tail -f test.test
Test
Test2

Code:
$ tail -F test.test
Test2
Test
tail: auf ,,test.test" kann nicht mehr zugegriffen werden: Datei oder Verzeichnis nicht gefunden

Jeweils nach zwei eingegebenen Zeilen in der Testdatei wurde diese gelöscht. Während tail mit -f davon nichts mitbekommt, gibt tail mit -F die entsprechende Meldung aus, die sich wohl in Scripten weiterverarbeiten lassen sollte.
 
*doing* jetzt verstehe ich es ...
also das löschen den quell-datei _während_ des tail's. dann full ack an usul :]

das sagt aber auch das man tail:
-f, --follow[={name|descriptor}]
output appended data as the file grows; -f, --follow, and --follow=descriptor are equivalent

-F same as --follow=name --retry
 
Zuletzt bearbeitet:
Ja - Frauen können sich manchmal nicht verständlich ausdrücken - bitte um Verzeihung :brav:

Also die Option -F gibt es bei mir nicht. Weder im man noch wenn ich mal einfach verwende (dann sagt er 'invalid option'). Allerdings hab ichs jetzt auch nur lokal auf dem Server mit dem Script getestet - muss es mal für den anderen auch probieren, glaube, der hat ne andere OS-Version...

Aber die genauen Parameter für --follow werde ich mir noch mal genauer zu Gemüte führen. Habs bisher noch nicht so ganz kapiert, was es macht, werds aber mal testen.

Danke für die vielen schnellen Antworten! Ihr seid mit Euren Antworten schneller gewesen als ich antworten kann....

Beste Grüsse,
Pygo
 
usul schrieb:
Die Lösung ist, glaube ich, viel simpler. Einfach mal statt -f den Parameter -F benutzen, der Unterschied ist wie folgt:

Code:
$ tail -f test.test
Test
Test2

Code:
$ tail -F test.test
Test2
Test
tail: auf ,,test.test" kann nicht mehr zugegriffen werden: Datei oder Verzeichnis nicht gefunden



Jeweils nach zwei eingegebenen Zeilen in der Testdatei wurde diese gelöscht. Während tail mit -f davon nichts mitbekommt, gibt tail mit -F die entsprechende Meldung aus, die sich wohl in Scripten weiterverarbeiten lassen sollte.

Hallo
Das ist wie immer eine Frage der Version:
$ tail --version
tail (coreutils) 5.2.1

Fakt ist, dass -f den Dateidescriptor verfolgt, der ja beim Löschen zunächst erhalten bleibt.
--follow=name dagegen den Dateiname (ist wohl das Gleiche wie -F)

Das Perlscript (ist tatsächlich eine solches ;) ) kann aber den Returnwert der Pipe auswerten, nur ist hier auf die Besonderheit zu achten, dass unter perl 0 als false und unter der shell 0 als true gewertet wird.

Gruß Wolfgang
 
Wolfgang_1 schrieb:
Das Perlscript (ist tatsächlich eine solches ;) ) kann aber den Returnwert der Pipe auswerten, nur ist hier auf die Besonderheit zu achten, dass unter perl 0 als false und unter der shell 0 als true gewertet wird.
Ja, wenigstens einmal richtig ausgedrückt, es ist tatsächlich eins *g* Aber hast ja recht, das tail macht eigentlich ja nicht das Perl-Script...
Wie würde das funktionieren, wenn man diesen Returnwert aus der Pipe auswerten will? Ich hab zwar schon mal mit pipes ansich gearbeitet, aber nur zwischen Perl-Scripten und ihren Klonen ;)

Also mein Script-beherbergender Server hat Version 2.0.10 und der log-file-Server weigert sich, diese Aussage zu machen.
Ausserdem dachte ich eben super,
Code:
tail: log_test: No such file or directory
tail: no files remaining
damit wäre ich doch glücklich - leider mag der Server mit dem logfile aber auch das --follow nicht:
Code:
% > rsh perforce3224 -l perforce tail --follow=name /cluster/3224/log/log_3224
usage: tail [+/-[n][lbc][f]] [file]
       tail [+/-[n][l][r|f]] [file]

Ich werde mal weiter testen....
Pygo
 
pygo:
ist das evtl. ein solaris 8 server?
spricht was gegen neue coreutils auf diesen server?
 
damager schrieb:
ist das evtl. ein solaris 8 server?
Tatsächlich habe ich eben (hab den Server immer nur per rsh angesteuert) auch erst festgestellt, dass da in den man-pages was von SunOS 5.9 steht.
Problem ist, dass ich von dem Server 'meine Finger lassen' muss. Ich 'darf' nur die logfiles auslesen. Mit irgendwelchen Updates kann ich das also nicht retten.
 
pygo schrieb:
Tatsächlich habe ich eben (hab den Server immer nur per rsh angesteuert) auch erst festgestellt, dass da in den man-pages was von SunOS 5.9 steht.
Problem ist, dass ich von dem Server 'meine Finger lassen' muss. Ich 'darf' nur die logfiles auslesen. Mit irgendwelchen Updates kann ich das also nicht retten.

schade ... :headup:
 
Hallo
ich kenne leider Solaris überhaupt nicht.
Eventuell kannst du ja mal die Manpage dieser tail -Version posten.
Sonst müsste man die Funktion nachbasteln.

Erstmal grobe Vorstellung, wenn es nicht anders geht:
:think:
Eventuell hilft ja ein fork für diese Pipe. Der Hauptprozess könnte dann die Lesbarkeit der Datei überwachen und gegebenenfalls dem Childprozess ein SIGKILL senden.

Um den Returnwert eines system unter perl auszuwerten, wertest du einfach die Funktion selbst aus.
Oder du verwendest gleich die Kurzform.
also
my @com = ("ls", "-la1");
(system(@com) == 0)?print "Alles ok\n":die "system @com error: $?";
oder
system @com && die "system @com error: $?";

Wichtig, dass es hier eben wie schon gesagt nicht || sondern && ist.

Wenn du die o.g. Optionen des tail mal genauer ansehen könntest,findest du ja eventuell etwas Brauchbares, was die sache vereinfachen würde.

Wenn nicht, muss eben was gebastelt werden.
;)
Gruß Wolfgang

edit:
Ich sehe gerade, noch Folgendes:
Warum nimmst du nicht dein locales tail und verwendest ssh?
Das rsh ist ohnehin alles Andere als optimal!
 
Zuletzt bearbeitet:
Wolfgang_1 schrieb:
Hallo
ich kenne leider Solaris überhaupt nicht.
Eventuell kannst du ja mal die Manpage dieser tail -Version posten.

siehe anlage ...
 

Anhänge

  • tail_solaris8.txt
    4,6 KB · Aufrufe: 2
Da war wohl wieder einer schneller :) Und da meine tail-man das selbe Datum aufweist, wirds wohl das gleiche sein.

Das mit dem local und ssh hab ich deshalb nicht gemacht, weil ich das mit dem rsh von meinem Kollegen übernommen habe und ehrlichgesagt in die Richtung auch keinen Schimmer habe *schäm* Ich werd gleich mal einen Blick drauf werfen ;)

Das mit dem Testen - in welcher Art auch immer - könnte natürlich was werden. Ich krieg ja sogar mit, wann der Server das Signal zum shutdown kriegt. Leider dauerts nur dann noch max ne halbe Stunde, bis er das wirklich tut.
 
Zurück
Oben