【问题标题】:How can I redirect the output from one filehandle into another?如何将输出从一个文件句柄重定向到另一个文件句柄?
【发布时间】:2009-03-06 14:03:52
【问题描述】:

我想从 Perl(在 Linux 上运行)中建立一个进程管道,由两个部分组成,在不同的时间运行。

例如:

启动消费者进程:

open( OUT, "| tar xvf - " ) || die "Failed: tar: $!";

然后很久以后开始生产者进程:

open( IN, "gpg -d $file |" ) || die "Failed: gpg: $!";

然后以某种方式将 gpg 的输出重定向到 tar 的输入。

我可以通过建立一个循环来做到这一点:

while (<IN> ) {
  print OUT;
}

但我想知道是否可以通过重定向将这两个进程粘合在一起。

【问题讨论】:

  • 为什么不用 'or' 而不是 '||'? 'or' 的优先级低于任何其他运算符,因此如果您在函数中省略括号,则 'or' 的工作方式相同,而 '||'将开始覆盖函数的参数,这很少是你想要的。另外,它看起来更好(对我来说)。

标签: perl redirect filehandle


【解决方案1】:

添加

pipe( IN, OUT );

在两个 open 语句之前。就是这样!

如果你想做更复杂的事情,我会推荐 IPC::Run CPAN 模块:

http://search.cpan.org/dist/IPC-Run/

它允许您启动进程,将它们的输入和输出绑定在一起,并在链中的任何点添加日志记录或重定向。

【讨论】:

  • 这对于一个小测试脚本来说效果很好。谢谢。 #! /usr/bin/perl -w 管道(输入,输出)|| die "失败:管道:$!";打开(输出,“|猫-n”)|| die "失败: cat: $!\n";打开(在,“netstat -n |”)|| die "失败:netstat: $!";逼近 );关闭(OUT);
  • 我以前使用管道进行分叉进程的父/子通信,但从来没有这样。它似乎对我不起作用(solaris 上的 perl 5.8)。我认为 open() 正在关闭/断开 IN/OUT 句柄之间的管道。
【解决方案2】:

如果两个进程完全不相关,则使用 FIFO。

use POSIX qw(mkfifo);
mkfifo($path, 0700) or die "mkfifo $path failed: $!";

这会在 $path 处创建一个 FIFO。现在让一个进程写入该文件,另一个进程从中读取。

【讨论】:

    【解决方案3】:

    我喜欢Proc::SafeExec,它可以让您以几乎任意的方式轻松地将进程和文件句柄联系在一起。这是一个例子:

    use strict;
    use warnings;
    
    use Proc::SafeExec;
    
    open(my $ls, "-|", "ls", "-l") or die "Err: $!";
    open(my $fh, ">", "tmp.txt") or die "Err: $!";
    
    my $p = Proc::SafeExec->new({
      exec => [qw(sed -e s/a/b/)],
      stdin => $ls,
      stdout => $fh,
    });
    $p->wait();
    

    查看 IPC::Run 后,它看起来简单了很多...这是使用 IPC::Run 代替的相同示例:

    use IPC::Run qw(run);
    
    run [qw(ls -l)], "|", [qw(sed -e s/a/b/)], ">", "tmp.txt";
    

    【讨论】:

    • 这些模块看起来很有趣。下周我会调查这些。谢谢。
    • 是的,在我发现 IPC::Run 之前,我花了太多时间手动处理输入/输出重定向、fork/exec、信号处理和 PID 监控。 (在较小程度上,Proc::Simple)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多