【问题标题】:wget not behaving via IPC::Open3 vs bashwget 不通过 IPC::Open3 vs bash 表现
【发布时间】:2011-03-01 08:43:54
【问题描述】:

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

代码如下所示:

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 时,我在标准输出中将页面和信息混合在一起。我期望的是一个流中加载的页面和另一个来自 wget 的 STDERR。

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

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

【问题讨论】:

  • @DVK - 我不确定你的意思?在标准输入上喂 wget?我不确定我需要给它什么?
  • 好的,试过了,通过 bash shell,stdout 和 stderr 仍然是可分离的……

标签: perl ipc wget


【解决方案1】:

您将一个未定义的值作为错误句柄参数传递给 open3,正如 IPC::Open3 所说:

如果 CHLD_ERR 为 false,或者与 CHLD_OUT 相同的文件描述符,则子节点的 STDOUT 和 STDERR 在同一个文件句柄上(这意味着自动激活的词法不能用于 STDERR 文件句柄,见概要)...

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

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

【讨论】:

  • aaand,这就是我实际上不是 RTFM 的结果...我阅读了 Open2 文档,然后意识到我在此过程的后期需要 STDERR,并且没有阅读过 Open3 文档的第一行.
猜你喜欢
  • 2014-07-09
  • 2012-08-17
  • 1970-01-01
  • 2017-02-18
  • 2012-04-19
  • 1970-01-01
  • 2011-01-07
  • 2013-12-22
  • 1970-01-01
相关资源
最近更新 更多