in reply to Undestanding this code snippet

Perl supports opening a pipe to or from a shell command, that's what the open call seems to try to accomplish. But for that, a pipe sign must be prepended (in case of writing to) or appended (in case of reading from) to the shell expression, like so:

open F, "| some_shell_expression"; # open for writing open F, "some_shell_expression |"; # open for reading

See open for details. Your open as written won't work, since you don't specify the open mode (read or write). The command itself as posted by you features a useless use of cat since it is better written as

/usr/bin/mycommand < file

The next line saves the input record separator (see perlvar), sets it to the empty string enabling "slurp mode" on the filehandle F; next all that can be read from F is read and then passed to eval to be executed. For that to work,

  1. something must be read from the filehandle F and
  2. the stuff read must be valid perl code.
See eval for details.

I suspect that there's nothing read from F, and evaling an empty string doesn't result in an error stored in $@.

If you just want to run a command and check it for errors, use system. If system returns something different than 0 (zero), something went wrong. Then exploit $? (see perlvar), along the lines

my $cmd = "/usr/bin/mycommand < file"; if ( system $cmd ) { warn $cmd . ($? == -1) ? " failed to execute: $!\n" : ($? & 127) ? sprintf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without' : sprintf "child exited with value %d\n", $? >> 8; }

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: Undestanding this code snippet
by Anonymous Monk on Jul 21, 2008 at 16:37 UTC

    Thanks everyone for replying, you are right, there is a "|" as the file handle is opened...apologize that I missed that when I modified the command before posting :( (open F, "some_shell_expression |";)

    With that said, is there still a way for catching that system error with the current code?
    Thanks again!

      Yes - see IPC::Open3. That module provides capturing STDERR of a command. The exit status is available after reaping the child with waitpid. Example (untested):

      my $pid = open3('<&STDIN', \*CHLD_OUT, \*CHLD_ERR, "some_shell_express +ion"); while(<CHLD_OUT>) { # do something with that command's output } my $err = <CHLD_ERR>; # may block - better use select here waitpid $pid, 0; if ( $? ) { warn $_[0] . ($? == -1) ? "failed to execute: $!\n" : ($? & 127) ? sprintf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without' : sprintf "child exited with value %d\n", $? >> 8; }

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}