Perl FAQ 5.16: Why doesn't open return an error when a pipe open fails?

Perl FAQ 5.16

Why doesn't open return an error when a pipe open fails?

These statements:

    open(TOPIPE, "|bogus_command") || die ...
    open(FROMPIPE, "bogus_command|") || die ...

will not fail just for lack of the bogus_command. They'll only fail if the fork to run them fails, which is seldom the problem.

If you're writing to the TOPIPE, you'll get a SIGPIPE if the child exits prematurely or doesn't run. If you are reading from the FROMPIPE, you need to check the close() to see what happened.

If you want an answer sooner than pipe buffering might otherwise afford you, you can do something like this:

    $kid = open (PIPE, "bogus_command |");   # XXX: check defined($kid)
    (kill 0, $kid) || die "bogus_command failed";

This works fine if bogus_command doesn't have shell metas in it, but if it does, the shell may well not have exited before the kill 0. You could always introduce a delay:

    $kid = open (PIPE, "bogus_command </dev/null |");
    sleep 1;
    (kill 0, $kid) || die "bogus_command failed";

but this is sometimes undesirable, and in any event does not guarantee correct behavior. But it seems slightly better than nothing.

Similar tricks can be played with writable pipes if you don't wish to catch the SIGPIPE.

5.##) How do I capture the exit status from an external program?

Perl provides a builtin variable which holds the status of the last backtick command: $?. Here is exactly what the perlvar page says about

The status returned by the last pipe close, backtick (``) command, or system() operator. Note that this is the status word returned by the wait() system call, so the exit value of the subprocess is actually ($? >> 8). Thus on many systems, $? & 255 gives which signal, if any, the process died from, and whether there was a core dump. (Mnemonic: similar to sh and ksh.)


Other resources at this site: