無限ループに陥ってしまったプロセスを強制終了させるためにはCtrl-Cやkillコマンドを利用します。
このとき、プロセスにはシグナルというものが送られています。プロセスはシグナルの種類に応じて既定された処理を実行します。
trapコマンドを用いると、各シグナル番号に対応する既定の処理を書き換えることができます。
trapコマンド
シグナルN1, N2, N3, ...を受けたときに実行するコマンドを指定することで、trapコマンド実行後からのシグナル受信時の挙動を書き換えます。
trap 'シグナルを受けたときに実行するコマンド' シグナル番号N1, N2, N3, ...
主なシグナルとサンプルコード
シグナル2
Ctrl-Cを押したときに送られるシグナルです。SIGINT (SIGnal INTerruput) とも。
sample.sh (実行注意!!!)
#!/bin/sh
trap '' 2 # ''は何もしない、つまりシグナルを無視するということ。
while :
do
echo 'looping... (CAN NOT BE STOPPED BY Ctrl-C!!)'
sleep 1
done
実行例 (killコマンドか何かでシグナル2以外を送って終了させてください)
$ sh sample.sh
looping... (CAN NOT BE STOPPED BY Ctrl-C!!)
looping... (CAN NOT BE STOPPED BY Ctrl-C!!)
....
シグナル15
killコマンドを実行したときに送られるシグナルです。シグナル受信時のコマンドリストにexitを含めていることに注意してください。含めないとシグナル受信後、コマンドリストを実行した後、プロセスは終了せずに残りの処理を継続実行します。
sample.sh
#!/bin/sh
trap "echo 'killed'; exit" 15
while :
do
echo 'looping...'
sleep 1
done
実行例 (他のターミナルでkillコマンドを実行します)
$ sh sample.sh
looping...
looping...
...
looping...
killed
別のターミナルでのコマンド例
$ ps | grep sample.sh | awk '{print $1}' | xargs kill
なお、killコマンドはデフォルトではシグナル15を送りますが、kill -n pidとするとシグナルnを送れます。
シグナル0
シェルスクリプト内でexitが実行されたり、すべての処理が完了して終了した際に自分自身に送るシグナルです。
sample.sh
#!/bin/sh
trap "echo 'end'" 0
echo 128
実行例
$ sh sample.sh
128
end
シグナル1
ターミナル終了時にログインシェルによって送信されるシグナルです。nohup という関連コマンドがあります。
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- UNIX リダイレクションについて「下記ファイルディスクリプタがプロセスと結びつける対象ファイル」を別のファイルに変更することをリダイレクションとよびます。実際には、ファイルディスクリプタ1と2の対象ファイルの変更を指すことが多いです。 ファイルディスクリプタとは? ファイルディスクリプタは「プロセス」と「プロセスが使用するファイル」を結びつけるもので、それらには0,1,2,...と連続した番号が割り当てられています。ファイルディ...
- シェルスクリプトにおける数値計算シェル変数はすべて文字列扱いであるため、数値計算のためには専用のコマンドを用いる必要があります。 整数同士の計算 整数同士の四則演算にはexprコマンドを使用します。 sample.sh #!/bin/sh expr 1 + 1 expr 1 - 1 expr 1 '*' 1 # ワイルドカードと区別するために、クォーテーションで囲う必要があります expr 1 / 1 expr 1 % 1 実行...
- egrepとgrepの違いgrepは 'g'lobal 'r'egular 'e'xpression 'p'rint つまり、全体から正規表現で一致したものを抽出するためのコマンドです。egrepは 'e'xtended grep つまりgrepの機能拡張版です。拡張正規表現とよばれる式が使用できるため、grepと比較して高度な抽出が可能になります。とはいえ、grepに'-E'オプションを付与して実行するとegrepとほぼ...
- シェルスクリプトにおける関数定義シェル関数は複数のコマンドをひとまとめにしたものです。引数の取得では、シェルスクリプトの引数と同じ名称の特殊変数を使用します。また、独自のローカル変数を用意することができないため、関数外で使用されている変数の内容を書き換えてしまう危険性があります。 シェル関数は複数のコマンドをまとめたもの sample.sh #!/bin/sh echo1(){ echo 1 } echo1 実行例 $ ...
- シェルスクリプトにおける反復処理for sample.sh #!/bin/sh for i in a b c; do echo $i done ARR=( "abc" "xyz" ) for e in "${ARR[@]}"; do echo $e done 実行例 $ ./sample.sh a b c abc xyz while sample.sh #!/bin/sh cnt=1 while ...