qstat -tn1
スクリプトの出力を解析して、実行中およびキューに入れられた PBS ジョブの数を確認しようとしています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)
...
しかし、 が不明な理由で失敗することがありますqstat
。その場合、 には何も出力されずstdout
、 に何らかのエラー メッセージが出力されstderr
、非ゼロのステータス (かなり標準的) で終了します。ただし、 は失敗したawk
ことを認識せずqstat
、0 0
受け取った空の入力に対して を正常に出力します。次に、が実際に失敗したことを認識せずに、 とread
の両方に 0 を割り当てます。R
Q
qstat
- 実行中のプロセスやキューに入れられたプロセスがない可能性があるため、スクリプトのブロックで と を 0 で
R
初期化する必要があります。また、そのようなプロセスの数として、空の文字列だけでなく を印刷する必要があります。Q
BEGIN
awk
0
- を実行すると、ゼロ以外のステータスで終了
set -o pipefail
できますが、終了ステータスを確認できず、とにかく実行されて空の入力が出力されます。count
read
awk
0 0
- 名前付きパイプとサブプロセスを試すこともできますが、それらを管理するのは複雑すぎてやり過ぎのように感じます。
count
の呼び出し側が障害を検出できるようにする良い方法はありますか?
答え1
プロセス置換を読み込むと、戻りステータスを取得できなくなると思いますcount
。そのため、そうしないでください。代わりに、結果を変数に格納するか、パイプを使用してください。
count=$(count)
if [ $? -eq 0 ]; then
read -r R Q <<<"$count"
…
または
set -o pipefail
if count | { read -r R Q; … }
もう 1 つの可能性は、変数を使用してPIPESTATUS
最初のコマンドの戻りステータスを確認することです。
count=$(qstat -tn1 | awk …)
if ((${PIPESTATUS[0]} == 0)); then
read P Q
…
あるいは、入力が空の場合に awk が何か特別なもの (たとえば何も出力しない) を出力するように設定します。
awk '
BEGIN { R = 0; Q = 0; }
$10 == "R" { R++ }
$10 == "Q" { Q++ }
END { if (NR) print R, Q }'
コマンドの入力が空かどうかをテストするにはifne
、もっと見るまたはその他の方法ただし、awk にパイプするのであれば、既存の awk スクリプト内で直接実行したほうがよいでしょう。
コマンドからの戻りステータスを取得する必要がある場合はqstat
、それを追加の入力行として awk に渡すことができます。解析を容易にするために、最後の行が一意の形式になるように調整します。
{
qstat -tn1
echo exit_code = $?
} | awk '
…
/^exit_code = / { status = $3 }
END { if (status == 0) print Q, R }
'
答え2
これ:
count ()
{
{ qstat -tn1 || echo "EPIC FAIL" } | awk '
BEGIN { R = 0; Q = 0; }
$10 == "R" { R++ }
$10 == "Q" { Q++ }
END { print R, Q }'
}
if read -r R Q < <(count)
...
が成功した場合、qstat
その出力は に送信されますawk
。 がqstat
ゼロ以外のステータスを返す場合、テキスト「EPIC FAIL」が に送信されますawk
。
これは単なる例です。 echo を、 内部awk
または で処理できる適切なものに置き換えてくださいif read
。