
何百人ものユーザーが共有しているLinuxクラスタでシミュレーションを実行しています。誰が実行しているかを決定するジョブスケジューラがクラスタにインストールされており、スケジューラコマンドの1つ(showq
)は、すべてのアクティブジョブ、アイドルジョブ、ブロックされたジョブなどのリストを表示します。その出力を処理して、いつでもジョブを実行している一意のユーザー数などを確認したいと思います。以下は、showq -r
実行中のジョブを示すいくつかの出力例です。
active jobs------------------------
JOBID S PAR EFFIC XFACTOR Q USERNAME GROUP MHOST PROCS REMAINING STARTTIME
123456 R bas ----- 1.0 - user_X group_A n1 8 4:00:00 Fri Sep 19 17:25:05
123457 R bas ----- 1.0 - user_Y group_B n2 16 4:00:00 Fri Sep 19 17:25:05
123458 R bas ----- 1.0 - user_Y group_B n3 1 4:00:00 Fri Sep 19 17:25:05
123459 R bas ----- 1.0 - user_X group_A n4 1 4:00:00 Fri Sep 19 17:25:05
123460 R bas ----- 1.0 - user_X group_A n5 2 4:00:00 Fri Sep 19 17:25:05
123461 R bas ----- 1.0 - user_Z group_A n6 4 4:00:00 Fri Sep 19 17:25:05
......
5000 active jobs
具体的には、以下を計算したいと思います。
- ジョブを実行している一意のユーザー数とユーザーごとに実行されているジョブの数(グループにも同じことをしたいが、ユーザーに対してこれを行うとこれは簡単ではありません。)
PROCS
ユーザー/グループが占めるプロセッサコアの数()- ユーザー/グループに対して実行中の
PROC=1
シリアル( )および並列( )ジョブの数PROC>1
awk
Pythonではこれを非常に簡単に実行できますが、/sed
または他のLinuxコマンドを組み合わせて実行したいと思います。滑らかなジョークが私を幸せにします:-)
答え1
最初にすべきことは、出力から望ましくない行showq -r
、つまりアクティブなタスクを表す行などを削除することです。これはを使用して行うことができ、またはデータ行の一部を記述する正規表現をshowq -r | sed '1,2d' |sed '$d'
使用できます。たとえば、この場合、値が常にある場合は機能します。データ行のみを含むファイルがある場合は、次のものを使用できます。grep
grep "----"
EFFIC
----
associative arrays in awk
残りの魔法を完了してください。
#!/bin/awk
{
proc_count[$7] = proc_count[$7] + $10;
if ($10 > 1) { multi_proc[$7]++; } else { single_proc[$7]++; }
}
END {
for (foo in proc_count) { print foo, proc_count[foo], multi_proc[foo], single_proc[foo] }
}
上記のスクリプトを実行すると、シリアルプロセッサの数が表示されないことがわかりますuser_z
。行数を保存し、0
そこにaを印刷したくないからです。エラーチェックを追加して出力をきれいにするのはあなたの役割です。
答え2
まず、次のスクリプトを保存してchmod +x
名前を付けますjob_processor.awk
。
#!/usr/bin/gawk -f
## $7 username
## $8 groupname
## $10 procs
{
if ( $10 == 1 )
printf ("username: %s and groupname: %s are serial!\n",$7,$8);
else if ( $10 > 1 )
printf ("username: %s and groupname: %s are parallel!\n",$7,$8);
printf ("username: %s and groupname: %s with procs: %d!\n",$7,$8,$10);
}
次の形式を使用する必要があります。
cat jobs |./job_process.awk |sed '1,2d' |sed '$d'
出力は次のとおりです
username: user_X and groupname: group_A are parallel!
username: user_X and groupname: group_A with procs: 8!
username: user_Y and groupname: group_B are parallel!
username: user_Y and groupname: group_B with procs: 16!
username: user_Y and groupname: group_B are serial!
username: user_Y and groupname: group_B with procs: 1!
username: user_X and groupname: group_A are serial!
username: user_X and groupname: group_A with procs: 1!
username: user_X and groupname: group_A are parallel!
username: user_X and groupname: group_A with procs: 2!
username: user_Z and groupname: group_A are parallel!
username: user_Z and groupname: group_A with procs: 4!