Re: Perl Probleme mit seek und tell
Arno Lehmann wrote:
Kyek, Andreas, VF-DE wrote:
Hallo,
Eine (hoffentlich) kleine Frage an die Perl-Experten hier:
Bin zwar kein Experte, aber...
folgendes kleines Stück perl-code:
--- cut here --- #!/usr/bin/perl
$pos=123456; open IN, "
Ergebnis:
--- cut here --- seek-Result=1 Aktpos=123456 seek-Result END=1 Aktpos=16308 -- cut here ---
Was geht hier vor? nach meiner Doku soll seek bei nicht gelingen ein RC=0 zurückgeben. Das File ist genau 16308 Bytes lang; ein seek auf Position 123456 dürfte doch gar nicht gehen, oder?
Doch. Schreib' dann mal in Datei und schau' Dir nachher die Datei an.
Habe ich gemacht und mit folgendem code in eine 907 Byte grosse Datei geschrieben: #!/usr/bin/perl open OUT, ">>./xx.asc" or die; seek OUT, 2048, 0; $pos=tell OUT; print OUT "Auf pos. 2048\n"; $npos=tell OUT; close OUT; print "pos=$pos, npos=$npos\n"; Ergebnis: pos=2048, npos=921 Und das Ergebnisfile ist auch nur 921 Bytes gross! Ergebnis: Der tell nach dem seek lügt!
Wie kann man prüfen, ob ein seek funktioniert hat? Der RC scheint immer 1 zu sein und die Position mittels tell zu prüfen funktioniert auch nicht (wie man sieht).
Doch, funktioniert eigentlich wie geplant. Um das Ende einer Datei zu suchen gibt es ja die Möglichkeit von hinten zu suchen.
Weiss ich, ich brauche ja eigentlich auch was anderes: Ich überwache alle 10 Minuten n-Files, die sehr gross werden können. Um nun nicht jedesmal durch das ganze File laufen zu müssen, merke ich mir die letzten Lese- positionen. Leider wird "gegen Mitternacht" das File ins Archiv verschoben und ein neues File mit _gleichem_ Namen aufgemacht. Die erste Idee war daher, den seek auf die alte letzte Position zu versuchen und (im Fehlerfall, das das File ja nun kleiner ist) von einem neuen File auszugehen und von vorne zu lesen. Das funktionierte aber nicht (s.o.) (mittlerweile mache ich ein "seek, 0,2" und ein "tell IN" und vergleiche das ermittelte Fileende mit der letzten bekannte Position. Aber der Grund für dieses seek Verhalten ist mir trotzdem unklar) Andreas
Hallo, Kyek, Andreas, VF-DE wrote:
#!/usr/bin/perl open OUT, ">>./xx.asc" or die; seek OUT, 2048, 0; $pos=tell OUT; print OUT "Auf pos. 2048\n"; $npos=tell OUT; close OUT; print "pos=$pos, npos=$npos\n";
Ergebnis: pos=2048, npos=921
Und das Ergebnisfile ist auch nur 921 Bytes gross!
Laut ls, oder wie? Mal cat oder od probiert?
Ergebnis: Der tell nach dem seek lügt!
Bezweifle ich immernoch.
Weiss ich, ich brauche ja eigentlich auch was anderes:
Ich überwache alle 10 Minuten n-Files, die sehr gross werden können. Um nun nicht jedesmal durch das ganze File laufen zu müssen, merke ich mir die letzten Lese- positionen. Leider wird "gegen Mitternacht" das File ins Archiv verschoben und ein neues File mit _gleichem_ Namen aufgemacht. Die erste Idee war daher, den seek auf die alte letzte Position zu versuchen und (im Fehlerfall, das das File ja nun kleiner ist) von einem neuen File auszugehen und von vorne zu lesen. Das funktionierte aber nicht (s.o.)
(mittlerweile mache ich ein "seek, 0,2" und ein "tell IN" und vergleiche das ermittelte Fileende mit der letzten bekannte Position. Aber der Grund für dieses seek Verhalten ist mir trotzdem unklar)
Der wurde ja schon erklärt. Wie wär's die inode-Nummer zu vergleichen? Eben nicht seek() zu nutzen, sondern fstat(), das auch andere hilfreiche Sachen liefert - Gesamtgröße oder ctime scheinen da ggf. interessant. Evtl. ist auch ein Blick in die Quellen von tail interesant - das merkt eine Dateiverkleinerung ja auch. Arno
Andreas
-- IT-Service Lehmann al@its-lehmann.de Arno Lehmann http://www.its-lehmann.de
On Friday 18 March 2005 13:24, Kyek, Andreas, VF-DE wrote:
#!/usr/bin/perl open OUT, ">>./xx.asc" or die; seek OUT, 2048, 0; $pos=tell OUT; print OUT "Auf pos. 2048\n"; $npos=tell OUT; close OUT; print "pos=$pos, npos=$npos\n";
Ergebnis: pos=2048, npos=921
Und das Ergebnisfile ist auch nur 921 Bytes gross!
Ergebnis: Der tell nach dem seek lügt!
Nein. Du öffnest das File mit O_APPEND (>>): O_APPEND The file is opened in append mode. Before each write, the file pointer is positioned at the end of the file, as if with lseek. O_APPEND may lead to corrupted files on NFS file systems if more than one process appends data to a file at once. This is because NFS does not support appending to a file, so the client kernel has to simulate it, which can't be done without a race condition. öffne ich das File ohne O_APPEND, klappt es: r2@opi:~> rm file r2@opi:~> perl -e 'open X,">file" and seek X, 2000,0; print X "x"; close X;' r2@opi:~> ls -l file -rw-r--r-- 1 r2 users 2001 2005-03-18 14:49 file mit O_APPEND ist es nur ein Byte lang: r2@opi:~> rm file r2@opi:~> perl -e 'open X,">>file" and seek X, 2000,0; print X "x"; close X;' r2@opi:~> ls -l file -rw-r--r-- 1 r2 users 1 2005-03-18 14:50 file Torsten
Hallo Andreas, hallo Leute, Am Freitag, 18. März 2005 13:24 schrieb Kyek, Andreas, VF-DE: [...]
Weiss ich, ich brauche ja eigentlich auch was anderes:
Ich überwache alle 10 Minuten n-Files, die sehr gross werden können. Um nun nicht jedesmal durch das ganze File laufen zu müssen, merke ich mir die letzten Lese- positionen. Leider wird "gegen Mitternacht" das File ins Archiv verschoben und ein neues File mit _gleichem_ Namen aufgemacht.
Dein Problem hört sich an, als wärst Du auf der Suche nach "logtail", das im Paket logdigest enthalten ist ;-) Gruß Christian Boltz -- | imicha@kira:~> /etc/init.d/glaskugel start | bash: /etc/init.d/glaskugel: Datei oder Verzeichnis nicht gefunden ist das ein grundsätzliches problem bei SuSE? oder fehlt mir ein RPM? [Michael Meyer in suse-linux]
participants (4)
-
Arno Lehmann
-
Christian Boltz
-
Kyek, Andreas, VF-DE
-
Torsten Foertsch