【问题标题】:Perl writing to file stream causing unexpected SIGPIPE errorPerl 写入文件流导致意外的 SIGPIPE 错误
【发布时间】:2012-06-27 20:07:32
【问题描述】:

我有以下 perl 代码尝试将字符串写入新创建的文件:

open(OUT, ">$file") or die "file out error!\n";
print OUT $string;

通常,此代码可以正常工作。如果我们对 $file 所在的目录没有写权限,程序就会失败,这是意料之中的。但是,不是打印“文件输出错误!”作为错误消息,程序只是以退出代码 13(权限被拒绝)退出。

  1. 当我们无法写入文件时,为什么打开方法会成功?
  2. 在这种情况下,我们如何获得适当的错误消息?

【问题讨论】:

  • 首先,我认为open 永远不会导致 SIGPIPE。写入封闭管道时会得到一个 SIGPIPE。这意味着print 可能是 SIGPIPE 的原因。 $SIG{PIPE} = 'IGNORE'; 将导致系统(因此 print)返回 $!=EPIPE 而不是抛出 SIGPIPE。
  • 是的,我同意所有观点,尽管它没有回答我的问题。
  • EROFS 表示您要写入的整个文件系统是只读的,而不是您尝试写入读写文件系统上的只读文件。有关该错误,请参阅 EACCES
  • 你的程序的退出代码是什么?如果是 13,那么这表明 EACCES 调用中的 open 错误。如果是 141,那就是 SIGPIPE 的证据。
  • 当系统返回该错误时,Perl 的 open 确实返回 false 和 $!=EACCES。 (chmod a-w . ; perl -e'open my $fh, ">", "file" or die $!')

标签: perl file-io sigpipe


【解决方案1】:

我认为您混淆了程序退出代码及其标准系统系统错误代码的报告。错误代码 (errno) 13 等同于“权限被拒绝”。

perl -lE '$!=13;say $!'
Permission denied

perl -lE '$!=32;say $!'
Broken pipe

当然,实际消息可能会因您的操作系统而略有不同。

就此而言,为打开构建错误消息的更好 (IMO) 方法是:`open OUT,">","$file" 或 die "Can't open $file: $! \n”。

【讨论】:

  • 一个进程退出集合$?(一个WEXITSTATUS),而不是$!(errno)。 $? = 13 是许多系统上的 SIGPIPE。
  • 使用die退出程序时,系统错误码和程序退出码可以相同。例如,试试perl -e '$!=4;die';echo $?perl -e '$!=14;die';echo $?
  • @mob,bash 的 $? 与 Perl 的不一样。它只是退出代码的一部分。该示例中的退出代码是 4
  • 就此而言,为打开构建错误消息的更好(IMO)方法是:`open OUT,">","$file" 或 die "Can't open $file: $!\n".
  • @ikegami 啊,那么您的原始评论更有意义。是的,当然:“退出代码” $?>>8 和进程收到的信号号是 $?&127 。
猜你喜欢
  • 1970-01-01
  • 2016-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多