コマンドを10秒ごとに実行し、それをバックグラウンドで実行したい(それによってwatch
?を削除したい)。すべての回答は次のようなものを示していますが、これは常に11〜14秒実行されます。どうすればこれを達成できますか?
while true; do
# perform command that takes between 1 and 4 seconds
sleep 10
done
コマンドを10秒ごとに実行し、それをバックグラウンドで実行したい(それによってwatch
?を削除したい)。すべての回答は次のようなものを示していますが、これは常に11〜14秒実行されます。どうすればこれを達成できますか?
while true; do
# perform command that takes between 1 and 4 seconds
sleep 10
done
回答:
どうですか:
( # 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
残りは本当に必要なときだけです。
$!
「最後にバックグラウンドに配置されたジョブのプロセスIDに展開されます」とあり、バックグラウンドにsleep
は配置されないため、そうではありません。:)
あなたには、次のような何かを行うことができbash
、zsh
またはksh
:
SECONDS=0
while command
do sleep "$((10-(SECONDS%10)))"
done
これはbash
マニュアルが言っていること$SECONDS
です:
$SECONDS
- このパラメーターが参照されるたびに、シェルの呼び出しからの秒数が返されます。に値が割り当てられている場合、
$SECONDS
以降の参照で返される値は、割り当てからの秒数と割り当てられた値です。場合$SECONDS
でunset
、それがその後にリセットされている場合でも、その特殊な性質を失います。
これが実際の例です:
( SECONDS=0
while sleep "$((RANDOM%10))"
do sleep "$((10-(SECONDS%10)))"
echo "$SECONDS"
done
)
10
20
30
40
50
60
70
80
90
100
SECONDS
は、を実行してくださいsleep "$((10-(($SECONDS-$start_time)%10)))"
。start_time=$SECONDS
ループの前に行う必要があります。
SECONDS
。最新の編集のようにサブシェルを生成することでも、この問題を回避できます。
while true
ループに関するものだったので、シェルの状態がそれを乗り越えると予想されるとは思いませんでした。とにかく、そのようなループを独自のコンテキストでラップすることは、通常、ベストプラクティスです。そのような状況で、私はより多くのためにそうすることを懸念するだろうtrap
「のよりsの日本酒$SECONDS
が、酒」。
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 CPUの割合。(%U +%S)/%Rで計算されます。オプションのpは、精度、小数点以下の小数桁数を指定する数字です。値が0の場合、小数点や小数は出力されません。