【问题标题】:Perl STDERR redirect failingPerl STDERR 重定向失败
【发布时间】:2017-09-13 19:48:29
【问题描述】:

我们的系统使用的常用函数脚本使用简单的 STDERR 重定向来创建用户特定的错误日志。是这样的

# re-route standard out to text file
close STDERR;
open STDERR, '>>', 'd:/output/Logs/STDERR_' . &parseUsername($ENV{REMOTE_USER}) . '.txt'
   or die "couldn't redirect STDERR: $!";

现在,我将它复制粘贴到我自己的函数脚本中,以获取系统特定的错误日志,虽然它会编译,但它会破坏需要它的脚本。奇怪的是,它甚至不打印子脚本抛出的错误。我的稍微修改的版本看起来像,

close STDERR;
open (STDERR, '>>', 'err/STDERR_SPORK.txt')
  or die print "couldn't redirect STDERR: $!";

在命令提示符下一切都编译得很好,-c 返回 ok,如果我在函数脚本中抛出警告并编译,它会正确输出。我仍然不明白为什么这会杀死孩子们。我切断了重定向,果然它们起作用了。有什么想法吗?

【问题讨论】:

  • or die print ...????
  • @ikegami 我遇到了一个问题,它在打开时失败了,它不会说明原因。添加 print 至少让我知道为什么 open 失败了。原因已得到解决。

标签: perl file-handling stderr


【解决方案1】:

die(和warn)写入STDERR。如果您关闭STDERR,然后在尝试重新打开它时需要die,您希望在哪里看到错误消息?

因为这是 Perl,所以有很多方法可以解决这个问题。这是一对。

  1. 首先将文件打开到 tmp 文件句柄,如果一切正常,将其重新分配给 STDERR

    if (open my $tmp_fh, '>>', 
       'd:/output/Logs/STDERR_' . &parseUsername($ENV{REMOTE_USER}) . '.txt') {
       close STDERR;
       *STDERR = *$tmp_fh;
    } else {
       die "couldn't redirect STDERR: $!";
    }
    
  2. 使用con。对于从命令行运行的程序,大多数系统都有“当前终端”的概念。在 Unix 系统中,它是 /dev/tty,在 Windows 上,它是 con。打开此终端伪文件的输出流。

    open STDERR, '>>', 
       'd:/output/Logs/STDERR_' . &parseUsername($ENV{REMOTE_USER}) . '.txt'
       or do {
           open my $tty_fh, '>', 'con';
           print $tty_fh "couldn't redirect STDERR: $!";
           exit 1;
       };
    

【讨论】:

  • 在 CGI 脚本中写入 CON:/dev/tty 没有用。
  • @ikegami 在他们的辩护中,我确实提到过使用命令行,但你是对的。这是一个 CGI 脚本,因此命令行重定向不会有太大帮助
  • 在第一个 sn-p 中,STDERR 最终不是 fd 2。这可能会导致问题。我认为您可以通过将close STDERR; *STDERR = *$tmp_fh; 替换为open STDERR, '<&', $tmp_fh or die $!; 来解决这个问题
【解决方案2】:

在脚本中没有任何更改,在服务器中四处寻找,并且没有更改任何内容后,它现在可以按预期工作。老实说,我不知道该说什么。

【讨论】:

  • 跟进它——现在听起来很有趣。还有一些你可能知道的事情。
猜你喜欢
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 1970-01-01
相关资源
最近更新 更多