一定の時間が経過した後にコマンドを実行しますか?


23

長いプロセスを実行している場合、時間ベースのコマンドを実行する方法はありますか?

たとえば、約10分間実行される非常に長いプロセスを実行しています。

5分後、別のコマンドを実行したいと思います。例として、個別のコマンドは次のようになります。echo 5 minutes complete

(注:コマンドの完了に向けて進行するのではなく、指定された間隔の後に実行されたコマンドのみが必要です。)

出来ますか?


1
ほとんどの場合、プロセスにかかる時間は事前にわかりません。
チョロバ

「時間ベースのコマンド」とはどういう意味ですか?進行状況バーを作成しますか?質問の現在の言い回しに基づいて、長時間実行されているコマンドをバックグラウンドに置いてから、システムクロックを表示できます。どうか明らかにしてください。
ワイルドカード

@Wildcard質問で明確にしました。プログレスバーではありません。これは、いくつかの間隔の後にコマンドを実行します
Aniket Bhattacharyea

1
「5分完了」は反響する奇妙なことです。「5分経過していませんか?」「時は_____」ではありませんか?別の任意のコマンドが実行される前に、長時間実行されているコマンドが開始されてから指定された時間間隔が経過したことを確認したいだけですか?もしそうなら、なぜ単に実行しないのlongcommand & sleep 300 && command-to-do-after-five-minutesですか?(実際、おそらくあなたが探しているものです。)すぐに2つのclock-progress-bar実装を取得したため、説明が十分ではなかったことに注意してください。
ワイルドカード

回答:


29

ただ走れ:

long-command & sleep 300; do-this-after-five-minutes

do-this-after-five-minutes5分後に実行されます。long-commandバックグラウンドで実行されます。


10
私は通常を使用するsleep 5m && foobarため、気を変えて^ C theを変更するsleepと、次のコマンドは実行されません。
ピーターコーデス

@PeterCordes、たとえばsleep 3; lsand ^Cでテストしたとき、2番目のコマンドは実行されません。なぜ、そして非対話型のシェルでは異なる動作をするのか、本当にわかりませんか?
ワイルドカード

1
@PeterCordes完全ではありません-シェルごとに異なる場合を除きます。ときにsleep 5m && echo眠っているあなたは、サスペンド時に、唯一のsleepコマンドは中断されています。残りのコマンドラインは実行されますが、sleep中断されたため、正常に終了せず、その後の部分&&はスキップされます。中断してみてsleep 5 || echo hello、をhello押すと直接表示され^Zます。
hvd

1
@hvd:うん、あなたは正しい、そして私は再び間違っている>。<、bash4を使用して。どうやら&&がゲットーとして、アラームリマインダーのat(1)ようなもののsleep 30m && mplayer something.mp3ためsleep 90m && fgに、または後でディスク集約的なコマンドを再開するための方法であると決めてから、長すぎたようです。したがって、実際にsleep 5m && echo helloは、次のコマンドをまったく実行せずに^Z中断sleepするので便利です。スリープが終了する前でも、複合コマンド全体を一時停止/再開できるようにする場合は、を使用します( sleep 2 && echo hello )
ピーターコーデス

@hvd:この&&イディオムによりスリープの実行直後プロセスを強制終了しないことが確実になります(^Zaを危険にさらす代わりにコマンドを実行できないためです^C)。これは、再開されるコマンドが遅いものの途中である場合sleep && fgや、sleep && bgユースケースで役立ちます。
ピーターコーデス

5

次のスクリプトを使用できます。

#!/bin/bash

TEMPFILE="$(mktemp)"
STARTTIME="$(date +%s)"
(./longprocess; rm -f "$TEMPFILE") &
while [ -f "$TEMPFILE" ]; do
    sleep 1s
    NOW="$(date +%s)"
    if (( (NOW-STARTTIME) % 300 == 0 )); then
        echo "$(( (NOW-STARTTIME)/60 )) minute(s) elapsed"
    fi
done
echo "Done!!!"

を実行longprocessし、sub-shell以前に作成された「ロック」ファイルの存在を監視します。


2
を確認man bashSECONDSます。SECONDS=0スクリプトの開始時に設定し、300以上のみをチェックするか、スクリプトで設定しSECONDS=$((date +%s))date再度使用することを忘れることができます

@yeti、ヒントをありがとう、私はそれを知りませんでした。
セルジュ

@yeti、sleep 1s常に前よりも正確に1秒遅れた後の時間に依存したい場合sleep 1s... プログラマーが時間について信じているFalsehoodsの犠牲になりまし。(この場合でも、ハッシュマークの進行状況バーなどを表示することもできます。)
ワイルドカード

@Wildcard ...まったく言及sleepしませんでした!

@yeti、そうですね。についてのヒントをありがとうSECONDS!:)
ワイルドカード

4

これには1つのライナーがあります。

( ( sleep $TIMEOUT ; echo "5 minutes complete") & $COMMAND )

あなたの場合、TIMEOUT = 5mで、COMMANDは長いコマンドです。

この投稿への私の答えも参照してください'サービスネットワークの再起動'でのタイムアウト


フォアグラウンドでサブシェルを起動してからコマンドを実行すると、不必要に複雑になります。外側の括弧とexecを削除します。
グレンジャックマン

1
@glennjackmanこの方法により、CTRL + C(たとえば)をメイン(最も外側の)サブシェルに送信するプロシージャ全体を強制終了できます。
coffeMug

1
しかし、execを使用すると、サブシェルはもうありません。コマンドだけがあります。コマンドの親は、サブシェルをまったく使用していないかのように、スクリプトを実行するシェルです。
グレンジャックマン

3
#! /bin/bash

( sleep 4 ) & # <-- The long running process.

seconds=1
while jobs %1 &>/dev/null ; do
    echo $((seconds++)) seconds complete
    sleep 1    
done
echo Done.

jobs %1 ジョブ%1が停止すると失敗します。

時間が長くなると、$ secondsがリアルタイムと同期しなくなる可能性があることに注意してください。開始時間を保存し、実際の時間との差を計算する方が適切です。

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