perlipcopen3

Why is IPC::Open3 calling cmd.exe instead of the requested program?


I'm running this on Perl 5.16.3 x64 (compiled with VC10) on Windows 7.

When I run something like this:

use strict;
use warnings;
use IPC::Open3;
use Symbol 'gensym';

my $command = q[perl -e "$| = 1; for (1..60) { print '.'; sleep 1 }"];

my ($in, $out, $err);
$out = gensym;
$err = gensym;

my $pid = open3($in, $out, $err, $command);

I can see in the process list that the actual command called by IPC::Open3 is:

cmd.exe /x/d/c perl -e "$| = 1; for (1..60) { print '.'; sleep 1 }"

Which, of course, creates a sub process with the actual call:

perl -e "$| = 1; for (1..60) { print '.'; sleep 1 }"

Because of this, I'm getting the pid corresponding to cmd.exe and not the one for perl.exe.

The documentation doesn't mention anything about this order of calls or anything regarding a different behavior on Windows. I don't have a Linux/Unix box here to test it, but I bet it doesn't do something like that there (if someone can test, please let me know if I'm wrong).

Anyway, I'm wondering why is IPC::Open3 doing this? Why isn't it directly calling perl in that command?

Thanks in advance for any comments.


Solution

  • To execute a shell command, you need a shell.

    Like system, open3 has the following calling convention:

    open3(..., ..., ..., $SHELL_COMMAND)
    open3(..., ..., ..., $PROG, @ONE_OR_MORE_ARGS)
    

    The following shouldn't invoke a shell:

    my @command = ('perl', '-e', '$| = 1; for (1..60) { print q{.}; sleep 1 }');
    my $pid = open3($in, $out, $err, @command);