コマンドを5分間実行する簡単な方法は何ですか?[複製]


66

この質問にはすでに答えがあります:

特定のコマンド(でのみ終了可能Ctrl-C)を5分間自動的に実行する簡単な方法はありますか?

例えば:

minute-command 5-minutes ping www.google.com

または、それ自体を終了しないその他のコマンド。

5分だけでなく、制限時間を指定できるようにしたいと思います。

回答:


67

この機能を提供する(少なくとも)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)       |
\-----------------------------+------------+----------------/

ノート:

  1. timeout常にSIGKILL最後のリゾート信号として使用します。
  2. timeout 子プログラムがそうするときにシグナルで終了する機能はありません。

2つのプログラムの終了ステータスは異なりますが、きちんと要約するのは難しいので、マニュアルページを参照してください。

timeout(デフォルトでは、複数のシステムにインストールされているcoreutils多くのディストリビューションで標準パッケージです)、私はあなたがない限り、あなたはで提供される特別な機能を必要とすることを使用することをお勧めtimelimit


10
なぜあなたはもう一方ではなく一方を使用するのですか
ブライスM.デンプシー

2
@ BriceM.Dempseyローカルマシンにはタイムアウトが存在しますが、timelimitは存在しません(ただし、リポジトリから利用可能です)。そのため、それらの1つがプリインストールされている場合...それとは別に、メソッドシグネチャを見るだけで、それらは異なることを実行し、異なるユースケースを持っていることがわかります。
ベヌバード

の少なくとも2つの実装が存在することに注意してくださいtimelimit。参照してください。私はプロセスを強制終了し、PIDが再利用されていないことを確認することができますどのようにそれらとGNUのタイムアウトの詳細は。
sch

1
@ BriceM.Dempsey timeoutはGNU coreutilsに含まれていますが、含まれてtimelimitいません。なし、一方、または両方をインストールできます。2番目については、timelimitがコマンドを実行し、指定されたシグナルで指定された時間後に生成されたプロセスを終了すると報告されています。最初「警告」シグナルが送信され、次にタイムアウト後に「init」(8)がシャットダウン時に動作するのと同様の「キル」シグナルが送信されます。そのため、途中で動作が異なります。
ハスター

GNU coreutilsはすべてのGNU / Linuxにプリインストールされtimeoutているため、そこに行く方法です。
rexkogitans

87

実際には、これは何の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

16

coreutilsbashなしの純粋な組み込み

このソリューションは、外部の実行可能ファイルを呼び出すことなくbash組み込みコマンドに依存して機能することがわかりました。最終的にcoreutils がインストールされていないシステムでも動作します[ 1 ]

YourCommand & read -t 300 ;  kill $!                           # 1st version
YourCommand & read -t 300 || kill $!                           # 2nd version 

説明:あなたがしてバックグラウンドでコマンドを送信するときにいつものように&、そのPIDは内部変数に格納されている$!(の現代版に存在しますdashcshbashtcshzsh...)。
シェル間で実際に違いを生じるのは、組み込みコマンドread[ 2 ]とオプションの存在-tです。最初のバージョンでは、指定された秒数が経過する前にユーザーが入力行を完了しない場合、命令は終了し、エラー戻りコードが生成されます。

-t TIMEOUT 入力の完全な行がTIMEOUT秒以内に読み取られない場合、読み取りをタイムアウトさせ、失敗を返します。

2番目のバージョンは1番目として機能しますが、を押すだけで強制終了タイムアウトを中止できますenter
実際、or演算子||は、タイムアウトが期限切れになったときなど、コマンドがゼロ以外のリターンコードで終了したkill場合にのみステートメントを実行readします。enterその瞬間の前に押すと、0を返し、以前のコマンドを強制終了しません。


Coreutilsソリューション[ 1 ]

とき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

説明

  • 4番目のバージョンでは、バックグラウンドで実行してから、5分間YourCommandシェルを実行しますsleep。終了すると、最後のバックグラウンドプロセス($!)が強制終了されます。シェルを停止します。
  • 5番目のバージョンでは、代わりにバックグラウンドYourCommandで実行し、そのPIDをすぐに変数に保存します$pid。次に、バックグラウンドで5分の仮眠を実行し、その結果としてコマンドが保存されたPIDを強制終了します。このコマンドグループをバックグラウンドで送信したため、シェルを停止することはありません。$!バックグラウンドで別のプログラムを最終的に実行することでの値を更新できるため、PIDを変数に保存する必要があります。簡単に言えば、間違ったプロセスを殺したり、プロセスをまったく殺したりするリスクを回避できます。
  • 6番目のバージョンでは、新しいbashシェルと呼ばれ、を介して5分で自殺します$$。その後、フォアグラウンドに残っているコマンドが実行されます。
  • 7番目のバージョンでは()、PIDを変数に保存するサブシェルが呼び出され(cmdpid)、バックグラウンド実行で送信された別のサブシェルで自分自身を強制終了し、フォアグラウンドでYourCommandを実行します。

もちろん、各バージョンでは、必要なキル信号を送信することができます。デフォルトから極端な ものまで、kill -9本当に必要な場合にのみ使用されます。

参照資料

  • [ 1 ] Coreutils
  • [ 2 ] Bash初心者ガイド
  • [ 3 ] BashFAQ

2
「睡眠があれば、ファンタジーを使ったり、インスピレーションを得ることができます[Bash FAQへのリンク]」+ 1 #thatsenoughinternetfortoday
joeytwiddle

11

特定の場合、pingサポートのほとんどの実装、-cまたは--count特定の数のpingの後に終了します。

ping -c 300 host.example.com

より一般的な解決策については、他の回答を参照してください。


7
ping具体的な例のために提供された印象OPを取得します。彼は、すべての異なるプログラムに対して個別の解決策を望んでいません。
user1717828

8

次のような簡単なスクリプトでそれを行うことができます。

#!/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
おそらく最初または最後の引数として時間を取り、コマンドとして他のすべての引数を実行するようにスクリプトを設計します。bashを単語分割するの$1はかなりつらいことです。また、あなたはちょうどsleep "$1"または何かをすることができますcountdown
ピーターコーデス

1
@PeterCordes完了、お望み通り。
MariusMatutiae

最初の引数の時間を使用するとtime=$1; shift、を実行できます。その後、位置パラメーターの配列スライス構文は必要ありません。しかし、はい、それははるかに簡単です。
ピーター

1
@PeterCordesは同意しましたが、あなたは私がこれを行うより安全な方法を知っていて怠けていたのか、それとも無知であるのかを尋ねました。笑。
MariusMatutiae

特異的に遮断することができるプログラムについて尋ねポスターとしてctrl-c、試してみるおそらくほうがよいkill -INTの代わりにkill -9(または少なくともしようと-9、それは一時ファイルを残してきれいに終了しないようにプログラムチャンスを与える-最初のものはsuceedなかった場合、数秒後にのみなど)
マティヤナリス

5

pingあなたの例で言及しているので、このコマンドには、特定の時間が経過した後に停止するいくつかのオプションがあります。

  • w deadline送受信されたパケット数に関係なく、pingが終了する までのタイムアウトを秒単位で指定します。この場合、pingカウントパケットが送信された後も停止せず、期限切れの期限が切れるか、カウントプローブが応答されるか、ネットワークからのエラー通知を待ちます。
  • W timeout 応答を待つ時間(秒単位)。このオプションは、応答がない場合のタイムアウトのみに影響します。それ以外の場合、pingは2つのRTTを待機します

man ping

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.