確保在 Linux 上僅執行一個 Bash 指令碼例項
簡介
在 Linux 上執行bash指令碼時,務必確保一次只執行一個指令碼例項。這對於執行關鍵任務的指令碼尤其重要,例如更新資料庫或傳送電子郵件的指令碼。同時執行多個相同指令碼例項可能會導致衝突、資料丟失和其他錯誤。在本文中,我們將討論確保 Linux 上僅執行一個bash指令碼例項的不同方法。
使用 Flock
確保 Linux 上僅執行一個bash指令碼例項的一種方法是使用“flock”命令。flock命令用於對檔案建立鎖,並且是大多數 shell(例如Bash、Zsh等)中內建的命令。這是一種簡單有效的方法,可以確保一次只執行一個指令碼例項。
我們可以信任這種方法,因為它不會出現競爭條件。此外,當程序完成時,檔案上的所有鎖都會被釋放。這些優點使得 flock 成為確保僅執行一個例項的安全方法。另一個好處是 flock 程式是 flock 系統呼叫的實現。
flock預設情況下會阻塞,直到鎖被釋放,然後繼續執行,不會出現錯誤。我們可以使用“-n”引數以非阻塞方式使用 flock。如果檔案上存在另一個鎖,這將導致 flock 立即以錯誤退出。
我們可以使用 flock 執行外部指令碼或在指令碼內部使用它。
執行外部指令碼
我們可以像這樣在指令碼中使用flock:
$ flock -n /var/lock/dobackup.lock ./dobackup.sh
現在假設我們的指令碼正在執行。讓我們看看如果我們再次執行上一行會發生什麼:
$ flock --verbose -n /var/lock/dobackup.lock ./dobackup.sh flock: failed to get lock $ echo $? 1
我們可以看到 flock 通知我們它無法獲取鎖並以值1(錯誤)退出。這意味著另一個例項擁有鎖。
當flock失敗時,它不會執行指令碼引數,這可以防止執行多個“dobackup.sh”例項。
在指令碼中使用 Flock
我們可以像這樣在指令碼內部使用flock:
#!/bin/bash another_instance() { echo "There is another instance running, exiting" exit 1 } ( flock -n 100 || another_instance DEST=/home/backup/`date +%s` mkdir -p "$DEST" rsync -avz root@host:/home/web "$DEST/." ) 100>/var/lock/dobackup.lock
在這種情況下,我們使用檔案描述符呼叫 flock,並將我們需要保護的所有內容括在方括號(子 shell)中,並將其重定向到我們用作鎖的檔案。我們使用在重定向中使用的檔案描述符在開頭呼叫 flock。因此,如果 flock 以錯誤退出,我們就知道有另一個例項正在執行。
子級別完成後,鎖檔案將關閉,鎖將自動釋放。
使用 Pid 檔案
確保 Linux 上僅執行一個bash指令碼例項的另一種方法是使用pid檔案。pid 檔案是一個特殊檔案,其中包含正在執行的指令碼的程序 ID (PID)。透過檢查 pid 檔案,我們可以確定指令碼是否正在執行,如果正在執行,則以錯誤訊息退出指令碼。
要實現此方法,我們可以將以下程式碼新增到指令碼的開頭:
if [ -f /path/to/pidfile ]; then pid=$(cat /path/to/pidfile) if kill -0 $pid 2>/dev/null; then echo "Script is already running" exit 1 else echo $$ > /path/to/pidfile fi else echo $$ > /path/to/pidfile fi
此程式碼檢查指定路徑中是否存在 pid 檔案。如果 pid 檔案存在,指令碼將從檔案中讀取 pid,並透過向程序傳送空訊號 (kill -0) 來檢查程序是否仍在執行。如果程序仍在執行,指令碼將以錯誤訊息退出。如果程序未執行,指令碼將用當前程序 ID 覆蓋 pid 檔案。如果 pid 檔案不存在,指令碼將建立它並寫入當前程序 ID。
在指令碼末尾,您可以新增以下程式碼以刪除 pid 檔案:
$ rm -f /path/to/pidfile
結論
確保 Linux 上僅執行一個 bash 指令碼例項是一項重要任務,可以防止衝突、資料丟失和其他錯誤。有幾種方法可以做到這一點,例如使用 flock 命令使用鎖檔案,使用 pid 檔案,或使用“pgrep”和“kill”命令。每種方法都有其優點和缺點,最適合您的指令碼的方法將取決於您的特定需求。透過實現任何這些方法,您可以確保您的指令碼順利執行且不會出錯。