2

I'm trying to use seek to "rewind" to the beginning of a file using the following code:

#! /usr/bin/perl

use strict;
use warnings;

my $infile = $ARGV[0];
open (FH, "<$infile");

while(<FH>) {
    chomp;
    print $_,"\n";
}

print "one time","\n";

seek FH, 0, 0;

while(<FH>) {
    chomp;
    print $_,"\n";
}

My input file looks like this:

A   A   A   A   A   A   A 
B   B   B   B   B   B   B

I run my program with the following command:

cat file | perl script.pl /dev/stdin

But instead of getting my expected output:

A   A   A   A   A   A   A 
B   B   B   B   B   B   B
one time
A   A   A   A   A   A   A 
B   B   B   B   B   B   B

I get:

A   A   A   A   A   A   A 
B   B   B   B   B   B   B
one time

Why?

ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
EpiMan
  • 839
  • 3
  • 11
  • 26
  • @toolic I did, but the same as previous ;( – EpiMan Nov 03 '14 at 18:46
  • according to http://stackoverflow.com/questions/12043592/perl-re-reading-from-already-read-filehandle – EpiMan Nov 03 '14 at 18:54
  • I comment both local::lib and use Fcntl; out but it is strange that I can not get the expected output!!! – EpiMan Nov 03 '14 at 18:55
  • 1
    Try checking `seek`'s return value. It should return 1 on success, false otherwise. – ThisSuitIsBlackNot Nov 03 '14 at 18:58
  • I removed all but I do not know why still does not work! updated above script! – EpiMan Nov 03 '14 at 18:59
  • I got it; I use " cat file | perl script.pl /dev/stdin" then I get half of the expected output, but I put the file "perl script.pl file" now work, do you know why? – EpiMan Nov 03 '14 at 19:14
  • 2
    Pipes are not seekable? – mpapec Nov 03 '14 at 19:18
  • `perl -we 'open my $fh, "<", "/dev/stdin" or die $!; seek $fh, 0, 0 or die $!;` gives `Illegal seek at -e line 1.` – ThisSuitIsBlackNot Nov 03 '14 at 19:18
  • Perl can read from a file passed as an argument, so you should never need to do `cat file | perl script.pl /dev/stdin` instead of `perl script.pl file` – ThisSuitIsBlackNot Nov 03 '14 at 19:37
  • 1
    It does work if `/dev/stdin` refers to a file rather than a pipe: `perl script.pl /dev/stdin < /etc/motd`. To see errors, change your `seek` line to `seek FH, 0, 0 or die "seek: $!\n";` – Keith Thompson Nov 03 '14 at 19:56
  • Why are you invoking the script using `perl script.pl`. The whole point of the `#!` line is that you don't have to invoke `perl` explicitly; you can just execute the script: `./script.pl` – Keith Thompson Nov 03 '14 at 19:57

1 Answers1

3

Pipes are not seek-able,

seq 5 | perl -Mautodie -pe 'seek ARGV,0,0 if eof'

gives Can't seek('ARGV', '0', '0'): Illegal seek at -e line 1, but in case of file it works as expected.

mpapec
  • 50,217
  • 8
  • 67
  • 127