この質問にはすでに答えがあります:
特定のコマンド(でのみ終了可能Ctrl-C
)を5分間自動的に実行する簡単な方法はありますか?
例えば:
minute-command 5-minutes ping www.google.com
または、それ自体を終了しないその他のコマンド。
5分だけでなく、制限時間を指定できるようにしたいと思います。
この質問にはすでに答えがあります:
特定のコマンド(でのみ終了可能Ctrl-C
)を5分間自動的に実行する簡単な方法はありますか?
例えば:
minute-command 5-minutes ping www.google.com
または、それ自体を終了しないその他のコマンド。
5分だけでなく、制限時間を指定できるようにしたいと思います。
回答:
この機能を提供する(少なくとも)2つのプログラムがあります。
名前
timelimit
—プロセスの絶対実行時間を効果的に制限するあらすじ
timelimit [-pq] [-S killsig] [-s warnsig] [-T killtime] [-t warntime] command [arguments ...]
そして
名前
timeout
-時間制限付きでコマンドを実行するあらすじ
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
次のようにパッケージ化されています。
$ dlocate `which timeout timelimit`
timelimit: /usr/bin/timelimit
coreutils: /usr/bin/timeout
/-----------------------------+------------+----------------\
| Feature | timelimit | timeout |
+=============================+============+================+
| time to run | -t time | first argument |
+-----------------------------+------------+----------------+
| terminate signal | -s signal | -s signal |
+-----------------------------+------------+----------------+
| grace period | -T time | -k time |
+-----------------------------+------------+----------------+
| kill signal | -S signal | (note 1) |
+-----------------------------+------------+----------------+
| propagate signals | -p | (note 2) |
\-----------------------------+------------+----------------/
ノート:
timeout
常にSIGKILL
最後のリゾート信号として使用します。timeout
子プログラムがそうするときにシグナルで終了する機能はありません。2つのプログラムの終了ステータスは異なりますが、きちんと要約するのは難しいので、マニュアルページを参照してください。
timeout
(デフォルトでは、複数のシステムにインストールされているcoreutils
多くのディストリビューションで標準パッケージです)、私はあなたがない限り、あなたはで提供される特別な機能を必要とすることを使用することをお勧めtimelimit
。
timelimit
。参照してください。私はプロセスを強制終了し、PIDが再利用されていないことを確認することができますどのようにそれらとGNUのタイムアウトの詳細は。
timeout
ているため、そこに行く方法です。
実際には、これは何のtimeout
ためです:
TIMEOUT(1) User Commands TIMEOUT(1)
NAME
timeout - run a command with a time limit
SYNOPSIS
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
DESCRIPTION
Start COMMAND, and kill it if still running after DURATION.
lx@lxtp:~$ dpkg -S /usr/bin/timeout
coreutils: /usr/bin/timeout
bash
なしの純粋な組み込みこのソリューションは、外部の実行可能ファイルを呼び出すことなくbash
、組み込みコマンドに依存して機能することがわかりました。最終的にcoreutils がインストールされていないシステムでも動作します[ 1 ]
YourCommand & read -t 300 ; kill $! # 1st version
YourCommand & read -t 300 || kill $! # 2nd version
説明:あなたがしてバックグラウンドでコマンドを送信するときにいつものように&
、そのPIDは内部変数に格納されている$!
(の現代版に存在しますdash
、csh
、bash
、tcsh
、zsh
...)。
シェル間で実際に違いを生じるのは、組み込みコマンドread
[ 2 ]とオプションの存在-t
です。最初のバージョンでは、指定された秒数が経過する前にユーザーが入力行を完了しない場合、命令は終了し、エラー戻りコードが生成されます。
-t TIMEOUT 入力の完全な行がTIMEOUT秒以内に読み取られない場合、読み取りをタイムアウトさせ、失敗を返します。
2番目のバージョンは1番目として機能しますが、を押すだけで強制終了タイムアウトを中止できますenter。
実際、or演算子||
は、タイムアウトが期限切れになったときなど、コマンドがゼロ以外のリターンコードで終了したkill
場合にのみステートメントを実行read
します。enterその瞬間の前に押すと、0を返し、以前のコマンドを強制終了しません。
ときcoreutilsのは、あなたのシステム上に存在していると、あなたは外部プログラムを呼び出すための時間とリソースを節約する必要がない、 timeout
そしてsleep
、あなたの目標に到達するための両方の最適な方法があります。
timeout
の使用timeout
は簡単です。
最終的に-k
、最初の障害が発生した場合に追加の強制終了信号を送信するオプションも使用することを検討できます。
timeout 5m YourCommand # 3rd version
sleep
ではsleep
、あなたの空想を使用するか、いくつかのインスピレーションを取ることができます[ 3 ]。コマンドをバックグラウンドまたはフォアグラウンドで残すことができることに注意してください(たとえばtop
、通常はフォアグラウンドにする必要があります)。
YourCommand & sleep 5m; kill $! # 4th Background
YourCommand & pid=$! ; (sleep 5m; kill $pid;) & # 5th Background
bash -c '(sleep 5m; kill $$) & exec YourCommand' # 6th Foreground
(cmdpid=$BASHPID; (sleep 5m; kill $cmdpid) & exec YourCommand) # 7th Foreground
説明
YourCommand
シェルを実行しますsleep
。終了すると、最後のバックグラウンドプロセス($!
)が強制終了されます。シェルを停止します。
YourCommand
で実行し、そのPIDをすぐに変数に保存します$pid
。次に、バックグラウンドで5分の仮眠を実行し、その結果としてコマンドが保存されたPIDを強制終了します。このコマンドグループをバックグラウンドで送信したため、シェルを停止することはありません。$!
バックグラウンドで別のプログラムを最終的に実行することでの値を更新できるため、PIDを変数に保存する必要があります。簡単に言えば、間違ったプロセスを殺したり、プロセスをまったく殺したりするリスクを回避できます。
$$
。その後、フォアグラウンドに残っているコマンドが実行されます。 ()
、PIDを変数に保存するサブシェルが呼び出され(cmdpid
)、バックグラウンド実行で送信された別のサブシェルで自分自身を強制終了し、フォアグラウンドでYourCommandを実行します。
もちろん、各バージョンでは、必要なキル信号を送信することができます。デフォルトから極端な ものまで、kill -9
本当に必要な場合にのみ使用されます。
参照資料
特定の場合、ping
サポートのほとんどの実装、-c
または--count
特定の数のpingの後に終了します。
ping -c 300 host.example.com
より一般的な解決策については、他の回答を参照してください。
ping
具体的な例のために提供された印象OPを取得します。彼は、すべての異なるプログラムに対して個別の解決策を望んでいません。
次のような簡単なスクリプトでそれを行うことができます。
#!/bin/bash
#
# $1 is the time to let the program run, and $2, $3, ... are the command itself.
#
"${@:2}" &
PID=$!
sleep "${@:1:1}"
kill -2 $PID
(下のコメントのMatija Nalisの提案に従って、シグナルSIGINT = 2を使用)。
(珍しい?)bash式の説明$@:...
:位置パラメータ($*, $@, "$*", "$@"
)は、たとえば次の追加の仕様を認めます。
"${@:START:COUNT}"
つまり、すべてのパラメータのうち、COUNT個を取得します。最初に取得するパラメータは、START番目の位置のものです。COUNTが省略された場合、START番目の位置から始めて、最後まですべてを取ります。それ$0
がプログラム名であることを忘れないでください。STARTが負の場合、最後からカウントを開始し、COUNT は負にできないため、最後の引数はであることに注意してください"${@:-1}"
。また、ほぼ常に二重引用符内に位置パラメータを含めます。
$1
はかなりつらいことです。また、あなたはちょうどsleep "$1"
または何かをすることができますcountdown
。
time=$1; shift
、を実行できます。その後、位置パラメーターの配列スライス構文は必要ありません。しかし、はい、それははるかに簡単です。
ctrl-c
、試してみるおそらくほうがよいkill -INT
の代わりにkill -9
(または少なくともしようと-9
、それは一時ファイルを残してきれいに終了しないようにプログラムチャンスを与える-最初のものはsuceedなかった場合、数秒後にのみなど)
ping
あなたの例で言及しているので、このコマンドには、特定の時間が経過した後に停止するいくつかのオプションがあります。
- w deadline送受信されたパケット数に関係なく、pingが終了する までのタイムアウトを秒単位で指定します。この場合、pingはカウントパケットが送信された後も停止せず、期限切れの期限が切れるか、カウントプローブが応答されるか、ネットワークからのエラー通知を待ちます。
- W timeout 応答を待つ時間(秒単位)。このオプションは、応答がない場合のタイムアウトのみに影響します。それ以外の場合、pingは2つのRTTを待機します。