web-dev-qa-db-ja.com

X秒ごとにコマンドを実行する

コマンドを10秒ごとに実行し、それをバックグラウンドで実行したい(それにより、watch?が削除されます)。すべての回答は次のようなものを示していますが、これは常に11〜14秒実行されます。どうすればこれを達成できますか?

while true; do
    # perform command that takes between 1 and 4 seconds
    sleep 10
done
10
user1032531

どうですか:

( # In a subshell, for isolation, protecting $!
  while true; do
    perform-command & # in the background
    sleep 10 ;
    ### If you want to wait for a perform-command
    ### that happens to run for more than ten seconds,
    ### uncomment the following line:
    # wait $! ;
    ### If you prefer to kill a perform-command
    ### that happens to run for more than ten seconds,
    ### uncomment the following line instead:
    # kill $! ;
    ### (If you prefer to ignore it, uncomment neither.)
  done
)

ETA:これらすべてのコメント、代替案、および追加の保護のためのサブシェルを使用すると、当初よりもはるかに複雑に見えます。ですから、比較のために、waitまたはkillについて心配するようになる前の様子を、$!および分離の必要性:

while true; do perform-command & sleep 10 ; done

残りは本当に必要なときだけです。

16
The Sidhekin

bashzsh、またはkshでは、次のようなことができます。

SECONDS=0
while   command
do      sleep "$((10-(SECONDS%10)))"
done

bashマニュアルは$SECONDSについて次のように述べています。

$SECONDS

  • このパラメーターが参照されるたびに、シェルの呼び出しからの秒数が返されます。 $SECONDSに値が割り当てられている場合、以降の参照で返される値は、割り当てからの秒数と割り当てられた値です。 $SECONDSunsetの場合、その後リセットしても、特別なプロパティは失われます。

これが実際の例です:

(   SECONDS=0
    while   sleep   "$((RANDOM%10))"
    do      sleep   "$((10-(SECONDS%10)))"
            echo    "$SECONDS"
    done
)

10
20
30
40
50
60
70
80
90
100
9
mikeserv

BASHのみ-コマンドで費やした時間を計算し、10から引くこともできます。

TIMEFORMAT=$'%0R'
while true; do
    T=$({ time command; } 2>&1)
    sleep $(( 10-T ))

バッシュマンから:

TIMEFORMATこのパラメーターの値は、時間予約語が前に付いたパイプラインのタイミング情報の表示方法を指定するフォーマット文字列として使用されます。 %文字は、時間値またはその他の情報に展開されるエスケープシーケンスを導入します。エスケープシーケンスとその意味は次のとおりです。中括弧はオプションの部分を示します。
%%リテラル%。
%[p] [l] R秒単位の経過時間。
%[p] [l] Uユーザーモードで費やされたCPU秒数。
%[p] [l] Sシステムモードで費やされたCPU秒数。
%P(%U +%S)/%Rとして計算されるCPUパーセンテージ。

オプションのpは、精度、つまり小数点以下の小数桁数を指定する数字です。値が0の場合、小数点や小数は出力されません。

3
Dani_l