Inconsistent returns from piped open

F

fishfry

#!/usr/bin/perl
use strict;

# 1. The open() call returns false.
my $x = open(XX, "| junk");
print "x = $x\n";

# 2. The open() call returns true.
my $y = open(YY, "| junk > foozle");
print "y = $y\n";


When the above code is run (on a Unix system), $x has a value of 0, and
$y has a nonzero value.

junk is a non-existent executable. It's correct for the open() to fail,
since the process creation failed.

However, adding an output redirect causes open() to return a nonzero
value.

This is causing me a problem, since I need to know if the process
creation failed.

Any explanation for why the second example returns true? And perhaps an
alternate way to do the same thing so I can find out if the process
creation fails?
 
X

xhoster

fishfry said:
#!/usr/bin/perl
use strict;

# 1. The open() call returns false.
my $x = open(XX, "| junk");
print "x = $x\n";

Perl tries to execute junk. It fails.
# 2. The open() call returns true.
my $y = open(YY, "| junk > foozle");
print "y = $y\n";

This contains shell metacharacters, so perl tries to start
up a shell. It succeeds, and returns the pid of the shell it
started. The shell turns around and tries to execute junk, and of
course it fails. But the shell's failure is not perl's failure.
When the above code is run (on a Unix system), $x has a value of 0, and
$y has a nonzero value.

junk is a non-existent executable. It's correct for the open() to fail,
since the process creation failed.

However, adding an output redirect causes open() to return a nonzero
value.

This is causing me a problem, since I need to know if the process
creation failed.

You do know that. It is just that that is not what you really want
to know.
Any explanation for why the second example returns true? And perhaps an
alternate way to do the same thing so I can find out if the process
creation fails?

You will be notified of this problem via a SIGPIPE or by the close of
the piped filehandle failing (plus by the shell's whining on STDERR).
If that isn't sufficient, then I don't know--maybe perldoc perlipc has
something useful to say on the matter.

Xho
 
F

fishfry

Perl tries to execute junk. It fails.


This contains shell metacharacters, so perl tries to start
up a shell. It succeeds, and returns the pid of the shell it
started. The shell turns around and tries to execute junk, and of
course it fails. But the shell's failure is not perl's failure.

Very sensible explanation, thanks. Didn't realize that the output
redirect caused an intervening shell to be created, whereas the first
case didn't. I think I'm going to have to explicitly fork/exec to get
control of the process creation.
 
C

Charles DeRykus

fishfry said:
Very sensible explanation, thanks. Didn't realize that the output
redirect caused an intervening shell to be created, whereas the first
case didn't. I think I'm going to have to explicitly fork/exec to get
control of the process creation.

There are some caveats - perldoc IPC::Open3 - but alternatively you may
be able to use something simpler:

use IPC::Open3;

my $pid = open3( \*W, \*R, \*E ,'./junk > froozle');
die "open fork failed: $!" unless $pid;
die "open error: ",<E> unless eof E;
 
C

Csaba

fishfry said:
#!/usr/bin/perl
use strict;

# 1. The open() call returns false.
my $x = open(XX, "| junk");
print "x = $x\n";

Perl tries to execute junk. It fails.
# 2. The open() call returns true.
my $y = open(YY, "| junk > foozle");
print "y = $y\n";

This contains shell metacharacters, so perl tries to start
up a shell. It succeeds, and returns the pid of the shell it
started. The shell turns around and tries to execute junk, and of
course it fails. But the shell's failure is not perl's failure.
[snip]
Any explanation for why the second example returns true? And perhaps an
alternate way to do the same thing so I can find out if the process
creation fails?

You will be notified of this problem via a SIGPIPE or by the close of
the piped filehandle failing (plus by the shell's whining on STDERR).
If that isn't sufficient, then I don't know--maybe perldoc perlipc has
something useful to say on the matter.

Maybe that you absolutely, positively have to check the return value of
close() when using open() for IPC.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top