有些時候,你不希望一個 script 同時有兩個以上的 instance,這個時候你可能有很多想法,例如利用檢查 pid file 的方法,或者是找一個 lockf(1) 之類的程式幫你處理這些事情。(老實說 FreeBSD 的 lockf(1) 的確蠻方便的,尤其是對於懶惰寫 code 的我來說。)
但是這會有另外一個問題,不是每個 OS 都有提供 lockf(1),有些就只給你 lockf(2)。所以我就得換個方法作,首先,我想到這樣的寫法
if [ -f $lockfile] ; then touch $lockfile
利用一個 lockfile 來確保互斥性,只不過 -f 與 touch 之間還是有機會產生 race condition。結果在讀了一些文章之後,我發現有人說 mkdir(2) 是 atomic 的(我目前還沒有找到什麼佐證的資料,NFS 就先放一旁吧……),也有人就用 mkdir(1) 來確保同時只會有一個 shell script 的 instance,再搭配 trap 來處理一些 signal,這樣似乎就可以暫時取代 lockf 了……。
最後的版本就像這樣,應該還有很多問題,但先這樣吧。
ToLock() { progName=`/bin/basename $0` lockname="/tmp/$progName.lock" if /bin/mkdir "$lockname" then # Remove lock directory when script terminates trap '/bin/rmdir "$lockname"' 0 1 2 3 15 trap "exit 2" 1 2 3 15 else echo >&2 "another $progName is running?" exit 1 fi }
最後附上幾篇參考資料