【问题标题】:Error in perlipc documentation?perlipc 文档中的错误?
【发布时间】:2012-05-14 11:24:39
【问题描述】:

我正在尝试解决我在 perlipc 文档中看到的内容。

如果您正在写入管道,您还应该捕获 SIGPIPE。否则, 想想当你启动一个管道到一个命令时会发生什么 不存在:open() 很可能会成功(它只是 反映了 fork() 的成功),但是你的输出将 失败——壮观。 Perl 无法知道该命令是否有效 因为您的命令实际上是在一个单独的进程中运行 exec() 可能失败了。因此,虽然虚假命令的读者 仅返回文件的快速结束,伪造命令的编写者将触发 他们最好准备好处理的信号。考虑:

   open(FH, "|bogus")  or die "can't fork: $!";
   print FH "bang\n"   or die "can't write: $!";
   close FH            or die "can't close: $!";

直到收盘才会爆炸,它会爆炸 SIGPIPE。要抓住它,你可以使用这个:

   $SIG{PIPE} = 'IGNORE';
   open(FH, "|bogus")  or die "can't fork: $!";
   print FH "bang\n"   or die "can't write: $!";
   close FH            or die "can't close: status=$?";

如果我没看错的话,它说第一个版本可能在最后关闭之前不会死。

但是,这在我的 OS X 机器上没有发生(Perl 版本 5.8.9 到 5.15.9)。无论我是否有 $SIG{PIPE} 行,它都会在 open 上以“无法分叉:没有这样的文件或目录”而爆炸。

我误会了什么?

【问题讨论】:

  • 我认为 open 已更改为更好地报告该案例,而 perlipc 未更新;您仍然可以获得记录在案的行为,但您需要使用更详细的 open(..., '|-') 机制。
  • geekosaur: 切换到open my $fh, '|-', ''bogus" or die 会出现同样的错误。
  • 呃。我的意思是真的很长的路,你根本不指定命令,而是脚本本身forks,你在孩子中运行exec

标签: perl ipc


【解决方案1】:

这是在 5.6 的开发过程中实施的更改,以便 system() 可以检测到它何时无法派生/执行子

https://github.com/mirrors/perl/commit/d5a9bfb0fc8643b1208bad4f15e3c88ef46b4160

它也记录在http://search.cpan.org/dist/perl/pod/perlopentut.pod#Pipe_Opens

它本身指向 perlipc,但 perlipc 似乎确实缺少这个

【讨论】:

    【解决方案2】:

    我的 Perl、v5.14.2、Ubuntu 12.04 上的输出相同:

    $ perl
       open(FH, "|bogus")  or die "can't fork: $!";
       print FH "bang\n"   or die "can't write: $!";
       close FH            or die "can't close: $!";
    can't fork: No such file or directory at - line 1.
    

    而且那个错误是奇怪,因为它与分叉无关——他们必须添加一些前瞻猜测,看看它是否可以执行bogus。 (这充其量是一个竞态条件,但在常见情况下可能会提供明显更好的错误处理;并且只会在竞态失败时与旧行为一样不方便。)

    【讨论】:

    • 不一定是猜测;鉴于 Perl 已经尝试使用内部 PATH 搜索和 exec 如果不涉及 shell 元字符,它已经预先检测到“未找到”。
    • @geekosaur: 但是当execve() 调用最终到来时,bogus 可能在PATH 和可执行文件中。是的,只有几毫秒的时间,但是race conditions are rarely this benign。 :)
    • 我认为只有在编写该代码时特别期望它会失败时才算作竞争条件。
    • 是的,这取决于chmod a-x /bin/bogus 在该程序执行期间的时间以获得不同的行为。绊倒会很棘手。
    猜你喜欢
    • 2021-07-31
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多