在csh中重定向stderr时遇到麻烦

时间:2011-04-19 08:57:40

标签: perl shell redirect csh tcsh

我正在编写一个Perl脚本,它应该在shell中执行命令并解析它们的输出。作为一个shell,我打算使用csh。我已经开始了这个

my $out = `cmd`

但它不捕获STDERR,我也需要它。使用输出重定向运行sh不会执行任何操作

my $out = `sh -c "cmd 2>&1"`

仍然只捕获STDOUT,而不是STDERR。

即使重定向到csh中的文件也不适合我

tcsh$ cmd >& logfile.log

仍然仅捕获STDOUT%)

我正在尝试执行的命令是actuallty sh脚本,此脚本中的一些命令打印到STDERR中,我想捕获该输出。如果我执行sh -c "cmd 2>/dev/null" STDERR实际上转到/ dev / null并且只在终端中打印STDOUT。

有人可以帮我吗?

6 个答案:

答案 0 :(得分:1)

在这里,您正在捕获sh的STDOUT,它不是cmd的STDERR:

my $out = `sh -c "cmd 2>&1"`;

您可以直接运行cmd吗?

my $out = `cmd 2>&1`;

答案 1 :(得分:1)

  • 反引号捕获STDOUT而不是STDERR。
  • system会将stdout和stderr转储到其父级设置中。
  • 如果你想捕获 STDERR,你需要像IPC::Open3这样的东西:
  

open2()非常相似,open3()会产生给定的$ cmd并连接CHLD_OUT以便从孩子那里读取,CHLD_IN用于写入孩子,CHLD_ERR用于错误。如果CHLD_ERR为假,

答案 2 :(得分:1)

我遇到过同样的问题。在进行了一些研究之后,我遇到了这篇文章:Capture stderr as well as stdout from a tcs。在这篇文章的最后,作者找到了他的解决方法,这也满足了我的要求。我想你可以试一试。它可以很好地合并stderr和stdout的输出。

答案 3 :(得分:1)

我相信有些事你没有告诉我们。你在cygwin吗?还是Windows?您是否设置了PERL5SHELL环境变量?

有些事情你没有告诉我们,因为这些都可以在我可以轻松测试的五个平台上正常工作:

% perl -le '$out = `sh -c "grep missing /dev/nowhere 2>&1" | cat -n`; chomp $out; print "got <<<$out>>>"'
got <<<     1   grep: /dev/nowhere: No such file or directory>>>

但到目前为止,没有理由明确地将 sh (1)称为shelling out。那是因为Perl 总是调用 sh (1)来解决所有反引号,管道打开以及system()炮轰:

% perl -le '$out = `grep missing /dev/nowhere 2>&1 | cat -n`; chomp $out; print "got <<<$out>>>"'
got <<<     1   grep: /dev/nowhere: No such file or directory>>>

我能想到的除此之外的唯一情况发生在非Unix系统上,因为它们没有 / bin / sh ,所以还定义了其他内容。

但在任何情况下,简单的炮轰都不会在背后召唤 tcsh (1)。您必须严重破解 perl (1)来源才能实现这一目标。我还怀疑你可以(轻松地)破解二进制文件,因为字符串"/bin/tcsh"将比"/bin/sh"更长,并且它通常不会在 / bin中找到/ 无论如何。

即使从shell开始,你也无法让stderr重定向工作,这说明了一些非常奇怪的事情。我想我们需要更多信息。

答案 4 :(得分:1)

你说在tcsh中运行命令cmd >& logfile.log只会将cmd的stdout发送到日志文件,而不是stderr。这没有意义。

尝试使用以下脚本替换cmd:

#!/bin/sh

echo stdout
echo STDERR 1>&2

“stdout”和“STDERR”都应该出现在logfile.log中。

如果是这样,那么也许你的“cmd”正在做一些奇怪的事情。我最好的猜测是cmd写入/ dev / tty,而不是写入stdout或stderr;这不会受到重定向的影响。

要了解我的意思,请将此行添加到上述脚本中:

echo tty > /dev/tty

答案 5 :(得分:1)

我没有时间像往常一样模拟一个例子,甚至没有测试一个例子。我想你可以尝试使用Capture::Tiny看看是否有帮助。