2013-02-15 58 views
0

的叉子,我知道我能做到以下幾點:管道文件句柄自我

open(STDOUT, "|-", "cmd"); 

這大概結果如下:

  1. fork();
  2. exec("cmd");
  3. 鏈接原工藝STDOUT以STDIN的新工藝。

我想要做的是上面的第2步,即不要做exec()。只需要將當前過程的兩個副本繼續進行,即將孩子的STDIN鏈接到父母的STDOUT。

那麼這將讓我繼續像這樣:

if (! $pid) 
{ 
    # Handle data in child here 
    open OUTFILE1 $file1; 
    open OUTFILE2 $file2; 
    my $i = 0; 
    while (<>) 
    { 
    print (i % 2 ? OUTFILE1 : OUTFILE2) "Line $i: $_"; 
    ++$i; 
    } 
    exit; 
} 
else 
{ 
    # Continue parent here 
    print STDOUT "Hello World from print()"; 
    system("echo Hello World from system()"); 
} 

上面的代碼應該由線到不同的文件(我知道或者行添加行號的輸出和寫這個數據這是一個有點愚蠢的,但它只是一個例子)。

有沒有一種方法或庫這樣做?我認爲perltie,但它似乎並沒有處理來自system()的結果,因此我相信我需要一個單獨的進程來實際管道STDOUT。

+0

我已經編輯了希望使其更清晰的問題。 – Clinton 2013-02-15 07:56:45

回答

3

IIRC,你只是想

open(STDOUT, "|-", "-"); 

open3也只需要一條線,具有更好的錯誤報告,並允許您捕獲STDERR爲好。

use IPC::Open3 qw(open3); 
use POSIX  qw(_exit); 

sub child { 
    print("Hello World from print()\n"); 
    system("echo", "Hello World from system()"); 
} 

my $pid = open3(
    '<&STDIN', 
    \local *CHILD_STDOUT, 
    '>&STDERR', 
    '-', 
); 

if (!$pid) { 
    if (eval { child(); 1 }) { 
     _exit(0); 
    } else { 
     print(STDERR [email protected]); 
     _exit($! || ($? >> 8) || 255); 
    } 
} 

while (<CHILD_STDOUT>) { 
    ... 
} 

waitpid($pid, 0); 
+0

正是我想要的。沒有命令參數,沒有想到「open」。 – Clinton 2013-02-15 08:03:27

+1

它有一個命令參數「-'。 – ikegami 2013-02-15 08:14:30