wget不通过IPC :: Open3 vs bash表现

时间:2010-06-08 20:11:37

标签: perl ipc wget

我正在尝试将文件从远程网站流式传输到本地命令,并在尝试检测错误时遇到一些问题。

代码看起来像这样:

use IPC::Open3;

my @cmd = ('wget','-O','-','http://10.10.1.72/index.php');#any website will do here

my ($wget_pid,$wget_in,$wget_out,$wget_err);
if (!($wget_pid = open3($wget_in,$wget_out,$wget_err,@cmd))){
    print STDERR "failed to run open3\n";
    exit(1)
}
close($wget_in);
my @wget_outs = <$wget_out>;
my @wget_errs = <$wget_err>;
print STDERR "wget stderr: ".join('',@wget_errs);
#page and errors outputted on the next line, seems wrong
print STDERR "wget stdout: ".join('',@wget_outs);

#clean up after this, not shown is running the filtering command, closing and waitpid'ing

当我直接从命令行运行wget命令并将stderr重定向到文件时,会发生一些明智的事情 - stdout将是下载的页面,stderr将包含有关打开给定页面的信息。

wget -O - http://10.10.1.72/index.php 2> stderr_test_file

当我通过open3运行wget时,我在stdout中将页面和信息混合在一起。我期望的是一个流中加载的页面和另一个流中的wget的STDERR。

我可以看到我已经将代码简化到不清楚我为什么要使用open3这一点,但总的计划是我想在我收到它时将stdout流式传输到另一个过滤程序,然后在结束我打算从wget和过滤程序中读取stderr,以确定出现什么问题。

    其他重要的事情:
  • 我试图避免将wget'd数据写入文件,然后将该文件过滤到另一个文件,然后读取输出。
  • 关键是我能够看到出了什么问题,而不只是阅读$? &GT;&GT; 8(即我必须告诉用户,嘿,IP地址是错误的,或者不是正确的网站,或者其他什么)。
  • 最后,我选择system / open3 / exec而不是其他perl-isms(即反引号),因为有些输入是由不值得信任的用户提供的。

1 个答案:

答案 0 :(得分:3)

您将未定义的值作为错误句柄参数传递给open3,而IPC::Open3表示:

  

如果CHLD_ERR为假,或者与CHLD_OUT相同的文件描述符,则子进程的STDOUT和STDERR位于同一文件句柄(这意味着自动生成的词法不能用于STDERR文件句柄,见大纲)......

解决方法是在调用$wget_err之前初始化open3

my ($wget_pid, $wget_in, $wget_out, $wget_err);
use Symbol qw(gensym);
$wget_err = gensym();
if (!$wget_pid = open3( ... ) ) { ...