1.背景
當多個程序可能會對同樣的資料執行操作時,這些程序需要保證其它程序沒有在操作,以免損壞資料。通常,這樣的程序會使用乙個「鎖檔案」,也就是建立乙個檔案來告訴別的程序自己在執行,如果檢測到那個檔案存在則程式設計客棧認為有操作同樣資料的程序在工作。這樣的問題是,程序不小心意外死亡了,沒有清理掉那個鎖檔案,那麼只能由使用者手動來清理了。
2.關於flock
flock 是對於整個檔案的建議性鎖。也就是說,如果乙個程序在乙個檔案(inode)上放了鎖,那麼其它程序是可以知道的。(建議性鎖不強求程序遵守。)最棒的一點是,它的第乙個引數是檔案描述符,在此檔案描述符關閉時,鎖會自動釋放。而當程序終止時,所有的檔案描述符均會被關閉。
3. shell中實現flock系統呼叫的命令是flock,其使用格式有以下兩種(man flock)
複製** **如下:
flock [-sxon] [-w timeout] lockfile [-c] command...
flock [-sxun] [-w timeout] fd
選項和引數:
-s,--shared:獲取乙個共享鎖,在定向為某檔案的fd上設定共享鎖而未釋放鎖的時間內,其他程序試圖在定向為此檔案的fd上設定獨佔鎖的請求失敗,而其他程序試圖在定向為此檔案的fd上設定共享鎖的請求會成功。
-x,-e,--exclusive:獲取乙個排它鎖,或者稱為寫入鎖,為預設項
-u,--unlock:手動釋放鎖,一般情況不必須,當fd關閉時,系統會自動解鎖,此引數用於指令碼命令一部分需要非同步執行,一部分可以同步執行的情況。
-n,--nb, --nonblock:非阻塞模式,當獲取鎖失敗時,返回1而不是等待
-w, --wait, --timeout seconds:設定阻塞超時,當超過設定的秒數時,退出阻塞模式,返回1,並繼續執行後面的語句
-o, --close:表示當執行command前關閉設定鎖的fd,以使command的子程序不保持鎖。
-c, --command command:在shell中執程式設計客棧行其後的語句
4. shell中實現排它鎖避免指令碼重複執行
linux中的例行性工作排程crontab會定時執行一些指令碼,但指令碼的執行時間往往無法控制,當指令碼執行時間過長時,可能會導致上一次任務的指令碼還沒執行完,下一次任務的指令碼又開始執行了。這種情況下可能會出現一些併發問題,嚴重時會導致出現髒資料/效能瓶頸的惡性迴圈。
通過使用flock建立排它鎖可以規避這個問題,如果乙個程序對某個加了排他鎖,則其它程序無法加鎖,可以選擇等待超時或馬上返回。測試例項如下:
4.1 建立執行指令碼
複製** **如下:
#cat /scripts/shell/file_lock.sh
#!/bin/bash
# description: test for file flock
path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export path
echo ""
echo "----------------------------------"
echo "start at `date '+%y-%m-%d %h:%m:%s'` ..."
sleep 140s
echo "finished at `date '+%y-%m-%d %h:%m:%s'` ..."
4.2 建立定時任務:測試排它鎖
複製** **如下:
#crontab -e
* * * * * flock -xn /dev/shm/test.lock -c "sh /scripts/shell/file_lock.sh > /root/stdout.log"
每分鐘執行一次該指令碼,並將輸出資訊寫入到stdout.log
檢視輸出日誌如下:
複製** **如下:
----------------------------------
start at 2014-04-10 10:23:01 ... #獲取鎖
finish at 2014-04-10 10:25:21 ... #釋放鎖
----------------------------------
start at 2014-04-10 10:26:01 ... #10:27:00及10:28:00啟動的定時任務由於無法獲取鎖,以失敗而退出執行,直到10:26:00才獲取到鎖
finish at 2014-04-10 10:28:21 ...
4.3 測試排它鎖,加上等待超時
複製** **如下:
* * * * * flock -x -w 20 /dev/shm/test.lock -c "sh /scripts/shell/file_lock.sh > /root/stdout.log"
檢視日誌輸出資訊:
複製** **如下:
----------------------------------
start at 2014-04-10 10:29:01 ...
finish at 2014-04-1程式設計客棧0 10:31:21 ...
----------------------------------
start at 2014-04-10 10:31:21 ... #10:31:00啟動的定時任務等待了20秒後,上乙個任務釋放了鎖,所以此任務可以馬上拿到鎖,並繼續執行
finish at 2014-04-10 10:33:41 ...
本文標題: shell指令碼實現檔案鎖功能
本文位址: /os/linux/117372.html
shell 指令碼實現檔案打包
將sent資料夾中的txt檔案壓縮到successful中對應資料夾中,若是沒有資料夾建立乙個 test3.sh bin bash date date y m for dir in ls file path file type 1 do 子目錄為資料夾 if echo dir grep then 去...
shell指令碼互斥鎖
指令碼防止同時執行兩個例項的互斥鎖 以下是主要寫法。檢查鎖檔案是否存在,如果存在表示系統中有其他例項在執行,則直接退出。需要注意的是,鎖檔案需要避免重名,建議指令碼名稱.file f tmp lock.file exit 開始執行任務前,建立鎖檔案,並把當前pid 寫入鎖檔案 echo tmp lo...
shell指令碼實現進度條功能
一,什麼是shell指令碼。乙個 shell 指令碼就是乙個包含一系列命令的檔案。shell 讀取這個檔案,然後執行 檔案中的所有命令,就好像這些命令已經直接被輸入到了命令列中一樣。shell 有些獨特,因為它不僅是乙個功能強大的命令列介面,也是乙個指令碼語言直譯器。我們將會看到,大多數能夠在命令列...