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

I'm trying to get myself introduced to Perl using "Beginning Perl" by Simon Cozens (kudos & thanks, Simon). I'm using a recent install from ActiveState (again, thanks). Everything's been fine so far until, in chapter 6, I started futzing with the example inventory.plx. It works fine, but I changed the line

 open(SORT, "| perl sort3.plx") or *SORT = *STDOUT;

to try to open a non-existent file as in

 open(SORT, "| perl foo.plx") or *SORT = *STDOUT;

Instead of assigning the file handle to STDOUT it fails with:

Can't open perl script "foo.plx": No such file or directory

It seems related to the pipe.

Is this to be expected? If so why? What's the recommended workaround?

Replies are listed 'Best First'.
Re: open to pipe fails with exit on Windows
by romandas (Pilgrim) on Oct 07, 2009 at 02:47 UTC

    I believe it is to be expected, because normally you pipe to a command or to an executable. After all, piping is essentially redirecting output going to a filehandle to some executable's STDIN. See perlopentut for more details

    In this case, it's expecting 'foo.plx' to be an executable Perl script. Was the original file (sort3.plx) an existing Perl script?

    If so, I suppose the workaround would be to check whether the command or script you want to pipe to actually exists first. Also, you want to get into the habit of using the three-argument version of open, considering that the two-argument version (used most often in educational texts) has some potential security issues when used with a variable filename.
Re: open to pipe fails with exit on Windows
by jakobi (Pilgrim) on Oct 07, 2009 at 09:35 UTC

    Same thing on Unix as well:

    What happens is this: perl(2) command exists, thus the open succeeds and perl(2) _is_ running. The failure itself from perl(2) (exiting), the invoking perl(1) setting $?, etc, does happen later, i.e. on the first print (*) on that handle.

    The fix of course is doing as romandas suggests.

    (*) make that actual use of the underlying handle. So I don't known what happens in case of empty print SORT "". Also it depends on whether the handle does buffering or directly talks to the other process perl(2). Write a small test case and ask your setup how it will behave :).

    If the invoked command dies after reading a bit, the error will be visible to perl(1) even later (in case of perl(2), it dies _without_ reading from STDIN of course).