Bash
用於檢測系統電源何時失去返回無效計時的 Cron 作業
我們的電子設備出現問題,因此我編寫了一個簡單的 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