Re: Problems with open
by Abigail-II (Bishop) on Jul 24, 2002 at 15:00 UTC
|
It will die if you have 5.6.0 or later.
What is happening is this: the open will open a pipe, fork,
and the child will exec "garbage". On perls older than
5.6.0, open will return the pid - that is, it will return
true if the fork succeeded.
Since 5.6.0, if you pipe open a simple program
(one which doesn't require the shell to resolve special
characters), and said program doesn't exist, the handling
is special cased and the open itself will
fail.
open my $fh => "| garbage *" or die;
will not die, because Perl will fork and exec a shell
(which will succeed), asking the shell to execute
garbage * (which can't be done because
"garbage" doesn't exist).
Abigail | [reply] [d/l] [select] |
|
|
Thanks a lot! So it looks like I need a work around for this. I am using Perl 5.005_02. Any ideas?
-Shannon
| [reply] |
|
|
Well, you could upgrade.... ;-).
If you know the command after the pipe is going to be simple
(just letters, digits and whitespace), you could test whether
the first word exists somewhere in the current path and is
executable. Or peek in the source of a modern perl and see
how's it dealt with and mimic that.
But note that even recent perls only handle cases that don't
involve the shell.
Abigail
| [reply] |
|
|
|
|
|
|
|
|
Re: Problems with open
by kodo (Hermit) on Jul 24, 2002 at 15:08 UTC
|
Uhm I've got perl 5.6.1 here on a win32-box (activestate perl) and it doesn't die when I have:
my $pager = "garbage";
open(FH,"| $pager") || die("Can't fork a $pager: $!");
print FH "Writing to $pager";
close(FH) || die("Can't close FH: $!");
and garbage doesn't exist. Also I get the PID returned but maybe this is a win32-issue.
You could simply do a check before the open, a la:
my $pager = "garbage";
if (-x $pager) {
open(FH,"| $pager") || die("Can't fork a $pager: $!");
print FH "Writing to $pager";
close(FH) || die("Can't close FH: $!");
}
giant | [reply] [d/l] [select] |
|
|
I am using Perl 5.005_02 on a SunOS 5.6 machine. I thought of the -x pager but if the $pager does not contain the full path to whatever pager you are using (like less) then this is not going to work. I was hoping to find a cleaner way of doing this, but sounds like we are on the right track. I know we could always throw in a which, but like I said, I would like to find a cleaner way.
Thanks,
-sk
| [reply] [d/l] [select] |
|
|
I guess if you wanted to check if $garbage is a valid exe before executing it you could do something like the following. I'm not sure what the behavior is on 5.002 with File::Spec - can probably replace that with split(/:/,$ENV{'PATH'});
use File::Spec;
sub valid_exe {
my $exe = shift;
for my $dir ( File::Spec->path() ) {
my $f = File::Spec->catfile($dir,$exe);
if( -e $f && -x $f ) { # it is a valid exe
return 1;
}
}
return 0;
}
Essentially what which will do for you, your call if it is cleaner. | [reply] [d/l] [select] |
Re: Problems with open
by bronto (Priest) on Jul 24, 2002 at 15:51 UTC
|
$ perl test.pl
Can't exec "garbage": No such file or directory at test.pl line 6.
Can't fork a garbage: No such file or directory at test.pl line 6.
I am running perl 5.6.1 on Debian Linux 3.0
Just a small adding to other monks' comments. Like other functions, print has a return value, too. So you shouldn't limit yourself at checking if open succeeds or fails: you should check print also, and take actions when it fails
Just my 2c/Euro --bronto
# Another Perl edition of a song:
# The End, by The Beatles
END {
$you->take($love) eq $you->made($love) ;
}
| [reply] [d/l] [select] |
|
|
This appears to be an issue with Perl pre 5.6. I am running 5.005_2 on SunOS 5.6. With diagnostics on, I get:
Can't exec "garbage": No such file or directory at foo.pl line 8 (#1)
(W) An system(), exec(), or piped open call could not execute the
+named
program for the indicated reason. Typical reasons include: the pe
+rmissions
were wrong on the file, the file wasn't found in $ENV{PATH}, the
executable in question was compiled for another architecture, or t
+he
#! line in a script points to an interpreter that can't be run for
similar reasons. (Or maybe your system doesn't support #! at all.
+)
-sk | [reply] [d/l] |
Re: Problems with open
by cybear (Monk) on Jul 24, 2002 at 14:57 UTC
|
I am thinking that the open might not fail, because it is only opening a link to $pager.
Until you actually try to send something to $pager, open is (may not be) doing anything with $pager
that would cause a failure. | [reply] |
|
|
What do you mean with "opening a link to $pager"?
Abigail
| [reply] |
|
|
The problem is is that the handle is not open when I try to print which tells me the open failed. The $pager (more) is a child of the FH process (which opened a pipe to whatever). If the child $pager failed, shouldn't that be returned and the "open" fail? Like my other question asks, in what case would this fail? The | works fine everytime and so the first chance for failure would come with the opening of $pager, right?
Thanks,
-Shannon
| [reply] |
Re: Problems with open
by simeon2000 (Monk) on Jul 24, 2002 at 14:59 UTC
|
Are you running a UNIX system? Knowing the OS you're coding on would help with the solution. | [reply] |
|
|
Oops. Very sorry about that. Everyone here is in Unix. SunOS 5.6
-sk
| [reply] |