Open3 command syntax

According to the manual, the syntax IPC::Open3::open3

is

$pid = open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, 'some cmd and args', 'optarg', ...);

      

I am confused about the first three parameters. Are these links to typeglobs?

I tried the following:

  • my $pid=open3("STDIN", "STDOUT", "STDERR", $cmd);

  • my $pid=open3(*STDIN, *STDOUT, *STDERR, $cmd);

  • my $pid=open3(\*STDIN, \*STDOUT, \*STDERR, $cmd);

  • my $pid=open3('<&STDIN', '>&STDOUT', '>&STDERR', $cmd);

but only number 4 seemed to work. According to the manual, I thought number 3 should work as well. For example:

use warnings;
use strict;
use feature qw(say);
use IPC::Open3;

my $cmd="sleep 1; echo This STDOUT; sleep 1; echo 'This is STDERR' 1>&2; sleep 1; echo -n 'Reading STDIN: '; read a";

my $pid=open3('<&STDIN', '>&STDOUT', '>&STDERR', $cmd);
say "Waiting for child..";
wait;
say "Done.";

      

+3


source to share


1 answer


If you pass in strings '<&STDIN'

and '>&STDOUT'

, then the child process gets a duplicate of your own Perl input and output program, and can read and write with and without them. >

These are very different things related to specifying file descriptors using links like glob. The file descriptor CHLD_OUT

in the documentation is STDOUT

for the child process, and it allows your Perl program to read from CHLD_OUT

so that you can receive and process the data being sent. Usage STDOUT

here won't work because this is the output file descriptor for your Perl process. If you really wanted to, you can use it STDIN

, but it will prevent you from reading anything that was originally presented on your standard input.

Equivalent points refer to CHLD_IN

which is the handle that you print

send data to the child process. Again, you can use it STDOUT

here, but that robs you of the original standard output channel. You will still have to invent another file descriptor for anyway CHLD_ERR

, because you will be reading it to see what the child is sending to the standard output of the error, and of course you cannot read from STDERR

.

So, best of all, you can replace



open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, 'command')

      

from

open3(\*STDOUT, \*STDIN, \*CHLD_ERR, 'command')

      

but file descriptors are not costly, so why commit to losing standard input and output? It is much better to create three new file descriptors and work with all six.

+3


source







All Articles