警告:この回答のすべてのソリューション(1つを除く)は、リアルタイム(システム)クロックに基づいて進む整数秒カウンターに基づいているため、1秒早くksh
戻ることができます(ただし、含まれていません)。コードの実行がいつ開始されたかに基づきます。
bash
、、ソリューションksh
、zsh
特別なシェル変数を使用$SECONDS
:
@bsravaninの答えの少し簡略化されたバージョン。
大まかに言えば、$SECONDS
スクリプトでこれまでに経過した秒数が含まれます。
bash
で、システム(リアルタイム)クロックのパルスによって整数zsh
秒が進みます。つまり、舞台裏でのカウントは実際には(!)から始まりませんが、最後のフルタイム秒以降のどの部分でもスクリプトがたまたま開始されたか、変数がリセットされました。0
SECONDS
対照的に、期待どおりに動作します。実際には、リセットしたときにksh
カウントが開始されます。さらに、で小数秒を報告します。0
$SECONDS
$SECONDS
ksh
したがって、このソリューションが合理的に予測可能かつ正確に機能する唯一のシェルはですksh
。とは言うものの、大まかな測定とタイムアウトの場合は、とでまだ使用できる可能性がbash
ありzsh
ます。
注:以下はbash
シバンラインを使用しています。ksh
またはzsh
を置き換えるだけbash
で、これらのシェルでもスクリプトが実行されます。
#!/usr/bin/env bash
secs=3600 # Set interval (duration) in seconds.
SECONDS=0 # Reset $SECONDS; counting of seconds will (re)start from 0(-ish).
while (( SECONDS < secs )); do # Loop until interval has elapsed.
# ...
done
Ubuntuの()sh
などのPOSIX機能のみのシェルのソリューション( POSIXに準拠していません)dash
$SECONDS
@dcpomeroの回答のクリーンアップバージョン。
によって返されるエポック時間date +%s
(1970年1月1日から経過した秒数)と条件付きのPOSIX構文を使用します。
警告:date +%s
それ自体(具体的には%s
フォーマット)はPOSIXに準拠していませんが、(少なくとも)Linux、FreeBSD、およびOSXで動作します。
#!/bin/sh
secs=3600 # Set interval (duration) in seconds.
endTime=$(( $(date +%s) + secs )) # Calculate end time.
while [ $(date +%s) -lt $endTime ]; do # Loop until interval has elapsed.
# ...
done