mus*_*hil 5 linux scripting bash
我试图通过解析输出,检查运行和排队的PBS作业的数量qstat -tn1从bash脚本。到目前为止,这已经奏效:
count ()
{
qstat -tn1 | awk '
BEGIN { R = 0; Q = 0; }
$10 == "R" { R++ }
$10 == "Q" { Q++ }
END { print R, Q }'
}
if read -r R Q < <(count)
...
Run Code Online (Sandbox Code Playgroud)
但是,我看到qstat偶尔会因未知原因而失败。在这种情况下,它不会向 打印任何内容stdout和一些错误消息stderr,并以非零状态(相当标准)退出。但是,awk不知道qstat失败了,并且很高兴地打印0 0了它收到的空输入。然后read将 0 分配给两者,R并且Q不知道qstat实际上失败了。
R并Q使用 0 ,因为可能没有正在运行的进程或没有排队的进程,并且我需要打印,而不仅仅是一个空字符串,以获得此类进程的数量。BEGINawk0set -o pipefail,这将允许count以非零状态退出,但read无法看到退出状态,并且无论如何awk都会执行并打印0 0空输入。有什么好的方法可以让调用者count检测到它的失败吗?
我认为读取count进程替换会阻止您获得其返回状态。所以不要这样做。相反,将结果存储在变量中,或使用管道。
count=$(count)
if [ $? -eq 0 ]; then
read -r R Q <<<"$count"
…
Run Code Online (Sandbox Code Playgroud)
或者
set -o pipefail
if count | { read -r R Q; … }
Run Code Online (Sandbox Code Playgroud)
另一种可能性是使用该PIPESTATUS变量来检查第一个命令的返回状态。
count=$(qstat -tn1 | awk …)
if ((${PIPESTATUS[0]} == 0)); then
read P Q
…
Run Code Online (Sandbox Code Playgroud)
或者,当它的输入为空时,安排 awk 打印一些独特的东西(例如什么都没有)。
awk '
BEGIN { R = 0; Q = 0; }
$10 == "R" { R++ }
$10 == "Q" { Q++ }
END { if (NR) print R, Q }'
Run Code Online (Sandbox Code Playgroud)
您可以使用ifnefrom moreutils或其他方法测试命令的输入是否为空。但是,既然您正在使用 awk,那么您不妨直接在已有的 awk 脚本中进行。
如果您需要从qstat命令中获取返回状态,您可以将其作为额外的输入行提供给 awk。为了更容易解析,安排最后一行具有唯一的格式。
{
qstat -tn1
echo exit_code = $?
} | awk '
…
/^exit_code = / { status = $3 }
END { if (status == 0) print Q, R }
'
Run Code Online (Sandbox Code Playgroud)