介紹各種在 Linux 系統下避免 crontab 重複執行相同程式的方法。
若在 Linux 中使用 crontab 定期執行例行性工作的程式,若 crontab 執行程式的間隔時間有可能小於該程式處理工作的時間,就會發生在某些時間點會有兩個以上的相同程式在執行,當發生這種情況時就會造成系統資源浪費,甚至造成資料處理上的錯誤。
以下介紹幾種可以避免同一個程式同時執行多次的方法。
若希望 crontab 在執行程式的時候,避免重複執行相同的程式,可以使用 PID 檔案的方式來判斷該程式目前是否已經在執行,若發現該程式目前已經有在執行的話,就直接離開,避免重複執行,以下是實作範例。
#!/bin/bash # 設定 PID 檔案放置路徑 PIDFILE=/home/officeguide/myjob.pid # 若 PID 檔案存在 if [ -f $PIDFILE ]; then # 取得 PID 檔案內容(也就是目前執行程式的 PID) PID=$(cat $PIDFILE) # 檢查程式是否真的在執行 ps -p $PID > /dev/null 2>&1 # 若 ps 執行成功,代表成功依據 PID 找到執行的程式, # 則直接離開本程式 if [ $? -eq 0 ]; then echo "程式已經在執行了。" exit 1 fi fi # 建立本程式的 PID 檔案 echo $$ > $PIDFILE # 若 echo 執行失敗,則終止程式執行 if [ $? -ne 0 ]; then echo "無法建立 PID 檔案。" exit 1 fi # 實際的程式內容 sleep 5m # 程式執行完畢,清除 PID 檔案 rm $PIDFILE
在這個例子中,程式實際執行的工作只有一行 sleep 5m
而已,其餘的部分都是在透過 PID 檔案檢查是否程式有重複執行。
若要將自己的程式套用此範例,只要修改 PID 檔案的路徑(建議可放在 /run/lock/
目錄之下),然後將 sleep 5m
替換成自己的程式即可。
flock
flock
是大部分 Linux 發行版中內建的指令,它可以讓使用者在 shell 中管理檔案或目錄的鎖定,我們可以透過 flock
避免重複程式執行:
# 透過 flock 避免重複程式執行 flock -xn /home/officeguide/myjob.lock sleep 5m
這裡的 flock
會先取得 /home/officeguide/myjob.lock
這個檔案的寫入鎖,然後再執行後面的指令(sleep 5m
)。
當發生重複執行時,flock
就會自動離開,並傳回錯誤代碼 1
:
# 透過 flock 避免重複程式執行 flock -xn /home/officeguide/myjob.lock sleep 5m # 取得程式執行傳回值 echo $?
1
solo
指令稿solo
是一個非常簡單的 Perl 指令稿,它是透過鎖定通訊埠的方式來避免重複程式執行。
solo
只是一段 Perl 指令稿,直接下載即可使用:
# 下載 solo 指令稿 wget https://www.timkay.com/solo/solo # 設定執行權限 chmod +x solo
透過 solo
執行程式時,要指定一個鎖定用的通訊埠(範圍介於 1024
至 65535
,隨意指定即可):
# 透過 solo 避免重複程式執行 ./solo -port=20000 sleep 5m
由於通訊埠不能被重複使用,所以當上一個執行的程式取得該通訊埠之後,後面重複執行的程式就會因為無法取得相同的通訊埠而被迫終止執行:
# 透過 solo 避免重複程式執行 ./solo -port=20000 sleep 5m
solo(20000): Address already in use
參考資料:Benjamin Cane