2013-08-18 42 views
9

Tôi đang cố gắng để có STDOUT/STDERR từ một tiến trình con thực hiện quay trở lại với cha mẹ thông qua một đường ống trong Perl. Gần nhất tôi đã thấy những gì tôi muốn làm là tại: http://forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.htmlchuyển hướng stdin/stdout từ quá trình exec'ed đến đường ống trong Perl

Sau đây là một ví dụ rút gọn về những gì tôi đang cố gắng làm. Tôi cũng đã thử một biến thể của liên kết ở trên. Tôi không thể thấy những gì tôi đang làm sai ...

#!/usr/bin/env perl 

use strict ; 
use warnings ; 

my $cmd = "/usr/bin/who -a" ; # anything to stdout 

pipe(READER, WRITER) ; 
my $child = fork() ; 
if ($child) { 
    print "I am the parent: My pid = $$ junior = $child\n" ; 
    close(WRITER) ; 
    my @output = <READER> ; 
    print @output ; 
    print "parent is DONE\n" ; 
} else { 
    print "I am the child. My pid = $$\n" ; 

    close(READER) ; 
    close(STDOUT); 
    close(STDERR); 
    *STDOUT = *WRITER ; 
    *STDERR = *WRITER ; 

    print WRITER "XXX ouput before exec....\n" ; 

    exec($cmd) or exit(1) ; 
} 
+2

Bạn có thể quan tâm đến [IPC :: Open2] (http://perldoc.perl.org/IPC/Open2.html). – squiguy

Trả lời

5

Không thể chuyển hướng mô tả tệp chỉ bằng các bài tập. Thay vào đó, một nhu cầu sử dụng open như được mô tả trong perldoc -f open. Trong trường hợp của bạn, mã con sẽ trông giống như sau:

print "I am the child. My pid = $$\n" ; 

    close(READER) ; 

    open STDOUT, ">&", \*WRITER or die $!; 
    open STDERR, ">&", \*WRITER or die $!; 

    print WRITER "XXX ouput before exec....\n" ; 

    exec($cmd) or exit(1) ; 
4

Slaven Rezic có câu trả lời đúng vì sao mã của bạn không hoạt động, nhưng bạn cũng nên biết một phím tắt mà bạn có thể sử dụng. Các ống đặc biệt + ngã ba open READER, '-|' gần như tất cả các công việc thiết lập cho bạn, tạo ra một quá trình con với STDOUT của nó viết vào một đường ống mà cha mẹ có thể đọc với READER. Điều đó chỉ rời khỏi chuyển hướng STDERR để bạn thực hiện thủ công.

Phiên bản rút gọn của mã trông như thế này:

my $child = open READER, '-|'; 
defined $child or die "pipe/fork: $!\n"; 
if ($child) { 
    print "I am the parent: My pid = $$ junior = $child\n" ; 
    my @output = <READER> ; 
    print @output ; 
    print "parent is DONE\n" ; 
} else { 
    print "I am the child. My pid = $$\n" ; 

    open STDERR, '>&STDOUT'; 

    print "XXX ouput before exec....\n" ; 

    exec($cmd) or exit(1) ; 
} 
0

Mã này là một cách khác để ống các stdout và stderr từ quá trình đứa trẻ.

#!/usr/bin/env perl 
use strict ; 
use warnings; 

my $cmd = "/usr/bin/who -a" ; # anything to stdout 

pipe(READER, WRITER) ; 
my $child = fork() ; 
if ($child) { 
    print "I am the parent: My pid = $$ junior = $child\n" ; 
    close(WRITER) ; 
    my @output = <READER> ; 
    print @output ; 
    print "parent is DONE\n" ; 
} else { 
    print "I am the child. My pid = $$\n" ; 
    close(READER) ; 
    open(STDERR,">&", WRITER) or die "Cannot duplicate STDERR; 
    open(STDOUT,">&", WRITER) or die "cannot duplicate STDOUT"; 

    print WRITER "XXX ouput before exec....\n" ; 

    exec($cmd) or exit(1) ; 

}

Các vấn đề liên quan