こんにちは!
LinuxやUNIXのシェルスクリプトで長時間かかる処理を書いているとき、「ユーザーが途中で Ctrl + C を押して強制終了(割り込み)したとしても、終了ログだけは残したい」「作成しかけた一時ファイルを消してキレイに終了したい」という場面はありませんか?
今回は、Cシェル(csh / tcsh)で割り込み処理を制御する onintr コマンドの使い方と、bashでおなじみの trap コマンドとの書き方の違いについて整理してみました。
💡 cshの「onintr」とは?
onintr(on interrupt)は、cshにおいてシグナル(割り込み)を受信した際のシェルの挙動を制御する組み込みコマンドです。
基本的には、スクリプト内に以下のようにラベルと一緒に記述して使います。
#!/bin/csh
# Ctrl+Cなどの割り込みが入ったら「cleanup:」ラベルへジャンプする設定
onintr cleanup
echo "処理を実行中です... (Ctrl+Cで中断テスト)"
sleep 100
# 正常終了時の処理
echo "すべての処理が正常に完了しました。"
exit 0
# --- 割り込み発生時のスキップ先 ---
cleanup:
echo "警告: Ctrl+C により処理が途中で強制終了されました。" > /var/log/my_script.log
# 必要に応じて一時ファイルの削除などを記述
exit 1
🔍 動きの仕組み
-
onintr labelと書いておくと、実行中にCtrl + C(SIGINT)などが押されたタイミングで、スクリプト内のlabel:の位置へgoto(ジャンプ) します。 -
ジャンプ先で「強制終了された旨をログに書き出す」「後始末をする」といった処理を実行し、最後に
exitで終了させるのが定石です。
⚙️ その他の指定パターン
-
onintr -すべての割り込みを無視します。(処理を途中で絶対に止められたくないクリティカルな区間に使います) -
onintr(引数なし) デフォルトの動作に復元します。(割り込みが入ったら即座にスクリプトを終了してシェルに戻る)
🐧 bashだとどう書く?(trapコマンド)
cshの onintr に相当するものが、bash(やsh)における trap コマンドです。
bashの trap はラベルへのジャンプではなく、実行したいコマンドや関数をワンライナーやブロックで直接指定できるのが特徴です。
#!/bin/bash
# Ctrl+C(シグナル番号 2 / SIGINT)が押されたときの処理を1行で定義
trap 'echo "CTRL+C is pushed." >> /var/log/my_script.log; exit 1' 2
echo "処理を実行中です..."
sleep 100
シグナル番号の 2 は SIGINT(Ctrl+Cによる中断)を意味しています。 trap '処理' INT や trap '処理' 2 のように指定することで、割り込み時に指定したコマンドを実行させることができます。
📝 まとめ:どういう時に使う?
onintr や trap は、主に以下のような「スクリプトの信頼性を高めたいとき」に使われます。
-
強制終了のログ記録 誰かが手動で中断したのか、最後まで走りきったのかをログファイル(
/var/log/...等)に明確に残したいとき。 -
一時ファイル(Lockファイル)の削除 二重起動防止用のロックファイルや、作業用のテンポラリファイル(
/tmp/...)を残さずにキレイにお掃除して終了したいとき。 -
外部リソースの解放 データベース接続の切断や、バックグラウンドプロセスの停止処理を確実に挟みたいとき。
古いシステムや特定の環境でcshのスクリプトをメンテする機会があれば、ぜひ onintr による割り込みハンドリングを活用してみてください!
【参考】

