在每分钟的第一秒开始循环运行

在每分钟的第一秒开始循环运行

我正在使用 nicstat 这个命令

while true; do nicstat -eth1 1 60 > log-$(date +%F-%T).txt; done

此命令为我的以太网接口每 60 秒创建日志文件,问题是文件不是每个时钟分钟的,运行此命令时创建的第一个日志文件可能类似于 log-12:00:04.txt ”包含这一分钟的第二个数字 4 的值,以下一分钟的第二个数字 3 结尾”,如果在一分钟开始时没有那么精确地盯着,过了一会儿我开始让秒数像 log-12:14 一样增加:05.txt,然后几分钟后 log-12:32:06 ...等等。

我需要每个时钟分钟的文件,其中包含从 00 到 59 的每个 secound 的值,例如:log-12:00:00.txt、log-12:01:00.txt、log-12:02:00.txt 等。

答案1

zsh

#! /bin/zsh -

zmodload zsh/datetime # for $EPOCHREALTIME/strftime...
zmodload zsh/zselect  # for sub-second sleeps
zmodload zsh/mathfunc # for int()

# wait till start of the next minute at first
for ((next = (EPOCHSECONDS / 60 + 1) * 60;; next += 60)) {
  (( sleep = int((next - $EPOCHREALTIME) * 100) ))
  (( sleep <= 0 )) || zselect -t $sleep
  strftime -s now %T $next
  nicstat -i eth1 1 60 > log-$now.txt &
}

我确实添加了异步&运行nicstat,假设nicstat 1 60运行时间略多于一分钟。然后,如果我们同步运行它(即没有&),它就会开始漂移。在这里,我们确保nicstat每分钟都开始。

然而,nicstat 1 60运行时间略多于 59 秒,而不是 60 秒,因为它显示的第一行不是 12:00:00 到 12:00:01 的统计信息,而是自启动以来的总体统计信息(或自上次重置统计信息以来) 。第二行(标记为12:00:01)是12:00:00到12:00:01的统计(59秒后的第60行标记为12:00:59是从12:00开始的统计:58 至 12:00:59)。

12:00:59 到 12:01:00 的统计数据将丢失。因此,您可能需要将其更改为nicstat 1 61,以便输出包含 61 行,第一行用于自启动以来的统计信息,接下来的 60 行用于该分钟内每秒的统计信息。

作为解决问题的另一种方法,您可以只运行一个nicstat并将awk其输出拆分为日志文件:

nicstat -i eth1 1 | awk '
  NR == 1 {header = $0; next}
  !/^[012]/ {next} # skip other headers
  {
    log = "log-" substr($0, 1, 6) "00.log"
    if (log != last_log) {
      if (last_log) close(last_log)
      print header > log
      last_log = log
    }
    print > log
  }'

这次,除了第一个文件的第一个非标题行之外,每个条目将是过去一秒的统计数据。

答案2

如果您不需要亚秒级精度,简单的解决方案如下:

while true ; do 
    sleep $[ 60 - $(date +%s) % 60  ];
    do_something;
done

相关内容