[技術筆記] 在Raspberry Pi OS自動排程Crontab注意事項

近期因為幫某中心進行機房溫溼度監控的狀態

利用了之前買來的Raspberry Pi Zero W搭配DHT22溫濕度作為整個監控的架構

搭配了Cacati這個網頁式架構的流量監控、圖表介面,作為他們隨時想查看的網頁介面

另外也串接了LINE Notify作為當溫濕度異常時,發送通知到LINE群組裡面去

基本上整個程式預期是以每分鐘執行一次的方式進行

程式基本以python作為開發語言

排程方法基本上就是以新增Crontab的方式進行

一是將DHT22讀到的值轉存到另一個Cacti可以讀取的檔案格式

二是將讀到資料依照日期新增csv檔案,每個檔案去紀錄每分鐘的溫溼度值

並且用while的方式去跑

但想一想,依該是用Crontab排程的方式去解決,也沒必要Hold一個python一值在那邊跑,然後用sleep睡60秒再來一次

但遇到的問題在於已經設定crontab每分鐘要進行一次

shell腳本也寫好但是卻無法正確執行(後來發現根本沒執行)

但直接執行shell腳本卻一切照我的想法走

找了許久,有許多的方向,最後敗在crontab的shell預設環境並不是我shell腳本用的bash shell問題,以及crontab的排程到底是要排在哪個地方

以下就基本解釋一下crontab各種不同與最後我解決的方法

Crontab排程

以第一直覺來說,大家的直覺指令依該會是

sudo crontab -e

但基本上這個是最高權限者,以root的權限去做想做的事情,但基本上不建議使用這個方法,除非要動到重開機(需要sudo權限的動作)才需要

時間間隔設定上

他會以

min hour dom month dow command

分別是:分鐘、小時、幾號、月、星期幾以及最後要執行的指令

並且這邊指令的部分就不需要多輸入sudo

如果非需要最高權限的部分,則通常指令是

sudo crontab -u user -e

並且文件你會發現,要設定的改為

min hour dom month dow user command

可以指定是由哪個使用者執行什麼指令

但當初我不管怎麼設定都無法正常作動

最後是改以修改/etc裡面的crontab

sudo nano /etc/crontab

其設定內容與sudo crontab -u user -e的方式相同

但設定完還是無法正確執行

在網路上又繞了一大圈

才發現有個致命的遺漏點

  1. shell的執行環境
  2. 各種shell的參數引用方法

基本上我的shell腳本是設定bash shell

也就是第一行寫的

#!/bin/bash

但很多人沒注意到的事情是

在crontab裡面的其實有設定shell的執行環境是什麼

大家只會一路的往下滑開始設定時間區間與執行的指令

在crontab的文件

有兩行,分別定義了SHELL與PATH

Raspberry Pi OS預設是

SHELL=/bin/sh

也就是因為這行,就算shell腳本直接執行都正常,但是由crontab呼叫則什麼反應都沒有

因此最後再把crontab預設的shell執行

改為SHELL=/bin/bash

所有一切都照我的預期方式進行

並且也可以將原本程式的while與sleep都取消掉

畢竟Raspberry Pi Zero W效能還是有限

跑了Cacti,其餘的能盡量釋出資源就盡量釋出

--

--

Wei-Ting SHIH | 施韋廷
遠方的寂靜

A joint Ph.D. candidate in NTU, Taiwan and CY Cergy Paris Université, France. Passionate in EE and CS field. A French, photography and life learner.