2013-04-17 1 views
2

Я бегу это на Perl 5.16.3 x64 (скомпилированный с VC10) на ОС Windows 7.Почему IPC :: Open3 вызывает cmd.exe вместо запрошенной программы?

Когда я бегу что-то вроде этого:

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); 

Я могу видеть в списке процессов, что фактическое команда вызывается IPC::Open3 является:

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

Который, конечно, создает подпроцесс с реальным вызовом:

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

Из-за этого, я получаю pid, соответствующий cmd.exe, а не файл perl.exe.

В документации ничего не говорится об этом порядке звонков или что-либо относительно другого поведения в Windows. У меня нет окна Linux/Unix, чтобы проверить его, но я уверен, что там не будет ничего подобного (если кто-то может протестировать, пожалуйста, сообщите мне, если я ошибаюсь).

В любом случае, мне интересно, почему это IPC::Open3? Почему он не напрямую вызывает perl в этой команде?

Заранее благодарим за любые комментарии.

ответ

3

Для выполнения команды оболочки требуется оболочка.

Как system, open3 имеет следующее соглашение о вызовах:

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

Следующая не должны ссылаться на оболочку:

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

Великий ответ. Я никогда не думал, что существует реальная разница между этими двумя конвенциями. Благодаря! :-) –

+0

согласен с комментарием @Francisco Zarabozo, отличный ответ! – arkhamvm