coreutils超时模拟perl
发布时间:2020-12-16 06:13:16 所属栏目:大数据 来源:网络整理
导读:我试图使用perl替换超时(需要在centos5中) 这里的脚本: #!/usr/bin/perluse strict;my $pid=$$;my $timeout=shift;my @args=@ARGV;eval { local $SIG{ALRM} = sub { print "Timed OUT!n"; exit 142; kill 9,$pid; }; alarm($timeout); system(@args);};exi
我试图使用perl替换超时(需要在centos5中)
这里的脚本: #!/usr/bin/perl use strict; my $pid=$$; my $timeout=shift; my @args=@ARGV; eval { local $SIG{ALRM} = sub { print "Timed OUT!n"; exit 142; kill 9,$pid; }; alarm($timeout); system(@args); }; exit $?; 测试时我发现: 这里都很好 time /tmp/timeout 3 sleep 6 Timed OUT! real 0m3.007s user 0m0.000s sys 0m0.004s 但这里都很糟糕 time echo `/tmp/timeout 3 sleep 6` Timed OUT! real 0m6.009s user 0m0.000s sys 0m0.004s 在我使用/usr/bin/timeout测试的debian系统上: time echo `/usr/bin/timeout 3 sleep 6` real 0m3.004s user 0m0.000s sys 0m0.000s 所以问题 >为什么perl脚本工作如此奇怪? 请注意,我知道/usr/share/doc/bash-3.2/scripts/timeout,我也发现它的行为与我的perl方法相同 另请注意,我无法在此脚本的目标服务器上安装CPAN模块 我尝试使用exec()但在这种情况下它不处理sub中的信号. UPD 用@rhj中的脚本(必须修复一下) #!/usr/bin/perl use strict; use warnings; my $PID=$$; my $timeout=shift; my @args=@ARGV; my $pid = fork(); defined $pid or die "fork: $!"; $pid == 0 && exec(@args); my $timed_out = 0; $SIG{ALRM} = sub { $timed_out = 1; die; }; alarm $timeout; eval { waitpid $pid,0 }; alarm 0; if ($timed_out) { print "Timed out!n"; kill 9,$pid; kill 9,$PID; } elsif ($@) { warn "error: $@n"; } 它通过了上面的测试,但在调用外部脚本的情况下失败: RUN_SCRIPT #!/bin/sh sleep 6 test.sh #!/bin/sh a=`./timeout.pl 2 ./run_script.sh` 产量 $time ./test.sh real 0m6.020s user 0m0.004s sys 0m0.008s 解决方法
这个版本应该始终有效:
#!/usr/bin/perl use strict; use warnings; my $pid=$$; my $timeout=shift; my @args=@ARGV; my $pid = fork(); defined $pid or die "fork: $!"; $pid == 0 && exec(@args); my $timed_out = 0; $SIG{ALRM} = sub { $timed_out = 1; die; }; alarm $timeout; eval { waitpid $pid,$pid; } elsif ($@) { warn "error: $@n"; } 但它不会处理exec()调用中的错误. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |