\r\n\r\n
よし、これでパソコンが使えるぞ。timeoutコマンドで実行可能な最大時間を設定することにより、プロセスに時間制限を与えることができます。ここでは、このコマンドを使用して実行中のプログラムを制限するためのチュートリアルを紹介します。
timeoutコマンドは、プログラムの実行時間に制限をかけることができるコマンドですが、なぜそのようなことをしたいのでしょうか?
1つの状況として、プロセスの実行時間が正確に分かっている場合があります。一般的な使用例としては、ログファイルやデータキャプチャープログラムをタイムアウトさせて、ログファイルがハードディスクのスペースを執拗に占有しないようにすることが挙げられます。
また、あるプロセスがどのくらいの時間実行されるかわからないが、無期限に実行させたくないことがわかっている場合などもあります。実行中のプロセスを設定し、ターミナルウィンドウを最小化した後、そのことを忘れてしまう癖があるかもしれません。
一部のプログラム(たとえ簡単なユーティリティであっても)は、ネットワークの性能に影響を与えるレベルのネットワークトラフィックを生成する可能性があります。あるいは、ターゲットデバイスのリソースを占有し、パフォーマンスを低下させる可能性があります。(ピンさん、見てますよ)パソコンから離れているときに、これらのプログラムを長時間起動したままにしておくのはよくありません。
タイムアウトはGNUコアUtilsの一部なので、LinuxやUnix系OS(macOSなど)には組み込まれています。インストールするものは何もなく、そのまま使用できます。
ここでは、簡単な例をご紹介します。例えば、デフォルトのコマンドラインオプションを使用した場合、pingコマンドはCtrl+Cを押して停止するまで実行され続けます。中断しなければ、そのまま実行し続けます。
ping 192.168.4.28タイムアウトを使用することで、Pingがノンストップで実行され、ネットワークの帯域幅を消費し、Pingを受けたデバイスを困らせることがないようにすることができます。
次のコマンドは、タイムアウトを利用してPingを制限しています。
timeout 15 ping 192.168.4.2815秒後にタイムアウトが発生すると、Pingセッションを終了し、コマンドラインプロンプトに戻ります。
15の後に "s "をつける必要はないことに注意。タイムアウトは秒単位と仮定されている。"s "をつけてもいいが、実際には違いはない。
分、時間、日単位で時間値を使用する場合は、"m"、"h"、"d "を追加します。
Pingを3分間実行させるには、次のコマンドを使用します。
timeout 3m ping 192.168.4.28Pingは3分間実行され、その後タイムアウトしてPingセッションを停止します。
データキャプチャーのファイルによっては、すぐに容量が大きくなってしまうものもあります。これらのファイルが不格好になったり、サイズが怪しくなったりするのを防ぐために、キャプチャープログラムの実行時間を制限してください。
この例では、ネットワークトラフィックのキャプチャツールであるtcpdumpを使用しています。今回調査したテスト機では、ubuntulinuxとfedoralinuxにtcpdumpが既にインストールされていました。Manjaro LinuxとArch Linuxでは、以下のコマンドでインストールする必要がありました。
sudo pacman -Syu tcpdumptcpdumpのデフォルトのオプションを使って10秒間実行し、その出力を以下のコマンドを使ってcapture.txtというファイルにリダイレクトすることができます。
timeout 10 sudo tcpdump > capture.txt(tcpdumpには、キャプチャしたネットワークトラフィックをファイルに保存する独自のオプションがあります。(tcpdumpではなく、タイムアウトの話なので、これは速攻です)
tcpdumpがネットワークトラフィックのキャプチャを開始し、10秒待つ。10秒経ってもtcpdumpはキャプチャを続け、.txtのサイズは増え続けている。tcpdumpを停止するには、Ctrl+Cで素早く操作する必要があります。
capture.txtlsをチェックすると、数秒で209Kに増えている。
ls -lh capture.txt何が起きて、なぜタイムアウトでtcpdumpが止まらなかったのでしょうか?
全ては信号の関係です。
timeoutはプログラムを停止させたいとき、SIGTERMシグナルを送ります。これは、プログラムを終了するように丁重にお願いするものです。プログラムによっては、SIGTERMシグナルを無視することを選択する場合があります。このようなときは、timeoutにもう少し強引に指示する必要がある。
タイムアウトを要求することで、SIGKILLシグナルを送ることができるのです。
SIGKILLシグナルは「キャッチ、ブロック、無視」することができず、常に通過します。シーゲルには、このプログラムを止めるように頼む良識がない。シグキルはストップウォッチと箱を持って隅に隠れている。
s(シグナル)オプションで、タイムアウトにSIGKILLシグナルを送るように指示することができます。
timeout -s SIGKILL 10 sudo tcpdump > capture.txtこのとき、tcpdumpは10秒経過するとすぐに停止します。
SIGTERMを使ってプログラムを停止しようとするとタイムアウトを要求し、SIGTERMが機能しないときだけSIGKILLを送信することができます。
kは引数として時間値をとる。
このコマンドでは、dmesgを30秒間実行させ、その後SIGTERMシグナルで終了させるタイムアウトを要求しています。40秒後にdmesgがまだ実行されている場合、SIGTERMは無視され、timeoutはSIGKILLを送信してジョブを完了させる必要があります。
dmesg は、カーネルのリングバッファメッセージを監視し、ターミナルウィンドウに表示するユーティリティです。
timeout -k 40 30 dmseg -wdmesgは30秒間実行され、SIGTERMシグナルを受信すると停止します。
SIGKILLは常にターミナルウィンドウに「Killed」という一言の死亡記事を残すので、dmesgを停止させたのはSIGKILLではないことがわかります。これは実現しなかった。
お行儀の良いプログラムは、終了時にこの値をシェルに返します。これを終了コードといいます。一般的には、プログラムの実行中に問題が発生した場合に、シェル(またはプログラムを開始したプロセス)に伝えるために使用されます。
timeout はそれ自身の終了コードを提供しますが、私たちはおそらくそれを気にしないでしょう。私たちは、タイムアウト制御されたプロセスの終了コードにもっと興味を持つかもしれません。
このコマンドは、5秒間Pingを実行することができます。この記事のリサーチに使用したテストネットワークにあるNostromoというコンピュータにPingを打っています。
timeout 5 ping Nostromo.localこのコマンドは5秒間実行され、タイムアウトで終了します。その後、次のコマンドで終了コードを確認します。
echo $?終了コードは124で、これはSIGTERMでプログラムが終了したことを示すためにtimeoutが使用する値です。SIGKILLでプログラムが終了した場合、終了コードは137となる。
Ctrl+Cでプログラムを中断すると、タイムアウトの終了コードが0になります。
timeout 5 ping Nostromo.local echo $?タイムアウトが終了する前にプログラムの実行が終了した場合、タイムアウトはプログラムからの終了コードをシェルに戻すことができます。
そのためには、プログラムが自動的に停止すること(言い換えれば、タイムアウトで終了しないこと)、そして、-preserve status オプションを使用する必要があります。
もし、-c (count)オプションの値が5であれば、Pingは5つの要求しか送らない。タイムアウトの時間を1分にすれば、間違いなくPingは自動で終了します。そして、echoを使って終了値を確認することができます。
timeout --preserve-status 1m ping -c 5 Nostromo.local echo $?ping は 5 回の ping 要求を完了し、終了する。終了コードは 0 である。
この終了コードがpingによるものであることを確認するために、pingに強制的に別の終了コードを生成させてみましょう。存在しないIPアドレスにPingリクエストを送ろうとすると、Pingは失敗し、エラー終了コードが返されます。次に echo を使って、終了コードが 0 以外であることを確認します。
timeout --preserve-status 1m ping -c 5 NotHere.local echo $?pingコマンドは、明らかに存在しないデバイスに到達できないので、エラーを報告してシャットダウンします。終了コードは2です。これは、pingが一般的なエラーに対して使用する終了コードです。
タイムアウトは、実行中のプログラムに対して何らかの境界を設ける方法です。ログファイルがハードディスクから溢れたり、ネットワークツールの起動を忘れたりする恐れがある場合は、タイムアウトで包んで、コンピュータ自身に調整させるようにしましょう。