【问题标题】:Why does this perl script sometimes stop printing after the system function为什么这个perl脚本有时会在系统功能后停止打印
【发布时间】:2011-07-11 14:03:34
【问题描述】:

我改变后:

system("recode ISO-8859-1..UTF-8 $csvPath");
if($? == -1) {
    die(" failed\n");
}

到:

if(system("recode ISO-8859-1..UTF-8 $csvPath")) {
        die(" failed!");
}

效果更好,但并非总是如此。

代码sn-p:

print("recoding file to utf-8...");
#`recode ISO-8859-1..UTF-8 $csvPath`;
system("recode ISO-8859-1..UTF-8 $csvPath");
if($? == -1) {
   die(" failed\n");
}
print(" done!\n");

这种情况并不总是发生。有时有效,有时无效。

如果它不起作用(在这种情况下脚本没有完成),第一个打印工作,但第二个打印“完成!”即使外部命令有效,也永远不会打印。

【问题讨论】:

  • 在我看来,如果脚本运行到结束,打印应该会发生。剧本写完了吗?在此上下文中的重要信息是您使用的是什么操作系统,以及您使用的是什么外壳。
  • 不,脚本没有完成。该系统是 GNU/Linux。用户有 bash shell。
  • 好吧,system 调用等待子进程完成,所以看起来这就是你的问题所在。阅读documentation for system
  • 另外,我怀疑这更多是 linux/Unix 标签的问题,如果有,请重新编码。
  • @peko,有三种可能性。 1) dieprint 已执行,而您只是没有注意到(由于缓冲或异常捕获或其他原因)。 2)system 没有返回,因为孩子没有结束。 3) Perl 进程被杀死(例如被信号)。

标签: perl printing system


【解决方案1】:

您的测试if($? == -1) 没有多大意义。如果命令成功,$? 将为 0,如果失败,则为非 0。例如,如果命令执行exit(1)$? 应该是 256——至少在类 Unix 系统上是这样。测试system() 返回的值可能比事后检查$@ 更简洁。

尝试在程序顶部设置$| = 1;;这会使您的输出无缓冲,并可能让您在脚本终止之前看到一些输出。

在执行之前打印命令字符串的确切值。如果$cvsPath 是一个空字符串(或者如果它是undef 并且您没有启用警告),那么您正在调用recode 而没有文件参数,它将从标准输入中读取。这或许可以解释您所看到的行为。

虽然这与您的问题没有直接关系,但如果给system() 一个参数,并且如果该参数包含shell 元字符(包括空格),那么命令由shell 执行。使用多个参数,它直接调用命令:

system('recode', 'ISO-8859-1..UTF-8', $csvPath);

perldoc -f system 了解更多信息。

事实上,如果 $cvsPath 的错误值是导致您的问题的原因,那可能已经暴露了它,因为它会将一个空字符串作为单独的参数传递给 recode。在这种情况下,recode 产生的错误消息是:

recode: fopen (): No such file or directory

(括号中显示的是空文件名)。

请注意,其中很多都是基于不完整信息的猜测。发布一个显示问题的小型完整程序将使这变得容易得多。

【讨论】:

    猜你喜欢
    • 2012-08-25
    • 2012-10-04
    • 1970-01-01
    • 2011-03-21
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 2014-11-23
    相关资源
    最近更新 更多