如何用Perl获取bjobs状态与输出并排查LSF随机故障?
解决方案建议
方法1:通过Shell重定向捕获输出与错误,结合退出状态码
LSF故障时bjobs -w通常会返回非0退出码,而任务全部完成时退出码为0。我们可以将标准错误重定向到标准输出,同时捕获命令的退出状态,以此区分两种场景:
my $cmd = 'bjobs -w 2>&1'; my $output = `$cmd`; my $exit_code = $? >> 8; # 判断LSF是否故障 if ($exit_code != 0) { if ($output =~ /Failed in an LSF library call: Failed in sending\/receiving a message: Connection reset by peer/) { print "LSF系统故障\n"; } else { print "命令执行异常,退出码:$exit_code\n"; } } else { # LSF正常,处理输出 if ($output eq '') { print "所有任务已完成\n"; } else { # 将输出保存到文件 open my $fh, '>', 'bjobs_result.txt' or die "无法创建文件: $!"; print $fh $output; close $fh; print "任务状态输出已保存\n"; } }
方法2:使用Capture::Tiny模块优雅捕获输出(推荐)
Capture::Tiny模块可以分别捕获命令的标准输出、标准错误和退出状态,无需手动处理Shell重定向,还能避免Shell注入风险:
首先安装模块:cpanm Capture::Tiny,然后编写代码:
use Capture::Tiny qw(capture); my ($stdout, $stderr, $exit_code) = capture { system('bjobs', '-w'); # 用列表形式传递命令参数更安全 }; if ($exit_code != 0) { if ($stderr =~ /Failed in an LSF library call: Failed in sending\/receiving a message: Connection reset by peer/) { print "LSF系统故障\n"; } else { print "命令执行错误:$stderr\n"; } } else { if ($stdout eq '') { print "所有任务已完成\n"; } else { open my $fh, '>', 'bjobs_result.txt' or die "无法创建文件: $!"; print $fh $stdout; close $fh; print "任务状态输出已保存\n"; } }
核心逻辑说明
- 退出状态码:LSF正常运行(无论是否有任务)时
bjobs -w返回0;LSF故障时返回非0值。 - 特征错误匹配:通过匹配标准错误中的特定故障字符串,精准判定LSF连接故障场景。
- 输出区分:任务全部完成时标准输出为空;LSF正常且有任务时标准输出包含任务状态信息;故障时标准错误包含特征报错内容。
内容的提问来源于stack exchange,提问作者Tony Wu
相关产品推荐
相关产品推荐

