2014-08-31 4 views
3

Согласно manual синтаксисе IPC::Open3::open3 являетсяСинтаксис команды open3

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

Я смущен относительно первых трех параметров. Эти ссылки на typeglobs?

Я попытался следующие:

  1. my $pid=open3("STDIN", "STDOUT", "STDERR", $cmd);
  2. my $pid=open3(*STDIN, *STDOUT, *STDERR, $cmd);
  3. my $pid=open3(\*STDIN, \*STDOUT, \*STDERR, $cmd);
  4. my $pid=open3('<&STDIN', '>&STDOUT', '>&STDERR', $cmd);

но только номер 4, казалось, работало. Согласно руководству, я думал, что номер 3 также должен работать. Например:

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

Если передать строки '<&STDIN' и '>&STDOUT' то дочерний процесс получает дубликат собственных стандартные входные и выходные ручек вашей программы Perl, и может читать и писать и из них без какого-либо дальнейшего вмешательства.

Это очень разные вещи от указания дескрипторов файлов с использованием ссылок типаglob. CHLD_OUT дескриптор файла в документации является STDOUT для процесса ребенка и позволяет вашей программе Perl для чтения из CHLD_OUT, так что вы можете получить и обработать данные, отправляет. Использование STDOUT здесь не будет работать, потому что это выход дескриптор файла для вашего процесса Perl. Если бы вы действительно захотели, вы могли бы использовать STDIN, но это не позволило бы вам прочитать что-либо, что было первоначально представлено на вашем стандартном входе.

Эквивалентные точки применимы к CHLD_IN, который является ручкой, которую вы print, чтобы отправить данные дочернему процессу. Опять же, вы могли использовать STDOUT здесь, но это лишает вас исходного стандартного выходного канала. В любом случае вам все равно придется изобретать еще один дескриптор файла для CHLD_ERR, потому что вы бы указали , указав, чтобы узнать, что ребенок отправляет на стандартный вывод ошибки, и, конечно, вы не можете читать с STDERR.

Так что лучшее, что вы можете сделать, это заменить

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

с

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

но дескрипторов файлов не являются дорогостоящими, так почему посвятите себя потерять свой стандартный ввод и вывод? Гораздо лучше создать три новых дескриптора файлов и работать со всеми шестью.

+0

Спасибо за приятное объяснение! Думаю, я должен получить концепцию сейчас :) –

Смежные вопросы