是否可以打开一个基于管道的文件句柄,将其打印到perl中的变量?

是否可以打开一个基于管道的文件句柄,将其打印到perl中的变量?,perl,file-io,Perl,File Io,我知道我能做到 ------ open(F,">",\$var); print F "something cool"; close(F); print $var; ------ 或者这个, open(F, "| ./prog1 | ./prog2 > tmp.file"); print F "something cool"; close(F); 但有可能把这些结合起来吗?我想做的事情的语义应该从以下内容中明确 open(F,"|./prog1 | ./prog2", \$var); p

我知道我能做到


------
open(F,">",\$var);
print F "something cool";
close(F);
print $var;
------
或者这个,


open(F, "| ./prog1 | ./prog2 > tmp.file");
print F "something cool";
close(F);
但有可能把这些结合起来吗?我想做的事情的语义应该从以下内容中明确


open(F,"|./prog1 | ./prog2", \$var);
print F "something cool";
close(F);
print $var;
然而,上述方法显然行不通


几分钟的实验和谷歌搜索似乎表明这是不可能的,但我想知道我是否坚持使用``来捕获输出。

您要做的是按原样打开文件句柄,将内容读取到一个变量,将您想要的任何内容追加到该变量,然后追加到刚刚生成的完整字符串


你就快到了,我希望这能有所帮助。:)

这似乎是不可能的,因为perl不支持“两端的管道”。更多信息请点击这里

perlmonks.org上的Corion为我回答了这个问题。

  • IPC::Open2
    可能会起作用,请参见
    man perlipc
    。然而,更有可能的是,您将以这种方式使程序死锁。不过这是安全的,只要管道中的数据小于pipe_BUF(在Linux 4096上),只写入一次,并且写入端在写入数据之后和读取结果之前立即关闭

  • 您可以尝试将程序重写为fork,这样您的最终结果是:
    YourProg |/prog1 |/prog2 | yourprogfork

  • 在现代Linux上,您可以使用/dev/shm将临时文件完全托管在虚拟内存中


    • 你可以通过几种方式实现你的目标。没有一个比在
      open
      中堆积额外的东西更容易

      您可以使用或使用其他类似模块,甚至可以编写自己的
      tee
      style子例程:

      my $var ='';
      
      open my $vh, '>', \$var or die "oh noes $!\n";
      open my $ph, '| ./prog1 | ./prog2' or die "Uh oh $!\n";
      
      my @handles = ($vh, $ph);
      
      print_to_all( \@handles,
          "I like cheese.\n",
          "I like teas.\n",
      );
      
      print $var;    
      
      sub print_to_all {
           my $handles = shift;
      
           for my $h ( @$handles ) {
               print $h @_;
           }
      
           return;
      }
      

      另一种方法是制作一个同时充当文件句柄和标量的函数。

      在perl中,我实际上想做的是不可能的。

      嗯,我知道我可以将我想输入到管道中的文件slurp成一个变量,然后一次发送所有文件-你认为这就是你的建议,对吗?但是我想一行一行地做这件事,我想这是不可能的。是的,我不知道一行一行地做这件事的方法。要一行一行地做这件事,请使用
      while
      循环逐行处理输入句柄并打印到输出句柄<代码>打印$\uuuwhile你是发到SOPW还是在chatterbox中询问?如果是SOPW,请发布一个链接。我经常惊讶于Perl中不可能实现的事情集是多么的小。这是另一个不可能的例子:参见daotoad关于绑定变量的建议。@mobrule在这一点上,我相当确定这是不可能的,至少不是我希望的方式,我得到的理由基本上是,这很可能会产生缓冲问题。我试过daotoad的例子,但它不起作用(见注释)。无论如何,这不是对perl的挖苦——我非常喜欢perl,我只是好奇。在上面的示例中,$var将只包含原始字符串,而pipe命令的结果将打印到STDOUT。我对直接将管道命令输出转换成$var很好奇,我认为这样做行不通。我试着用我自己的prog1、prog2运行这段代码,但最后它的$var只包含原始的串联输入字符串。