10秒ごとにコマンドを実行し、バックグラウンドで実行するようにしたい(したがってwatch
?を削除します)。すべての回答は次のように表示されますが、実行には11〜14秒かかります。これはどのように達成できますか?
while true; do
# perform command that takes between 1 and 4 seconds
sleep 10
done
答え1
どうですか?
( # 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
orkill
およびそれらの分離要件について心配する$!
前の外観は次のとおりです。
while true; do perform-command & sleep 10 ; done
残りは必要なときにすぐそこにあります。
答え2
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
答え3
BASHのみ - コマンドに費やされた時間を計算して10から減算することもできます。
TIMEFORMAT=$'%0R'
while true; do
T=$({ time command; } 2>&1)
sleep $(( 10-T ))
BASHの人々から:
TIMEFORMAT このパラメーターの値は、時刻予約語の先頭にあるパイプのタイミング情報の表示方法を指定する書式文字列として使用されます。 % 文字は、時間値やその他の情報に拡張されるエスケープシーケンスを紹介します。エスケープシーケンスとその意味は次のとおりです。中括弧はオプションの部分を表します。
%%リテラル%。
%[p][l]R 経過時間(秒)です。
%[p][l]U ユーザーモードで消費された CPU 時間 (秒)。
%[p][l]S システムモードで消費された CPU 時間 (秒)。
%P CPU パーセントで、 (%U + %S) / %R として計算されます。オプションのpは、精度、つまり小数点以下の桁数を指定する数値です。値が0の場合、小数点や小数は出力されません。