Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Shell 腳本防重複運行實戰:鎖文件機制與 trap 信號處理

編輯:Linux 教學

定時任務(cron)執行的備份/同步腳本若上次未結束就觸發下次,會導致數據衝突、資源耗盡。本文從簡單鎖文件演進到原子操作 noclobber + trap 信號清理的健壯方案,並分析邊界情況。

演進歷程

版本 1:簡單鎖文件(有競態條件)

LOCK="/tmp/my.lock"
[[ -e $LOCK ]] && { echo "re-entry, exiting"; exit 1; }
touch $LOCK
# 正常業務邏輯
rm -f $LOCK

缺陷:[[ -e ]] 和 touch 非原子,兩進程同時通過檢查;腳本異常退出遺留鎖文件導致永久阻塞。

版本 2:原子創建 + 信號清理(生產就緒)

LOCK="/tmp/my.lock"
if ( set -o noclobber; echo "$$" > "$LOCK" ) 2>/dev/null; then
    trap 'rm -f "$LOCK"; exit $?' INT TERM EXIT
    # 正常業務邏輯
    rm -f "$LOCK"
    trap - INT TERM EXIT
else
    echo "Failed to acquire lock: $LOCK. Held by $(cat $LOCK)"
    exit 1
fi

關鍵技術解析

技術作用
set -o noclobber禁止 > 覆蓋現有文件,保證 echo $$ > lock 原子性
$$當前進程 PID,寫入鎖文件便於排查持有者
trap 'cmd' SIG捕獲信號執行清理:INT(Ctrl+C)、TERM(kill)、EXIT(正常退出)
trap - SIG恢復信號默認處理,避免影響子進程

信號處理詳解

  • INT:用戶按 Ctrl+C 中斷腳本
  • TERM:kill -TERM PID 優雅停止
  • EXIT:腳本正常結束(包括 exit、執行完畢)
  • 無法捕獲:kill -9 (SIGKILL) 內核直接終止,無法執行 trap

邊界情況應對

  • 系統崩潰/斷電:重啟後 /tmp 通常清空,鎖自動釋放
  • NFS 共享鎖文件:需使用 flock 或 fcntl 鎖,普通文件鎖不可靠
  • 多實例不同參數:鎖文件名包含參數哈希 /tmp/my_${param_hash}.lock

替代方案對比

Copyright © Windows教程網 All Rights Reserved
方案優點缺點
flock -n內核級鎖、自動釋放、支持共享/排他需安裝 util-linux、不支持 NFS
mkdir lockdir目錄創建原子性、跨平台需手動清理、無進程信息
PID 文件 + kill -0可檢測進程存活競態條件複雜、需防 PID 復用