запускать цикл в первую секунду каждой минуты

Я использую для nicstat эту команду

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

эта команда создает файл журнала для каждых 60 секунд моего интерфейса Ethernet, проблема в том, что файлы не для каждой минуты часов, при запуске этой команды первый созданный файл журнала может быть чем-то вроде log-12: 00: 04.txt ", содержащим значения от второго числа 4 в этой минуте, заканчивающегося вторым числом 3 в следующую минуту " также, если он не был так точно уставлен в начале минуты, через некоторое время у меня начинают увеличиваться секунды, например, log-12: 14: 05.txt, затем через несколько минут log-12: 32: 06 ... и Т. Д.

Мне нужен файл для каждой минуты часов, содержащий значения для каждого цикла от 00 до 59, например: log-12: 00: 00.txt, log-12: 01: 00.txt, log-12: 02: 00. txt и т. д.

0
16.03.2017, 12:10
2 ответа

С 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 (а 60-я строка после 59 секунд с пометкой 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
  }'

На этот раз, за исключением первой строки без заголовка первого файла, каждая запись будет статистикой за прошедшее второе.

1
28.01.2020, 02:46

Если вам не нужна субсекундная точность, простым решением будет что-то вроде:

while true ; do 
    sleep $[ 60 - $(date +%s) % 60  ];
    do_something;
done
0
28.01.2020, 02:46

Теги

Похожие вопросы