Назад | Перейти на главную страницу

Задание Cron для обнаружения потери питания системы, возвращающее неверное время

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

Идея скрипта довольно проста, запишите временную метку в /tmp/powerlast.tmp. Если в следующий раз при запуске сценария промежуток времени будет больше 90 секунд, добавьте запись, используя значение $ powerlast, в файл powerfailure.csv.

Я получаю какие-то странные результаты, например, 24 декабря в 11:50 отключилась электрика, но сценарий говорит мне, что это произошло в 11:20 - это неправильно.

#!/bin/bash
powercsv=~/powerfailure.csv
powerlast=/tmp/powerlast.tmp
frequency=60                  # seconds
margin=$(($frequency+($frequency/2)))
if [ ! -f "$powercsv" ]; then
  echo "timestamp,weekofyear,dayofyear,day,date,month,year,hour,minute" > "$powercsv"
fi
if [ ! -f "$powerlast" ]; then
  echo "4133980799" > "$powerlast"
fi
last=$(($(cat "$powerlast"))) # seconds since epoch
now=$(($(date +%s)))          # seconds since epoch
lastdate=$(date -d @$last)
nowdate=$(date -d @$now)
if [ $now -lt $last ]; then
  # first run ever
  echo "$now" > "$powerlast"
else
  # aim is to detect gaps greater than the run frequency.
  # echo "margin $margin frequency $frequency"
  echo "$now" > "$powerlast"
  gap=$(($now-$last))
  if [ $gap -gt $margin ]; then
    echo "$nowdate: Power interruption detected at $lastdate! $gap exceeds $margin second limit."
    weekofyear=$(date -d @$last +%V)
    dayofyear=$(date -d @$last +%j)
    day=$(date -d @$last +%a)
    date=$(date -d @$last +%d)
    month=$(date -d @$last +%m)
    year=$(date -d @$last +%y)
    hour=$(date -d @$last +%H)
    minute=$(date -d @$last +%M)
    echo "$last,$weekofyear,$dayofyear,$day,$date,$month,$year,$hour,$minute" >> "$powercsv"
  fi
fi

Я запланировал запуск задачи * * * * * /home/usr/powerfailure/powerfailure.sh через crontab -e

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

$ grep  -Eo '^[0-9]+' /tmp/powerlast.tmp | while read x; do date -d @$x; done
Tue Dec 24 12:41:02 GMT 2019

Как ни странно, все мои записи, кажется, регистрируются примерно через 20 минут.

$ grep -Eo '^[0-9]+' powerfailure.csv | while read x; do date -d @$x; done
Fri Dec 20 13:03:02 GMT 2019
Sat Dec 21 10:18:01 GMT 2019
Sat Dec 21 11:18:02 GMT 2019
Sat Dec 21 19:20:02 GMT 2019
Sun Dec 22 02:19:01 GMT 2019
Mon Dec 23 14:21:02 GMT 2019
Tue Dec 24 07:20:02 GMT 2019
Tue Dec 24 11:20:01 GMT 2019

Я проверил / var / log / syslog и обнаружил там какой-то странный порядок меток времени, поэтому я думаю, что это может быть виновато, но я не знаю, почему он это делает.

Dec 24 11:45:01 raspberrypi CRON[9915]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)
Dec 24 11:46:02 raspberrypi CRON[9976]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)
Dec 24 11:47:01 raspberrypi CRON[10011]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)
Dec 24 11:17:46 raspberrypi cron[324]: (CRON) INFO (pidfile fd = 3)
Dec 24 11:17:46 raspberrypi cron[324]: (pi) ORPHAN (no passwd entry)
Dec 24 11:17:46 raspberrypi cron[324]: (CRON) INFO (Running @reboot jobs)
Dec 24 11:18:01 raspberrypi CRON[737]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)
Dec 24 11:19:01 raspberrypi CRON[1459]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)
Dec 24 11:20:01 raspberrypi CRON[2308]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)
Dec 24 11:20:01 raspberrypi CRON[2313]: (smmsp) CMD (test -x /etc/init.d/sendmail && test -x /usr/share/sendmail/sendmail && test -x /usr/lib/sm.bin/sendmail && /usr/share/sendmail/sendmail cron-msp)
Dec 24 11:52:35 raspberrypi CRON[3237]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)
Dec 24 11:53:01 raspberrypi CRON[3657]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)
Dec 24 11:54:01 raspberrypi CRON[4600]: (usr) CMD (/home/usr/powerfailure/powerfailure.sh)

Я переместил файл отслеживания из /tmp и изменил мой сценарий, чтобы использовать touch вместо. Теперь сценарий отслеживает дату изменения файла, а не его содержимое. Мне до сих пор неясно, почему она не работает так, как задумано, но эта система работает именно так, как задумано.

#!/bin/bash
powerdir=~/powerfailure
mkdir -p "$powerdir"
powercsv="$powerdir/powerfailure.csv"
powertouch="$powerdir/powerlast.touch"
frequency=60                  # seconds
margin=$(($frequency+($frequency/2)))
if [ ! -f "$powercsv" ]; then
  echo "timestamp,weekofyear,dayofyear,day,date,month,year,hour,minute" > "$powercsv"
fi
if [ ! -f "$powertouch" ]; then
  touch "$powertouch"
fi
last=$(date -r "$powertouch" +%s) # seconds since epoch
now=$(($(date +%s)))              # seconds since epoch
lastdate=$(date -d "@$last")
nowdate=$(date -d "@$now")
# echo "Last: $last, Now: $now, Last Date: $lastdate, Now Date: $nowdate"
if [ $now -lt $last ]; then
  # first run ever
  echo "$now" > "last"
  echo "Reset power last variable"
  echo "Reported: $(date)"
  echo "Last: '$last' -> $(date -d "@$last")"
  echo "Current: $now' -> $(date -d "@$now")"
else
  # aim is to detect gaps greater than the run frequency.
  # echo "margin $margin frequency $frequency"
  touch "$powertouch"
  gap=$(($now-$last))
  if [ $gap -gt $margin ]; then
    echo "Reported: $(date)"
    echo "Last: '$last' -> $(date -d "@$last")"
    echo "Current: '$now' -> $(date -d "@$now")"
    echo "$nowdate: Power interruption detected at $lastdate! $gap exceeds $margin second limit."
    weekofyear=$(date -d "@$last" +%V)
    dayofyear=$(date -d "@$last" +%j)
    day=$(date -d "@$last" +%a)
    date=$(date -d "@$last" +%d)
    month=$(date -d "@$last" +%m)
    year=$(date -d "@$last" +%y)
    hour=$(date -d "@$last" +%H)
    minute=$(date -d "@$last" +%M)
    echo "$last,$weekofyear,$dayofyear,$day,$date,$month,$year,$hour,$minute" >> "$powercsv"
  fi
fi