bash で Ctrl-C をフックする方法

bash で Ctrl-C をフックする方法、つまりSIGINTを自前のシグナルハンドラで捕捉する方法についてメモ。

概要

シグナルハンドラを設定するには、trap というbashのビルトイン・コマンドを使います

#!/bin/bash
hander()
{
  echo "recv!!"
}

trap hander SIGINT

while /bin/true; do    :    ; done

Ctrl-Cを押すと SIGINT という名前のシグナルがプロセスに通知されるので、trapコマンドで SIGINT を受け取ったら hander という関数を呼ぶように設定しています

このシェルスクリプトは実行すると末尾で無限ループになるだけです。ただCtrl-C を押しても、シェルスクリプトは終了せず、代わりに hander()関数が呼ばれて"recv!" という文字列が画面に表示されます

Ctrl-Cでは停止しないので、終了させる場合は Ctrl-Z で中断させて

$ kill %1

とします

実利用例

スクリプト内で子プログラム(=子プロセス)を起動して、 Ctrl-C が押されたら、子プログラムだけkillする例

#!/bin/bash
hander()
{
   kill %1
}

trap hander SIGINT

./childprogram &

wait %1