Edu*_*Edu 6 perl redirect fork kill
我在perl中创建了一个脚本来运行超时的程序.如果正在执行的程序需要更长的时间,那么超时将比脚本终止该程序并返回消息"TIMEOUT".
脚本工作得很好,直到我决定重定向执行程序的输出.
当stdout和stderr被重定向时,脚本执行的程序没有被杀死,因为它的pid与我从fork获得的pid不同.
似乎perl执行一个shell,在重定向的情况下执行我的程序.
我想有输出重定向但仍能够在超时的情况下终止程序.
有关如何做到这一点的任何想法?
我的脚本的简化代码是:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX ":sys_wait_h";
my $timeout = 5;
my $cmd = "very_long_program 1>&2 > out.txt";
my $pid = fork();
if( $pid == 0 )
{
exec($cmd) or print STDERR "Couldn't exec '$cmd': $!";
exit(2);
}
my $time = 0;
my $kid = waitpid($pid, WNOHANG);
while ( $kid == 0 )
{
sleep(1);
$time ++;
$kid = waitpid($pid, WNOHANG);
print "Waited $time sec, result $kid\n";
if ($timeout > 0 && $time > $timeout)
{
print "TIMEOUT!\n";
#Kill process
kill 9, $pid;
exit(3);
}
}
if ( $kid == -1)
{
print "Process did not exist\n";
exit(4);
}
print "Process exited with return code $?\n";
exit($?);
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助.
psm*_*ars 12
尝试改变$cmd从
my $cmd = "very_long_program 1>&2 > out.txt";
Run Code Online (Sandbox Code Playgroud)
至
my $cmd = "exec very_long_program 1>&2 > out.txt";
Run Code Online (Sandbox Code Playgroud)
该exec会告诉得到由perl的催生外壳采用very_long_program替换本身,而不是运行very_long_program作为一个孩子.
(在这种情况下perl生成shell的原因是因为$cmd包含重定向字符 - 而且perl不知道如何自己处理它们.另一种解决问题的方法是在fork()调用之后但在调用之前在perl中进行重定向exec()- 但这有点棘手,所以exec首先尝试解决方法!)