利用鎖機制,讓一個特定的shell指令碼,每次只能運行一個執行個體。具體來說,獲得鎖的指令碼執行個體,能夠繼續往下執行臨界區代碼;沒有獲得鎖的執行個體,則只能等待。
例如,要求指令碼只能順序訪問某個資源,例如磁碟檔案等,就可以參考下面的實現。
#!/bin/bash## file locking using bash.# ver 0.1.6## author : malundao ( malundao@sina.com )# date : 2011-08-31 # ref : http://unix.derkeiler.com/Newsgroups/comp.unix.shell/2005-09/0472.html## note:# shflock_cleanhook() is a user defined function to clean up user-specific sth.## /path/to/lock/. note; directory, not a file.# should be modified LOCKPATH="/tmp"cleanup() { shflock_cleanhook cd $LOCKPATH [ -e lock.pid ] || exit read pid >/dev/null 2>&1 <lock.pid if [ -n "$pid" ]; then if [ "$pid" == "$$" ]; then rm -f lock.$pid rm -f lock.pid exit fi fi exit}# trap EXIT ? trap 'cleanup' HUP INT TERMgetlock() { oldpath=`pwd` cd $LOCKPATH while echo $$ > lock.$$ [ -e lock.pid ] do rm lock.$$ read pid >/dev/null 2>&1 <lock.pid if [ -n "$pid" ]; then if [ -e /proc/$pid ]; then cd $oldpath return 1 # Lock is taken by others else #unsafe: rm -f lock.$pid echo WARN: please delete stale lock.pid by HAND. return 2 fi else # sleep some seconds,then back to 'while' loop # 11 is a prime number, $$ as a random. echo sleep $(( $$ % 11 )) sleep $(( $$ % 11 )) fi done # 'ln -s' is an atom op. ln -s lock.$$ lock.pid >/dev/null 2>&1 if [ $? -eq 0 ]; then cd $oldpath return 0 # We got the lock else [ -e lock.pid ] || echo WARN: please delete hanging lock.pid by HAND. cd $oldpath return 3 # Lock is probably taken by others. fi}putlock () { oldpath=`pwd` cd $LOCKPATH && rm -f lock.$$ lock.pid cd $oldpath}## test shflock_cleanhook() { echo i\'m a hook.}while true; do while ! getlock; do #echo wait a second... sleep 1 done echo \[$$\] `date` ,now hold lock for 3 seconds... sleep 3 #echo putlock putlock sleep 1 # yielddone