簡體   English   中英

Perl如何正確處理系統命令(包括帶有Kill和RC / STDERR / STDOUT捕獲的超時)

[英]Perl how to properly handle System Commands (including Timeout with Kill & capture of RC/STDERR/STDOUT)

從Perl腳本中,我想執行各種系統命令並處理腳本中的輸出。

該腳本將自動運行,因此我想確保沒有命令掛起等。

我願意接受任何形式的反饋。

我對命令執行的要求:

  • 超時->如果命令運行時間超過XX秒,則該命令應終止其進程
  • 如果命令返回信息,則不必等待超時結束
  • 我想在腳本中捕獲退出狀態,STDERR,STDOUT。

這是我從另一個stackoverflow問題得出的示例: 殺死一個掛起的子進程

目前對我不起作用的是:

  • 無法捕獲已執行命令的退出狀態
  • 無法捕獲已執行命令的STDERR

碼:

my $cmd = "sleep 15"; # other tests i use -> "echo bla" and "alkjdsf"
my $TIMEOUT = 10;

my $pid = open my $proc, '-|', "$cmd";

if (fork() == 0) {
    my $poor_mans_alarm = "sleep 1,kill 0,$pid ||exit for 1..$TIMEOUT;kill 9,$pid";
    # run poor man's alarm in a background process
    exec($^X, '-e', "$poor_mans_alarm");
}

my $process_output = "";
while (<$proc>) {
   $process_output .= $_;
}

如果您對此代碼有竅門或推薦一個完全不同的解決方案,請告訴我。

謝謝和歡呼



加成:

使用IPC :: Open3獲得了一個有效的示例,但是對於以后的讀者,請查看包含Timeout功能的IPC :: Run,如James Green所述。

IPC :: Open3的工作示例:

my $pid = open3(\*WRITE, \*READ,\*ERROR,"$command");

if (fork() == 0) {
    my $poor_mans_alarm = "sleep 1,kill 0,$pid ||exit for 1..10;kill 9,$pid";
    # run poor man's alarm in a background process
    exec($^X, '-e', "$poor_mans_alarm");
}


# get all the STDOUT and STDERR from the Child.
while (<READ>) {
   $output .= $_;
}

while (<ERROR>) {
   $output .= $_;
}

waitpid($pid, 0);
if ($?) {
    $rc = $? >> 8;
    if ($rc != 1){
        print "Some error $?\n";
    }
}

看起來IPC::Run提供了您所需要的幾乎所有東西,包括超時以及STDOUT和STDERR的捕獲。 文檔位於https://metacpan.org/pod/IPC::Run,其中包括一些用法示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM