Perl Probleme mit seek und tell
Hallo,
Eine (hoffentlich) kleine Frage an die Perl-Experten hier:
folgendes kleines Stück perl-code:
--- cut here ---
#!/usr/bin/perl
$pos=123456;
open IN, "
Hallo. 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.
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. Und nur um seek() einen Fehler produzieren zu lassen gibt es auch andere Möglichkeiten, z.B. könntest Du eine pipe oder /dev/null benutzen mit seek(), das dürfte m.E. nicht funktionieren. Arno
Andreas
PS: System ist einmal ein SuSE 9.2 mit perl-5.8.5. Es geht aber genauso wenig auf einer SUN mit perl 5.005.
-- IT-Service Lehmann al@its-lehmann.de Arno Lehmann http://www.its-lehmann.de
On Friday 18 March 2005 12:31, Kyek, Andreas, VF-DE wrote:
Hallo,
Eine (hoffentlich) kleine Frage an die Perl-Experten hier:
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? 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).
Das hat mit Perl nichts zu tun, das ist UNIX! Du kannst durchaus auf eine Position seek()en, die größer als das File ist. Wenn Du dann dort schreibst, erzeugst Du ein Lock im File. Hier ein Beispiel: Zuerst mache ich ein kleines Filesystem: r2@opi:~> dd if=/dev/zero of=fs bs=4k count=10000 10000+0 records in 10000+0 records out r2@opi:~> /sbin/mke2fs fs mke2fs 1.35 (28-Feb-2004) fs is not a block special device. Proceed anyway? (y,n) y Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 10000 inodes, 40000 blocks 2000 blocks (5.00%) reserved for the super user First data block=1 5 block groups 8192 blocks per group, 8192 fragments per group 2000 inodes per group Superblock backups stored on blocks: 8193, 24577 Writing inode tables: done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 25 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. und mounte es: r2@opi:~> sudo mount -oloop fs /mnt r2@opi:~> cd /mnt r2@opi:/mnt> ls -l total 12 drwx------ 2 root root 12288 2005-03-18 13:00 lost+found hier kommt der große Trick: r2@opi:/mnt> dd if=/dev/zero of=file seek=10000000 count=1 bs=1k 1+0 records in 1+0 records out und wir haben in einem Filesystem, das knapp 40MB groß ist, ein File von 9.6GB, jedenfalls laut ls: r2@opi:/mnt> ls -lh file -rw-r--r-- 1 r2 users 9.6G 2005-03-18 13:01 file du ist anderer Meinung: r2@opi:/mnt> du -h file 4.0K file und nach df sind auch wirklich nur 17KB belegt: r2@opi:/mnt> df . Filesystem 1K-blocks Used Available Use% Mounted on /home/r2/fs 38733 17 36716 1% /mnt von denen sich 4KB auflösen, wenn das Riesenfile gelöscht wird: r2@opi:/mnt> rm file r2@opi:/mnt> df . Filesystem 1K-blocks Used Available Use% Mounted on /home/r2/fs 38733 13 36720 1% /mnt Ungefähr klar, was passiert? Torsten
On Fri, Mar 18, 2005 at 12:31:28PM +0100, Kyek, Andreas, VF-DE wrote:
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, der seek ist gelungen, das perl seek macht auch nichts anderes als ein lseek(3): The lseek() system call allows the file offset to be set beyond the end of the existing end-of-file of the file. If data is later written at this point, subsequent reads of the data in the gap return bytes of zeros (until data is actually written into the gap). Hier sind die moeglichen Fehler die auftreten koennen: [EBADF] The fildes argument is not an open file descriptor. [EINVAL] The whence argument is not a proper value or the resulting file offset would be negative for a non- character special file. [EOVERFLOW] The resulting file offset would be a value which can- not be represented correctly in an object of type off_t. [ESPIPE] The fildes argument is associated with a pipe, socket, or FIFO. /GM
participants (4)
-
Arno Lehmann
-
Gerhard Meier
-
Kyek, Andreas, VF-DE
-
Torsten Foertsch