Categories: Linux

Linux 避免 Crontab 重複執行程式教學與範例

介紹各種在 Linux 系統下避免 crontab 重複執行相同程式的方法。

若在 Linux 中使用 crontab 定期執行例行性工作的程式,若 crontab 執行程式的間隔時間有可能小於該程式處理工作的時間,就會發生在某些時間點會有兩個以上的相同程式在執行,當發生這種情況時就會造成系統資源浪費,甚至造成資料處理上的錯誤。

以下介紹幾種可以避免同一個程式同時執行多次的方法。

以 PID 檔案避免重複執行

若希望 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 執行程式時,要指定一個鎖定用的通訊埠(範圍介於 102465535,隨意指定即可):

# 透過 solo 避免重複程式執行
./solo -port=20000 sleep 5m

由於通訊埠不能被重複使用,所以當上一個執行的程式取得該通訊埠之後,後面重複執行的程式就會因為無法取得相同的通訊埠而被迫終止執行:

# 透過 solo 避免重複程式執行
./solo -port=20000 sleep 5m
solo(20000): Address already in use

參考資料:Benjamin Cane

Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

9 個月 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

9 個月 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

9 個月 ago

Windows 使用 TPM 虛擬智慧卡保護 SSH 金鑰教學與範例

本篇介紹如何在 Windows...

10 個月 ago

Linux 以 Shamir’s Secret Sharing 分割保存金鑰教學與範例

介紹如何在 Linux 中使用...

10 個月 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

10 個月 ago