[comp.lang.perl] `...` and open

mayer@sono.uucp (Ronald &) (05/25/91)

When attempting to execute unix program from perl, I'm unable to both
    1) Determine if the program was actually executed
and
    2) Get the output from the program into a perl string

As shown below, the only ways I know of getting the output of a unix
program into a perl string, `...` and open(F,'...|'), don't seem to be
able to distinguish between a program with no output which returns
false and a program which doesn't exist.  This is in contrast to
perl's 'system(...)', which returns a different value for nonexistant
programs.

#! /usr/local/bin/perl
### Unix programs: 'true' returns 0; 'false' returns 1; 'undef' doesnt exist.
`true`, print "$?\n";       # 0
`false`, print "$?\n";      # 256
`undef`, print "$?\n";      # 256 (how do I distinguish this from `false`?)

open(F,'true|') || die; <F>; close(F); print "$?\n"; # 0
open(F,'false|')|| die; <F>; close(F); print "$?\n"; # 256
open(F,'undef|')|| die; <F>; close(F); print "$?\n"; # 256, same question...

print system('true'),"\n";  # 0
print system('false'),"\n"; # 256
print system('undef'),"\n"; # 65280 easily distinguishable from system('false')


Does anyone know why? (I kinda assume that '``' and 'open' are using
'sh' or 'csh', which return the same value when executing 'false' as
they do when they execute a nonexistant program.  Is this correct?)

Does anyone know of a workaround?  (Other than parsing `which filename`?)

        Ron Mayer

lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (05/25/91)

In article <MAYER.91May24152103@porky.sono.uucp> mayer@sono.uucp (Ronald &) writes:
: 
: When attempting to execute unix program from perl, I'm unable to both
:     1) Determine if the program was actually executed
: and
:     2) Get the output from the program into a perl string
: 
: As shown below, the only ways I know of getting the output of a unix
: program into a perl string, `...` and open(F,'...|'), don't seem to be
: able to distinguish between a program with no output which returns
: false and a program which doesn't exist.  This is in contrast to
: perl's 'system(...)', which returns a different value for nonexistant
: programs.
: 
: #! /usr/local/bin/perl
: ### Unix programs: 'true' returns 0; 'false' returns 1; 'undef' doesnt exist.
: `true`, print "$?\n";       # 0
: `false`, print "$?\n";      # 256
: `undef`, print "$?\n";      # 256 (how do I distinguish this from `false`?)
: 
: open(F,'true|') || die; <F>; close(F); print "$?\n"; # 0
: open(F,'false|')|| die; <F>; close(F); print "$?\n"; # 256
: open(F,'undef|')|| die; <F>; close(F); print "$?\n"; # 256, same question...
: 
: print system('true'),"\n";  # 0
: print system('false'),"\n"; # 256
: print system('undef'),"\n"; # 65280 easily distinguishable from system('false')
: 
: 
: Does anyone know why? (I kinda assume that '``' and 'open' are using
: 'sh' or 'csh', which return the same value when executing 'false' as
: they do when they execute a nonexistant program.  Is this correct?)

Yes, that's basically correct.  In the case of `undef` and such, where
perl doesn't actually use the shell, it would be possible for it to
return a different value, but I hesitate to be inconsistent with the shell.
It seems ugly that adding a shell metacharacter would change the return
value.  On the other hand, that's the way system() works already...

: Does anyone know of a workaround?  (Other than parsing `which filename`?)

Yes, you can say

    open(IN, "-|") || (exec('undef') || exit 255);

Larry