Bash

用於檢測系統電源何時失去返回無效計時的 Cron 作業

  • January 8, 2020

我們的電子設備出現問題,因此我編寫了一個簡單的 bash 腳本來嘗試記錄事件發生的時間。我創建了一個每分鐘執行一次的 cron 作業來執行腳本。

腳本的構想很簡單,將時間戳寫入/tmp/powerlast.tmp。如果下次腳本執行時,時間間隔大於 90 秒,則將使用 $powerlast 值的條目附加到 powerfailure.csv 文件。

我得到了一些奇怪的結果,例如,在 12 月 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

引用自:https://serverfault.com/questions/996658