首页 文章

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

提问于
浏览
3

我正在编写一个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 回答

  • 1

    我've come across the same question. And after conducting a little research, I'已经见过这篇文章:Capture stderr as well as stdout from a tcs . 在这篇文章的最后,作者找到了他的解决方法,这也满足了我的要求 . 我想你可以试一试 . 它可以很好地合并stderr和stdout的输出 .

  • 1

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

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

    你能直接运行 cmd 吗?

    my $out = `cmd 2>&1`;
    
  • 1
    • Backquotes捕获STDOUT而不是STDERR .

    • system会将stdout和stderr转储到其父级设置 .

    • 如果你想捕获STDERR,你需要像IPC::Open3这样的东西:

    与open2()极为相似,open3()产生给定的$ cmd并连接CHLD_OUT以便从子节点读取,CHLD_IN用于写入子节点,CHLD_ERR用于写入错误 . 如果CHLD_ERR为假,

  • 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)称为shell . 那是因为Perl always 为所有的反引号,管道打开和 system() shell-outs调用sh(1):

    % 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重定向工作,这说明了一些非常奇怪的事情 . 我想我们需要更多信息 .

  • 1

    你说在tcsh中运行命令 cmd >& logfile.log 只发送cmd 's stdout to the log file, not its stderr. That doesn' t有意义 .

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

    #!/bin/sh
    
    echo stdout
    echo STDERR 1>&2
    

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

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

    要查看我的意思,请将此行添加到上面的脚本中:

    echo tty > /dev/tty
    
  • 1

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

相关问题