Perl 如何检查使用IPC::open3执行的命令是否挂起?
我使用以下脚本从作为参数传递的命令中捕获STDIN、STDOUT和STDERRPerl 如何检查使用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
#!/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;
};
}