【问题标题】:Passing data from child to parent after exec in Perl在 Perl 中执行后将数据从子级传递给父级
【发布时间】:2013-02-28 23:10:29
【问题描述】:

我想在另一个perl程序parent.pl中调用一个perl程序child.pl,并希望将数据从child.pl传递到parent.pl并通过parent.pl打印这些数据。 system("perl child.pl") 可能不起作用,因为在 child.pl 完成之前, parent.pl 不会做任何事情。我读了the online doc of perlipc,似乎pipe() 和fork() 可以满足我的一些需求,但是在exec 之后我找不到将数据从子进程传递给父进程的方法。这是parent.pl的代码:

#!/usr/bin/perl -w

pipe(FROM_CHILD, TO_PARENT);  

$pid = fork();  

if ($pid == 0) {  
    # We're in the child process.  
    close(FROM_CHILD);  
    # Send data to parent.  
    print TO_PARENT "Hello, parent\n"; #  I can pass data to parent before exec
    exec("perl child.pl");             #  But how what should I do after exec, in child.pl?
    exit(0);  # Terminate child.  
} 
elsif (undef $pid) {  
    print "Not defined: means an error.";  
} 
else {  
    # Parent process.  
    close(TO_PARENT);  
    $data = <FROM_CHILD>;  
    print "From child: $data\n";  
    $id = wait();  
    print "Child $id is dead.\n"; 

【问题讨论】:

    标签: perl ipc


    【解决方案1】:

    这可能会有所帮助:

    #!/usr/bin/perl
    open (my $child, "-|","./child.pl") or die("$!");
    while (<$child>) {
      print "P: $_";
    }
    close($child);
    

    打开函数,from perldoc:

    对于三个或更多参数,如果 MODE 是 |- ,则文件名是 解释为输出将通过管道传输到的命令,并且 如果 MODE 是 -| ,文件名被解释为通过管道输出的命令 我们。

    如果你不想接触标准输出,那么你需要孩子的合作,然后你可以使用命名管道:

    parent.pl

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Fcntl;
    use POSIX;
    my $fpath = '.named.pipe';
    
    mkfifo($fpath, 0666) or die "mknod $!";
    system("perl child.pl &");
    sysopen(my $fifo, $fpath, O_RDONLY) or die "sysopen: $!";
    
    while (<$fifo>) {
      print "P: $_";
    }
    close($fifo);
    unlink($fifo);
    

    child.pl

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Fcntl;
    use POSIX;
    
    my $fpath = '.named.pipe';
    sysopen(my $fifo, $fpath, O_WRONLY) or die "sysopen: $!";
    print "screen hello\n";
    print $fifo "parent hello\n";
    close($fifo);
    

    【讨论】:

    • 非常感谢这个答案,但是如果 child.pl 有其他输出到标准输出怎么办?例如,child.pl 有两个功能:print_data_to_screen 到屏幕和print_data_to_parent 到父级。
    • 可以用stderr打印到屏幕吗?
    • 恐怕不,stdout 和 stderr 在 child.pl 中用于不同的目的。我可以将管道传递给 child.pl 并在 child.pl 中使用它吗?我不知道如何实现。
    • 谢谢,这正是我想要的。而且我还找到了 Windows 平台 (Win32::Pipe) 命名管道的替代方案,因为我的代码应该在两个平台上运行。
    猜你喜欢
    • 2018-03-09
    • 2023-03-13
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 2011-09-07
    • 2021-06-29
    • 1970-01-01
    相关资源
    最近更新 更多