Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No output from IPC::Open3

Tags:

perl

When I execute the following synopsis for IPC::Open3:

# send STDOUT and STDERR to already open handle
open my $outfile, '>>', 'output.txt' or die "open failed: $!";
my $pid = open3('<&STDIN', $outfile, undef, 'ls');
waitpid($pid, 0);

Why is there no output in "output.txt"?

like image 507
mvanle Avatar asked Nov 07 '25 06:11

mvanle


1 Answers

The behavior of IPC::Open3 (And IPC::Open2) when given an open file handle as one of the in or out arguments is poorly described in the documentation. When you pass just the filehandle as chld_out or chld_err, whatever is currently open on it is closed, and it's reused as the read end of a pipe (With the write end connected to the executed process's standard output or standard error). The opposite ends are naturally used for the chld_in argument.

A demonstration:

#!/usr/bin/env perl
use v5.36;
use IPC::Open3;

# send STDOUT and STDERR to already open handle
open my $outfile, '>>', 'output.txt' or die "open failed: $!";
say '$outfile is a file handle' if -f $outfile;
my $pid = open3('<&STDIN', $outfile, undef, 'ls');
if (-f $outfile) {
    say '$outfile is still a file';
} elsif (-p _) {
    say '$outfile is now a pipe handle';
}
say scalar <$outfile>; # First file in directory
waitpid $pid, 0;

produces the output:

$outfile is a file handle
$outfile is now a pipe handle
a file name

If you use the >&HANDLE version of the output argument, passing the underlying file descriptor of the handle as HANDLE, it instead uses that as the executed process's standard output:

my $pid = open3('<&STDIN', sprintf(">&%d", fileno $outfile), undef, 'ls')

will fill your output.txt with the output of running ls as desired.

like image 63
Shawn Avatar answered Nov 09 '25 10:11

Shawn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!