2014-08-31 36 views
3

的語法按照manualIPC::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程序本身的標準輸入和輸出句柄的副本,並且可以讀取和寫入,並從他們身上沒有任何進一步的干預。

這是從使用typeglob引用指定文件句柄的非常不同的事情。文檔中的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

感謝您的好解釋!我想我現在應該得到這個概念:) – 2014-08-31 13:44:59