Как лучше всего выполнить сравнение временных меток в Bash

У меня есть сценарий оповещения, который я пытаюсь удержать от рассылки спама, поэтому я хотел бы поставить условие, что если оповещение было отправлено в течение, скажем, последнего часа, не отправлять другое оповещение. Теперь у меня есть задание cron, которое проверяет условие каждую минуту, потому что мне нужно быстро получать оповещения, когда условие выполняется, но мне не нужно получать электронное письмо каждую минуту, пока я не возьму проблему под контроль. Каков наилучший способ сравнить время в bash для этого?


person Ichorus    schedule 15.10.2008    source источник


Ответы (3)


Безусловно, проще всего хранить метки времени как время модификации фиктивных файлов. Команды GNU touch и date могут устанавливать/получать это время и выполнять вычисления даты. В Bash есть тесты для проверки того, является ли файл новее (-nt) или старше (-ot) другого.

Например, чтобы отправить уведомление, только если последнее уведомление было более часа назад:

touch -d '-1 hour' limit
if [ limit -nt last_notification ]; then
    #send notification...
    touch last_notification
fi
person Bruno De Fraine    schedule 15.10.2008
comment
Примечание. Я обнаружил, что -nt не работает, если между отметками времени нет разницы не менее 1 секунды. Чтобы проверить, был ли файл новым, я сравнил его с временным файлом, к которому прикасался. Я добавил туда sleep 1, чтобы учесть эту проблему -nt. Кажется, что это сравнение на самом деле является самым простым способом, но если вам не нравится мое предложение сна, вам может потребоваться более точное сравнение даты и времени в зависимости от ваших потребностей. - person BuvinJ; 16.11.2015
comment
Обратите внимание, что -nt является расширением POSIX: pubs.opengroup.org/onlinepubs/009695399 /утилиты/test.html - person Ciro Santilli 新疆再教育营六四事件ۍ 25.12.2018

Используйте «тест»:

if test file1 -nt file2; then
   # file1 is newer than file2
fi

РЕДАКТИРОВАТЬ: Если вы хотите узнать, когда произошло событие, вы можете использовать «касание», чтобы создать файл, который вы позже сможете сравнить с помощью «теста».

person JesperE    schedule 15.10.2008
comment
Спасибо, я не знал о бите -nt. Я мог бы создать файл при первом срабатывании предупреждения и удалить его, когда состояние восстановится (в этом случае я мог бы просто проверить его существование). Любая идея, как я мог бы реализовать бит «если прошло хотя бы час, снова выдать предупреждение»? - person Ichorus; 15.10.2008
comment
Я считаю, что @Bruno ответил на это. - person JesperE; 16.10.2008

Используйте команду даты, чтобы преобразовать два значения времени в стандартный формат и вычесть их. Вероятно, вы захотите сохранить предыдущее время выполнения в точечном файле, а затем сделать что-то вроде:

last = cat /tmp/.lastrun
curr = date '+%s'

diff = $(($curr - $last))
if [ $diff -gt 3600 ]; then
    # ...
fi

echo "$curr" >/tmp/.lastrun

(Спасибо, Стив.)

person jonathan-stafford    schedule 15.10.2008
comment
Почему бы просто не использовать секунды с начала эпохи (%s)? 3600 секунд в часе. - person Steve Baker; 15.10.2008
comment
Мне нравится этот метод, он не зависит от более новой версии bash. И Busybox может это сделать. - person Daniel YC Lin; 11.01.2013
comment
Я думаю, вам нужны обратные кавычки или $() в вашем звонке на сегодняшний день. - person harschware; 14.08.2014