Bash脚本迭代一个特定的时间范围,一次一秒

时间:2018-03-11 20:26:07

标签: bash timestamp

我试图在bash中创建某种循环,它将迭代特定的时间范围,一次一秒。

在每个时间间隔,它将执行该时间戳I.e.的任务。 " Wed Mar 2 12:00:03 CDT 2018"

我很难绕过如何制作一个每秒钟迭代一次的循环,当它达到60秒时,更新分钟等等。

思考?这看起来很明显,但正确的语法让我感到厌烦。

3 个答案:

答案 0 :(得分:0)

这是一种方法,将时间计算委托给date

$ for i in {1..10}; do date -d "+$i seconds"; done

Sun Mar 11 20:40:57 UTC 2018
Sun Mar 11 20:40:58 UTC 2018
Sun Mar 11 20:40:59 UTC 2018
Sun Mar 11 20:41:00 UTC 2018
Sun Mar 11 20:41:01 UTC 2018
Sun Mar 11 20:41:02 UTC 2018
Sun Mar 11 20:41:03 UTC 2018
Sun Mar 11 20:41:04 UTC 2018
Sun Mar 11 20:41:05 UTC 2018
Sun Mar 11 20:41:06 UTC 2018
Sun Mar 11 20:41:07 UTC 2018

如果要迭代一定时间,请将for循环更改为while循环和计数器。

答案 1 :(得分:0)

要制作一个时间循环,您需要以可比较的方式格式化日期/时间。最简单的技巧是将日期转换为看似整数的东西,然后使用ltleeqgtge运算符bash。

考虑一下:

$ date
Mon Mar 12 00:16:29 EET 2018 #this format/data type is not comparable by bash
$ date +%Y%m%d%H%M%S
20180312001629 #this is an integer representing the current time

这是从现在到特定时间点的示例循环:

stop=$(date +%Y%m%d%H%M%S --date "2018-03-12 00:20:55")
while [[ $(date +%Y%m%d%H%M%S) -le $stop ]];do #comparing current date & time with stop date & time
echo "date now is $(date)";
sleep 1;      #sleep 1 second
done

date now is Mon Mar 12 00:20:51 EET 2018
date now is Mon Mar 12 00:20:52 EET 2018
date now is Mon Mar 12 00:20:53 EET 2018
date now is Mon Mar 12 00:20:54 EET 2018
date now is Mon Mar 12 00:20:55 EET 2018

这里的诀窍是命令

stop=$(date +%Y%m%d%H%M%S --date "2018-03-12 00:20:55")

将给定日期(使用--date标志)转换为一种整数格式。

然后while循环会将同一整数格式的当前datestop日期进行比较。

这是一个类似的脚本,可以在特定时间开始/停止,但它有点“资源饥饿”#34;因为它不断地将当前时间与开始时间进行比较:

date;             #just print the current date & time
compl=false;
start=$(date +%Y%m%d%H%M%S --date "2018-03-12 01:45:50");
stop=$(date +%Y%m%d%H%M%S --date "2018-03-12 01:45:55");
while true;do 
 while [[ $(date +%Y%m%d%H%M%S) -ge $start ]] && [[ $(date +%Y%m%d%H%M%S) -le $stop ]];do 
  echo "date now is $(date)";
  sleep 1;
  compl=true;
 done;
 ($compl) && break;
done

Mon Mar 12 01:45:37 EET 2018
date now is Mon Mar 12 01:45:50 EET 2018
date now is Mon Mar 12 01:45:51 EET 2018
date now is Mon Mar 12 01:45:52 EET 2018
date now is Mon Mar 12 01:45:53 EET 2018
date now is Mon Mar 12 01:45:54 EET 2018
date now is Mon Mar 12 01:45:55 EET 2018

在特定时间启动/停止脚本的替代方法是使用纪元日期/纪元秒 纪元日期是自纪元(1970-01-01 UTC)以来的秒数 每个日期都可以使用格式date +%s表示为纪元秒数。

date                         #just print the current date & time
start="2018-03-12 02:17:52"
stop="2018-03-12 02:17:57"
timerequired=$(( $(date +%s --date "$start") - $(date +%s) ))
sleep $(($timerequired))     #sleep till the starting time 
while [[ $(date +%s) -le $(date +%s --date "$stop") ]];do 
  echo "date now is $(date)";
  sleep 1;
done

Mon Mar 12 02:17:39 EET 2018
date now is Mon Mar 12 02:17:52 EET 2018
date now is Mon Mar 12 02:17:53 EET 2018
date now is Mon Mar 12 02:17:54 EET 2018
date now is Mon Mar 12 02:17:55 EET 2018
date now is Mon Mar 12 02:17:56 EET 2018
date now is Mon Mar 12 02:17:57 EET 2018

最后,您可以使用外部工具根据日期和时间自动执行操作。时间如cronanacronat

答案 2 :(得分:0)

回显范围内每秒的日期:

from=$(date -d "Wed Mar 2 12:59:58 CDT 2018" +%s) 
to=$(date -d "Wed Mar 2 13:00:04 CDT 2018" +%s) 
for s in $(seq $from $to); do echo $(date -d @$s); done

date -d将日期良好的日期作为输入。 +%s将其格式化为自纪元以来的秒数。所以你得到两个大的值,比如from = 1520013598,to = ... 3604。 date -d @1520013598将时间戳转换回人类可读日期。

你的范围可能在变量中,例如start和stop,你可能想要foobar($ time)而不是回应它:

start="Wed Mar 2 12:59:58 CDT 2018"
stop="Wed Mar 2 13:00:04 CDT 2018"
from=$(date -d "$start" +%s) 
to=$(date -d "$stop" +%s) 
for s in $(seq $from $to)
do
    timestamp=$(date -d @$s)
    foobar $timestamp
done