nysus has asked for the wisdom of the Perl Monks concerning the following question:

I'm really struggling with this pipe business. I've never dealt with them for and I need some mercy. In the following bit:
#!/usr/bin/perl use strict; open (PIPE,"| perl non-existant_file") or die "Can't open pipe: $!"; print "hello"; sleep 5; print "goodbye";
Why the heck doesn't the program die? The error prints but the program plows on and prints 'hello', sleeps, and the prints 'goodbye'. Thanks again, again, and again.

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop";
$nysus = $PM . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: More pipe problems
by arturo (Vicar) on Jul 18, 2001 at 22:55 UTC

    And lo, the aspirant was directed to the holy documentation of the camel, in the perldoc of perlipc, wherein it is written:

    Be careful to check both the open() and the close() return values. If +you're writing to a pipe, you should also trap SIGPIPE. Otherwise, th +ink of what happens when you start up a pipe to a command that doesn' +t exist: the open() will in all likelihood succeed (it only reflects +the fork()'s success), but then your output will fail--spectacularly. + Perl can't know whether the command worked because your command is a +ctually running in a separate process whose exec() might have failed.

    and also therein is described the fix, but that is left for the aspirant who now knows where to look to find the wisdom he seeks.

    (HTH!)

      I get the hint. :-) I'll try slogging my way through perlipc. I'll admit I looked at it ever so briefly but its big hairy title scared me away.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop";
      $nysus = $PM . $MCF;
      Click here if you love Perl Monks

Re: More pipe problems
by Cubes (Pilgrim) on Jul 18, 2001 at 22:49 UTC
    The open only fails if your process can't fork at all. As noted already, the return from close will give you the exit status of the child process. You may also get a SIGPIPE if you try to write to a pipe whose other end has gone away.

    Update: See the section on Pipes in chapter 6 of the camel for more information; reading up on the specifics of pipes on your OS might also provide enlightenment (they are strange beasts, and can cause all sorts of oddball errors if handled improperly).

Re: More pipe problems
by spudzeppelin (Pilgrim) on Jul 19, 2001 at 00:00 UTC

    Actually, the explanation behind this one is even simpler. You're opening a pipe to perl, with "non-existant_file" called as an argument. That pipe will succeed; perl will be opened, and subsequently exit, but the point is that the "open" call itself was successful -- you were able to open a handle to a perl process.

    The cheap and easy way around this is to make sure that whatever you intend to open on a pipe is executable and has the shebang at the top, and omit the perl. e.g.:

    #!/usr/bin/perl use strict; open (PIPE,"|non-existant_file") or die "Can't open pipe: $!"; print "hello"; sleep 5; print "goodbye";

    This way, when non-existant_file fails to execute, the open call fails, and you should die the way you intended.

    As an aside, it doesn't even have to be perl inside the pipe for this to be a factor. This could just as easily have been a pipe to awk or gzip or foobarbazwhee with incorrect arguments -- as long as the right-hand side of the pipe is, in fact, invoked, open doesn't fail.

    Spud Zeppelin * spud@spudzeppelin.com

Re: More pipe problems
by rucker (Scribe) on Jul 18, 2001 at 22:46 UTC
    Check for errors on the close.
Re: More pipe problems
by petral (Curate) on Jul 19, 2001 at 08:13 UTC
       Why the heck doesn't the program die? The error prints but the program plows on

    You've gotten answers to solve your problem, but your statement puzzled me.  Actually, the error doesn't print:

    "Can't open perl script "non-existant_file": No such file or directory"

    Is a completely different error (notice yours mentions "pipe") which is, of course, the message coming from the *successfully* forked perl (see spudzeppelin just above).  It appears where you expect to see your error because, as all the docs say, the forked program inherits STDOUT from its parent. (Don't worry, this will be confusing no matter how long you live with it.)

      p