Bashでバックグラウンドプロセスを起動し、SIGSTOPで停止状態にした。
新しいsleepを起動せず、同じPIDのプロセスを再開する。
sleep 600 &
TASK_PID=$!
kill -STOP "$TASK_PID"適切なコマンドはどれか。
SIGCONTを送ると、SIGSTOPなどで停止中の同じプロセスが再開します。監視するpsと、状態を変えるkillの役割を区別します。
詳細解説
kill -CONT "$TASK_PID"SIGCONTは停止中の同じプロセスを実行可能状態へ戻します。PIDは変わりません。
正しい選択肢です。kill -CONTはTASK_PIDで指定した既存プロセスへSIGCONTを送り、停止状態から再開させます。新しいsleepは作られず、PIDも変わりません。
killという名前でも、送るシグナルがSIGCONTなら終了ではなく再開操作になります。
kill -TERM "$TASK_PID"SIGTERMはプロセスへ終了を依頼するシグナルで、再開ではありません。
誤りです。SIGTERMはプロセスへ終了を依頼します。停止状態のプロセスへ送った場合でも、目的は再開ではなく終了です。
アプリケーションはSIGTERMを捕捉して終了処理を行えますが、SIGSTOPのように捕捉できないシグナルもあります。
nohup "$TASK_PID" &nohupには新しく起動するコマンドを指定します。既存PIDを再開する操作ではありません。
誤りです。nohupは、端末切断時のSIGHUPを無視する設定で新しいコマンドを起動するために使います。数値のPIDを既存プロセスとして再開する機能はありません。
nohupの引数には実行するコマンド名を指定するため、TASK_PIDの値をコマンド名として扱おうとして失敗します。
ps -p "$TASK_PID"psはプロセス状態を表示しますが、状態を変更しません。
誤りです。ps -pは指定PIDの情報を表示する監視操作です。停止状態ならSTAT欄などで確認できますが、実行状態へ変更しません。
確認にはps、変更には適切なシグナル送信という役割分担を押さえます。
実際に確かめる
一時的な検証環境で実行できる例です。
sleep 60 &
TASK_PID=$!
kill -STOP "$TASK_PID"
ps -o pid=,stat=,comm= -p "$TASK_PID"
kill -CONT "$TASK_PID"
ps -o pid=,stat=,comm= -p "$TASK_PID"
kill -TERM "$TASK_PID"期待される結果
停止後: 状態欄の先頭がおおむね T
再開後: 状態欄の先頭がおおむね S
※環境により追加の状態文字が付きます理解のポイント
- $!による直前のバックグラウンドPID取得
- SIGSTOP・SIGCONT・SIGTERMの役割
- 監視コマンドと状態変更コマンドの違い
確認時の注意
- 確認環境:
- psの出力は環境やタイミングにより追加の状態文字が付きます。
- 検証の最後にSIGTERMを送り、起動したsleepを残さないようにします。
基礎のおさらい
$!とPID
$!は、現在のシェルが直前にバックグラウンド起動したプロセスのPIDを返します。PIDを変数へ保存すると後続操作で同じプロセスを指定できます。
killはシグナル送信
killコマンドは対象PIDへシグナルを送ります。終了、停止、再開などの動作は、指定したシグナルの意味で決まります。
停止と終了は別状態
停止中のプロセスは存在し続け、再開できます。終了したプロセスは同じPIDの同じ実行として再開できません。
psのSTAT
一般にTはジョブ制御シグナルなどで停止中、Sは割り込み可能なスリープ状態を示します。追加文字が付く場合があるため、先頭文字を中心に確認します。