Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何检查使用IPC::open3执行的命令是否挂起?_Perl_Ipc - Fatal编程技术网

Perl 如何检查使用IPC::open3执行的命令是否挂起?

Perl 如何检查使用IPC::open3执行的命令是否挂起?,perl,ipc,Perl,Ipc,我使用以下脚本从作为参数传递的命令中捕获STDIN、STDOUT和STDERR #!/usr/bin/perl use strict; use warnings; use IPC::Open3; local(*CMD_IN, *CMD_OUT, *CMD_ERR); my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $ARGV[0]); close(CMD_IN); my @stdout_output = <CMD_OUT>; m

我使用以下脚本从作为参数传递的命令中捕获STDIN、STDOUT和STDERR

#!/usr/bin/perl

use strict;
use warnings;

use IPC::Open3;

local(*CMD_IN, *CMD_OUT, *CMD_ERR);

my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $ARGV[0]); 

close(CMD_IN);

my @stdout_output = <CMD_OUT>;
my @stderr_output = <CMD_ERR>; 

close(CMD_OUT);
close(CMD_ERR);

waitpid ($pid, 0); # reap the exit code

print "OUT:\n", @stdout_output;
print "ERR:\n", @stderr_output;
除了我不确定如何监控传递的命令是否挂起之外,一切都很好。你能建议一条路吗

我从“编程Perl”中借用了这个片段。

您可以使用select或IO::select并提供一个超时。如果您想同时读取stdout和stderr,那么无论如何都应该这样做,请参阅IPC::Open3的文档

下面是一个使用IO::Select的示例程序:

注:

我对文件句柄使用词法变量。这需要对stderr句柄使用gensym。 can_read的参数是以秒为单位的超时。 我对非缓冲IO使用sysread。 如果存在读取超时,我将终止子进程。
我根据答案提出了以下解决方案

然而,在nwellnhof的例子中使用选择和避免信号看起来更干净,这就是我接受它的原因。如果有人感兴趣,我将在这里发布:

my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $cmd);

if ($pid > 0){
    eval{
        local $SIG{ALRM} = sub {kill 9, $pid;};
        alarm 6;
        waitpid($pid, 0);
        alarm 0;
    };
}

非常感谢!实际上,我实现了一些可以完成这项工作的东西,但我宁愿避免使用信号,而是使用您的解决方案。如果其他人感兴趣,我无论如何都会发布它。
my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $cmd);

if ($pid > 0){
    eval{
        local $SIG{ALRM} = sub {kill 9, $pid;};
        alarm 6;
        waitpid($pid, 0);
        alarm 0;
    };
}