Claude CodeでSlurmのsbatchを点検する — #SBATCHの誤りとsbatch/scancelの権限
sbatchスクリプトの#SBATCH指定をClaude Codeに読ませて直し、sbatchとscancelはask、squeueとsacctはallowに切る。--test-onlyで投入前に確かめる手順と、効かない書き方も示します。
Claude CodeでSlurmのsbatchを点検する — #SBATCHの誤りとsbatch/scancelの権限
sbatchのジョブスクリプトは、書き間違いがキューに入ってから表に出ます。メモリ指定の矛盾は即座に拒否され、時間指定の誤りは数分で打ち切られ、ディレクティブの置き場所の誤りは黙って無視されます。投入前にClaude Codeへ読ませる価値があるのはこの部分です。
ただし、点検を頼む相手に sbatch や scancel を自由に打たせると、点検が投入に化けます。この記事では、点検の観点、権限ルールの切り方、--test-only での検証の順に進めます。
点検は「読むだけ」と「投入」を分けて頼む
スクリプトを読んで直す作業は、作業ディレクトリ内のファイル操作で済みます。クラスタに触れるのは sbatch、scancel、squeue、sacct を実行するときです。
権限ルールはこの境目に引きます。
- 読むだけ: ファイルの読み取りと、
squeue/sacctによる状態の参照 - 変更が起きる:
sbatch(投入)とscancel(取り消し)
ジョブを走らせるのは人間の判断に残し、Claudeには「直した理由が分かる差分」と「投入前の検証結果」を出させる。この分担が、以降の設定の前提です。
Claude Codeに見せる点検観点
次のスクリプトには、わざと誤りを入れてあります(例示用の架空のジョブです)。
#!/bin/bash
#SBATCH --job-name=align
#SBATCH --time=48
#SBATCH --mem=64G
#SBATCH --mem-per-cpu=4G
#SBATCH --cpus-per-task=16
#SBATCH --output=$HOME/logs/%x-%j.out
module load samtools
#SBATCH --partition=highmem
export OMP_NUM_THREADS=16
srun ./run_alignment.shSlurmのsbatchマニュアルに照らすと、読ませたい箇所は4つあります。
このスクリプトの誤り
--time=48 は48分
数字だけの指定は分として扱われます。2日のつもりなら
2-00:00:00か48:00:00と書きます。--mem と --mem-per-cpu の併記
--mem、--mem-per-cpu、--mem-per-gpuは同時に使えません。どれか1つに絞ります。--output の $HOME
#SBATCH行はシェルではなくSlurmが直接読むため、変数名は文字列のまま扱われます。パスは絶対パスで書きます。module load のあとの #SBATCH
最初の非コメント行に達した時点で、以降のディレクティブは処理されません。
--partitionは効いていません。
ほかにも、メモリの単位とCPU数の掛け算で見落としが出やすい箇所があります。
--memの既定単位はメビバイトで、K/M/G/Tの接尾辞で変えられる。--mem=0は「ノードの全メモリを要求」の特別扱い--mem-per-cpuを--exclusiveと併用し、「値 × ノードのCPU数」がパーティション内のどのノードのメモリも超えると、ジョブは拒否される--timeが所属パーティションの上限を超えると、ジョブは待機状態のまま残る。エラーにならず、いつまでも始まらない--cpus-per-taskはタスクあたりのCPU数。--ntasksと掛けた総数が必要CPUになる
ハードコードした OMP_NUM_THREADS=16 も点検対象です。--cpus-per-task を変えたときに食い違うので、Slurmが設定する SLURM_CPUS_PER_TASK を参照する書き方に寄せると、指定が1か所で済みます。
ジョブ配列のスクリプトで見る点
--array を使うスクリプトは、誤りの種類が増えます。Claudeに読ませるときは、次の3点を観点に足します。
- 添字の範囲: 最小の添字は0。
--array=0-15%4のように%を付けると、同時に走るタスクを4つに絞れる。%を落とすと、全タスクが一斉にキューへ入る - 出力ファイル名: 配列ジョブの既定は
slurm-%A_%a.out(%Aが親のジョブID、%aが添字)で、通常のジョブのslurm-%j.outとは別物。--outputを自分で書くなら、配列では%A_%aを入れないと、各タスクが同じファイルを奪い合う形になる - 添字の上限: 最大値はクラスタの設定値
MaxArraySizeより1小さい値までで、管理者の設定に依存する
%x(ジョブ名)や %j(ジョブID)などのファイル名パターンは、#SBATCH 行の中でSlurmが展開します。シェルの $HOME とは違う仕組みなので、混ぜて書いたときに誤りが出やすい箇所です。
GPUを使うジョブでは、--mem-per-gpu も排他の対象です。--mem や --mem-per-cpu と同時に書くと、先ほどのメモリ指定の併記と同じ誤りになります。
CLAUDE.mdに点検の手順を書いておく
毎回プロンプトで観点を並べる代わりに、リポジトリの CLAUDE.md に手順を置きます。例えば次のような内容です。
## sbatchスクリプトの点検
ジョブスクリプト(`*.sbatch`)を直すときは、次の順で進める。
1. `#SBATCH` 行を上から読み、以下を表にして報告する
- `--time` の書式(数字のみは分)
- `--mem` / `--mem-per-cpu` / `--mem-per-gpu` の併記
- `--cpus-per-task` × `--ntasks` と、スクリプト内のスレッド数指定の一致
- `#SBATCH` が最初のコマンド行より前に集まっているか
- `--output` / `--error` に変数(`$HOME` など)を書いていないか
2. 直した理由を1行ずつ付けて差分を示す
3. 直したら `sbatch --test-only <file>` を実行して結果を貼る
4. `sbatch`(`--test-only` なし)と `scancel` は実行しない。実行は人間が決める4行目はあくまで指示で、強制力はありません。強制はこのあと書く権限ルールの役目です。CLAUDE.mdは「Claudeが何を試みるか」を形づくり、権限ルールは「何が通るか」を決めます。
permissionsでsbatch/scancelをask、squeue/sacctをallowにする
.claude/settings.json に次を置きます。
{
"permissions": {
"allow": [
"Bash(squeue *)",
"Bash(sacct *)"
],
"ask": [
"Bash(sbatch *)",
"Bash(scancel *)"
]
}
}ルールの評価順はdeny、ask、allowの順で、最初に当たったものが結果を決めます。特異性は評価順を変えません。ここから3つのことが決まります。
sbatch --test-only も確認の対象になります。Bash(sbatch *) の * は空白を含む任意の文字列に当たるため、sbatch --test-only job.sbatch も同じaskに入ります。askが先に評価されるので、Bash(sbatch --test-only *) をallowに足しても例外にはなりません。
dry-runを承認なしで通したいなら、sbatch * のaskをやめて Bash(sbatch --test-only *) だけをallowに置く構成になります。この場合、通常の sbatch job.sbatch はどのルールにも当たらず、既定の動作として確認が出ます。askルールで明示的に縛るか、既定の確認に任せるかの選択です。
squeue と sacct はallowを書く必要があります。Claude Codeが確認なしで通す組み込みの読み取り専用コマンドは ls、cat、grep、wc などで、squeue と sacct はその一覧にありません。allowを書かない限り、状態を見るたびに確認が出ます。
複合コマンドは部分ごとに判定されます。&&、|、; で連結した場合、askは「どの部分が当たっても」確認を出します。allowは全部分が許可されて初めて通ります。squeue -u $USER && scancel 12345 は、scancel がaskに当たるので止まります。引数なしの xargs は剥がしてから照合されるため、squeue ... | xargs scancel の末尾も scancel として判定される規則です。
依頼文の例と、確認画面で見る点
CLAUDE.mdに手順があれば、依頼は短くて済みます。
align.sbatch を点検して。#SBATCH の問題を表で報告し、
直したら sbatch --test-only の結果まで見せて。askの確認画面には、実行されるコマンドの全文が出ます。承認の前に見るのは次の3点です。
--test-onlyが付いているか(付いていなければ、それは本当の投入)- 対象のファイル名が点検したスクリプトと一致しているか
&&や;でほかのコマンドが連結されていないか
確認画面で「Yes, and don't ask again」を選ぶとallowルールが保存されます。ただしaskとallowの両方に当たるコマンドはaskが先に評価されるため、sbatch をaskに置いている限り、保存しても確認は消えません。
ルールが効かない書き方
権限ルールが見るのは、Claudeが書いたコマンドの文字列です。同じプログラムでも別の形で呼ぶと当たりません。公式のドキュメントは、git push のdenyが git -C . push や bash -c '...' 経由では当たらない例を挙げています。sbatch に置き換えても同じです。
| 書き方 | Bash(sbatch *) のask |
|---|---|
sbatch job.sbatch | Bash(sbatch *) のask当たる |
/usr/bin/sbatch job.sbatch | Bash(sbatch *) のask当たらない |
bash -c 'sbatch job.sbatch' | Bash(sbatch *) のask当たらない |
bash submit_all.sh(中で sbatch) | Bash(sbatch *) のask当たらない |
srun や salloc のように別名でジョブを走らせるコマンドは、別の文字列なので、使わせたくないならaskに足します。
文字列の照合では防ぎきれない部分は、PreToolUse hookでコマンド全文を検査するか、サンドボックスで実行環境そのものを絞ります。権限の二重化の考え方はClaude CodeでDenoを開発するにも書いています。引数を条件にするルールの書き方はClaude Codeの権限ルールをパラメータで書くが詳しいです。
--test-onlyで投入前に確かめる
--test-only は、バッチスクリプトを検証し、現在のキューと指定条件から開始時刻の見積もりを返します。ジョブは実際には投入されません。
sbatch --test-only align.sbatch点検の流れは次のとおりです。
点検から投入まで
- 1
Claudeに #SBATCH を読ませる
CLAUDE.mdの手順どおり、観点ごとの表と直した差分を出させます。
- 2
--test-only を通す
askの確認画面でコマンドを確かめて承認します。拒否されたらメッセージをClaudeに戻し、指定を直させます。
- 3
人間が sbatch を実行する
差分と見積もりを読んだうえで、投入は手元のシェルで打ちます。
- 4
squeue と sacct で追う
状態の参照はallow済みなので、Claudeに続けて見せられます。
--test-only が見るのはSlurmが受け付けるかどうかと待ち時間の見積もりで、スクリプト本体の正しさは見ません。module load の失敗やコマンドのタイプミスは、ジョブが動いて初めて出ます。投入後に sacct で終了状態を見て、直しにつなぐ作業は別に残ります。
つまずきやすい点
点検で直した直後や、権限を切った直後に出やすい例です。
--partitionを指定したのに別のパーティションで動く:#SBATCHがmodule loadなどの後ろにないか確かめる--timeや--mem-per-cpuの上限はクラスタ管理者の設定で決まる。上限を超える--timeを書いてもエラーにならず、ジョブが待機のまま残ることがある- 権限ルールは
settings.jsonに置いても、より優先度の高い設定(管理者の設定)に上書きされうる。拒否が効かない場合は設定の優先順位を確かめる
Slurm上でClaude Codeを長時間走らせる運用そのものはClaudeに長時間の科学計算を任せるにあります。
まとめ
点検では #SBATCH の書式と置き場所、メモリ指定の排他、時間の単位を見ます。権限は sbatch と scancel をask、squeue と sacct をallowに置きますが、askは --test-only にも及ぶので、dry-runを承認なしにしたい場合は構成を組み替える必要があります。ルールが見るのは文字列だけで、bash -c やラッパースクリプト経由は止まりません。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。