サーバー運用をしていると、ネットワーク遅延やデッドロックでコマンドがハングアップするケースは珍しくありません。
この記事では、timeout コマンドを使って制限時間付きでコマンドを実行する方法を解説します。
シェルスクリプトでのタイムアウト処理、終了コードの読み方、実務でよく使う組み合わせパターンまでカバーします。
この記事のポイント
・timeout コマンドで指定秒数を超えたプロセスを自動終了できる
・終了コード 124 で「タイムアウトによる終了」を判定できる
・--kill-after で SIGTERM の後に SIGKILL を送るダブル保険が設定できる
・cron ジョブや API 呼び出しのハングアップ対策として積極的に使う
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
timeoutコマンドとは|なぜ必要なのか
サーバー運用で「コマンドがハングアップする」ケースには主に3つの原因があります。・NFS や SMB マウント先がネットワーク経路の問題で応答しなくなった
・curl や wget でリモートホストが無応答のまま接続を保持している
・デッドロックが発生したプロセスがいつまでもロックを解放しない
このような状況に対処するのが
timeout コマンドです。指定した秒数が経過してもコマンドが終了しなかった場合、シグナルを送って強制終了します。
実行環境:RHEL 9.4 / Ubuntu 24.04 LTS(coreutils パッケージに含まれる)
基本的な使い方
1. 書式と基本動作を確認する
書式は非常にシンプルです。# 基本書式 timeout 秒数 コマンド [引数...] # 例: 5秒以内に終わらなければ終了する $ timeout 5 sleep 10 $ echo $? 124
sleep 10 は 5 秒で強制終了され、終了コード 124 が返ります。タイムアウトが発生しなかった場合は、実行したコマンドの終了コードがそのまま返ります。
このため、スクリプト内では「終了コード 124 = タイムアウトによる終了」として判定できます。
2. 時間単位を指定する
秒数の代わりに単位付きで指定できます。# 30秒(単位なしの数値は秒) timeout 30 コマンド # 2分 timeout 2m コマンド # 1時間 timeout 1h コマンド # 90分(分単位で指定) timeout 90m コマンド
s(秒)・m(分)・h(時間)・d(日)です。3. 送信するシグナルを変更する
デフォルトではSIGTERM(番号15)が送信されます。プロセスによっては SIGTERM を無視するものがあるため、
-s オプションでシグナルを指定できます。# SIGKILL(強制終了)を送信する timeout -s SIGKILL 10 コマンド # シグナル番号で指定(9=SIGKILL) timeout -s 9 10 コマンド
応用・実務Tips
1. --kill-after でダブル保険をかける
SIGTERM を送ってもプロセスが終了しないケースがあります。--kill-after(短縮形 -k)を使うと、SIGTERM の後に指定秒数待って、まだ動いていれば SIGKILL を送ります。# 30秒でSIGTERM → さらに10秒待ってSIGKILL timeout --kill-after=10 30 コマンド # 短縮形 timeout -k 10 30 コマンド
2. シェルスクリプトでタイムアウト判定する
#!/bin/bash # 外部APIを30秒以内に呼び出す例 timeout 30 curl -s https://api.example.com/status -o /tmp/api_result.json EXIT_CODE=$? if [ $EXIT_CODE -eq 124 ]; then echo "ERROR: APIへの接続がタイムアウトしました" >&2 exit 1 elif [ $EXIT_CODE -ne 0 ]; then echo "ERROR: curl が失敗しました(終了コード: ${EXIT_CODE})" >&2 exit 1 fi echo "API応答を取得しました" cat /tmp/api_result.json
$? を変数に保存するのがポイントです。if 文の直前に他のコマンドを挟むと終了コードが上書きされるため、必ず変数に退避してから判定します。3. cron ジョブのハングアップ対策
cron で定期実行しているジョブがハングアップすると、次の実行が重複して起動されます。timeout を組み合わせることでジョブの最大実行時間を保証できます。
# /etc/cron.d/backup-job の設定例 # バックアップスクリプトを最大115分でタイムアウトさせる 0 2 * * * root timeout -k 60 115m /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
その後、全バッチジョブに timeout を標準導入しました。
なお、Apache のタイムアウト設定は
timeout コマンドではなく httpd.conf の Timeout ディレクティブで行います。詳しくはApache タイムアウト設定の詳細を参照してください。
4. 対話型コマンドに使う場合の注意
パスワードを求める SSH やsudo のような対話型コマンドは、timeout ではなく SSH の
ConnectTimeout オプションなど専用の設定を使うのが適切です。# SSH接続のタイムアウトは -o ConnectTimeout が正しい ssh -o ConnectTimeout=10 user@192.0.2.10 "コマンド" # コマンド全体に上限をかけたい場合は timeout との組み合わせも有効 timeout 60 ssh -o ConnectTimeout=10 user@192.0.2.10 "バッチ処理.sh"
トラブルシュート|よくある問題と対処法
「タイムアウトしているはずなのにプロセスが残る」
SIGTERM を無視するプロセスや、子プロセスを生成して制御が分散している場合に起きます。--kill-after を必ず併用してください。それでも残る場合は、
setsid でプロセスグループリーダーにしてから timeout を実行すると効果的です。# setsid でプロセスグループをまとめて timeout にかける timeout --kill-after=5 30 setsid コマンド # プロセスが残っているか確認(ss / lsof でポートを確認するのも有効) ss -tlnp | grep ポート番号
「timeout: failed to run command: No such file or directory」
コマンド名のスペルミス、またはコマンドが PATH に含まれていないことが原因です。# コマンドが存在するか確認する which コマンド名 type コマンド名 # 絶対パスで指定する timeout 30 /usr/local/bin/myscript.sh
「古いシステムで timeout コマンドが見つからない」
timeout は coreutils 7.0 以降(2009年リリース)に含まれます。RHEL 6 以前など古い環境では未インストールの場合があります。
# インストール確認(RHEL/Rocky 系) rpm -q coreutils # インストール確認(Ubuntu/Debian 系) dpkg -l coreutils # バージョン確認 timeout --version
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| 30秒でタイムアウトさせる | timeout 30 コマンド |
| 2分でタイムアウトさせる | timeout 2m コマンド |
| SIGTERM後10秒でSIGKILL | timeout --kill-after=10 30 コマンド |
| 終了コードでタイムアウト判定 | EXIT=$?; [ $EXIT -eq 124 ] |
| シグナル種別を指定する | timeout -s SIGKILL 10 コマンド |
| SSH接続タイムアウト(推奨) | ssh -o ConnectTimeout=10 user@host |
timeout コマンドをシェルスクリプトや cron ジョブに組み込んでおくことで、ハングアップが起きても影響を最小限に抑えられます。
シグナル処理の詳細についてはLinux 基本コマンドの解説もあわせて参考にしてください。
シェルスクリプトの書き方や、サーバー運用の「型」が身についていますか?
timeout コマンドひとつとっても、終了コードの読み方や --kill-after の使い所を知らなければ、ハングアップが起きたときに対処できません。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:inotifywaitコマンドでファイル変更をリアルタイム監視する方法|スクリプト自動化と実務活用も
- 前のページへ:trapコマンドでbashスクリプトのシグナルを捕捉・処理する方法|一時ファイル削除やエラー終了処理の実践例も
- この記事の属するカテゴリ:Linuxtips・シェルスクリプトへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます