2009-06-06 23 views
2

可能重複:
Quick-and-dirty way to ensure only one instance of a shell script is running at a time殼牌片段,以確保只有一個實例shell腳本在任何特定時間運行

在以前的工作,我們曾經有過一個高度精煉的bash函數稱爲run-only-once,我們可以將它寫入任何長時間運行的shell腳本中,然後在腳本開始時調用它,它將檢查腳本是否已經作爲另一個進程運行,如果是這樣,請退出通知標準輸出。

有沒有人有這樣的功能/片段,他們可以分享?

我們舊的函數(我不再有)會在/ var/run中檢查PID文件(以scriptname。$$格式),然後使用然後退出或繼續。在存在PID文件的情況下,它將執行一些檢查以確保該過程仍處於活動狀態。它還有幾個選項來控制是否輸出通知。

從內存中,我們的功能只在bash中工作。/bin/sh版本的獎勵積分。

回答

10

在腳本

SCRIPTNAME=`basename $0` 
PIDFILE=/var/run/${SCRIPTNAME}.pid 


if [ -f ${PIDFILE} ]; then 
    #verify if the process is actually still running under this pid 
    OLDPID=`cat ${PIDFILE}` 
    RESULT=`ps -ef | grep ${OLDPID} | grep ${SCRIPTNAME}` 

    if [ -n "${RESULT}" ]; then 
    echo "Script already running! Exiting" 
    exit 255 
    fi 

fi 


#grab pid of this process and update the pid file with it 
PID=`ps -ef | grep ${SCRIPTNAME} | head -n1 | awk ' {print $2;} '` 
echo ${PID} > ${PIDFILE} 

,並開始將這個末

if [ -f ${PIDFILE} ]; then 
    rm ${PIDFILE} 
fi 

這首先檢查了PID文件並退出,如果它存在的存在。如果是這樣,那麼它確認該腳本名稱下的一個進程正在運行,如果存在,則退出。如果沒有,那麼它繼續並用新的pid文件更新腳本。最後一位檢查是否存在pid文件並將其刪除,以便下次運行該腳本。

雖然在/ var/run上檢查權限對您的腳本是正常的,否則在另一個目錄中創建PID文件。腳本運行在同一個目錄下會很好。

+0

好的答案,我可能會使用它,或者將這個問題與問題185451的答案組合起來,Nik指向的是(即,我將使用陷阱並殺死-0)。 – 2009-06-07 02:28:51

5

有兩種方法可以從shell執行原子鎖。最簡單和最便攜的是mkdir。創建一個目錄將總是失敗,如果一個文件/目錄的名稱已經存在,所以只需使用「鎖定目錄」而不是「鎖定文件」。

mkdir "$LOCK" || { echo "Script already running" ; exit 1 ; } 

另一種方法是noclobber選項,使用set -C設置。此選項強制shell使用O_EXCL標誌打開輸出重定向文件。使用這樣的:

set -C 
> "$LOCK" || { echo "Script already running" ; exit 1 ; } 
set +C 

而不是重定向空命令,你可能更喜歡呼應其他有用的存儲在文件中的當前PID什麼的。

這是值得牢記一些古老的歷史彈已經打破了noclobber選項-C不使用O_EXCL而是馬車非原子檢查文件的存在的實現。可能不是21世紀的問題,但你應該注意以防萬一。

1

在Linux中使用lockfile實用程序更可靠。

從手冊頁:

  ... 
     lockfile important.lock 
     ... 
     access_"important"_to_your_hearts_content 
     ... 
     rm -f important.lock 
     ... 

您可以指定重試和等待時間。這是專門爲此目的而創建的,因此它需要照顧競爭條件

相關問題