久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

如何正經(jīng)的實現(xiàn)shell腳本單例運行

193次閱讀
沒有評論

共計 2339 個字符,預(yù)計需要花費 6 分鐘才能閱讀完成。

這篇文章將為大家詳細(xì)講解有關(guān)如何正經(jīng)的實現(xiàn) shell 腳本單例運行,丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

看起來可行的方法

一個非常簡單的思路就是,新的腳本被執(zhí)行時,先檢測當(dāng)前腳本是否有其他實例正在運行,如果有則直接退出。

runCount=$(ps -ef|grep test.sh | grep -v grep -c) if [  ${runCount}  -ge 1 ] then echo -e  test.sh already running,num:${runCount}  exit 1; fi while true do echo  test.sh run  sleep 1 done

這里通過 ps 獲取到當(dāng)前在運行的 test.sh 腳本數(shù),如果大于 1,說明已經(jīng)有在運行的了。

但是你運行會發(fā)現(xiàn),其程序數(shù)量不只是一個。

$ ./test.sh test.sh already running,num:2

驚不驚喜? 為什么為這樣呢? 原因在于,shell 腳本中一個命令執(zhí)行相當(dāng)于 fork 了一個進(jìn)程執(zhí)行,這里執(zhí)行的是查找 tesh.sh 并 grep 的程序,另外還有一個就是當(dāng)前運行的腳本程序,這樣的方式自然就會出現(xiàn)每次都有兩個了。

當(dāng)然判斷條件這里你可以換一下,例如數(shù)量大于 2,但終歸不太好。

文件鎖

實際上這種方法你已經(jīng)在《如何讓你的程序同時只有一個在運行》介紹過了,只不過之前是用于編寫 C /C++ 程序,而這里是用于 shell 腳本。

我們來回顧一下,這是一個怎樣的過程:

運行前檢查是否有該鎖文件,并且文件中的進(jìn)程正在運行

如果有并且程序正在運行,則已經(jīng)有實例在運行

否則,無實例,創(chuàng)建鎖文件,寫入進(jìn)程 id

退出時,刪除鎖文件

解釋一下第一條,為什么一定要確定鎖文件中的進(jìn)程正在運行,因為,有些情況下如果運行的時候退出沒有刪除該文件,則會導(dǎo)致新的實例永遠(yuǎn)無法運行。

#!/usr/bin/env bash LOCKFILE=/tmp/test.lock if [ -e ${LOCKFILE} ]   kill -0 `cat ${LOCKFILE}`; then echo   $0 already running  exit fi #  確保退出時,鎖文件被刪除  trap  rm -f ${LOCKFILE}; exit  INT TERM EXIT # 將當(dāng)前程序進(jìn)程 id 寫入鎖文件  echo $$   ${LOCKFILE} #  做你需要的事情  sleep 1000 #  刪除鎖文件  rm -f ${LOCKFILE}

我們試著運行其中一個,然后另外一個窗口嘗試運行:

$ ./test.sh ./test.sh already running

由于已經(jīng)有實例在運行,發(fā)現(xiàn)新的程序無法運行了。而等舊的腳本運行完之后,新的就可以運行了。

實際上這里面有幾個點非常巧妙:

kill -0 `cat \${LOCKFILE}` 這里用于檢測該進(jìn)程是否存在,避免進(jìn)程不在了,但是鎖文件還在,導(dǎo)致后面的腳本無法運行。

trap rm -f \${LOCKFILE}; exit INT TERM EXIT 用于確保腳本退出時,鎖文件會被刪除。

rm -f {LOCKFILE} 腳本最后需要刪除鎖文件

flock

說到鎖文件,這里就不得不提 flock 命令了。沒有前面的一些巧妙處理,我們很多時候會很難刪除原先創(chuàng)建的鎖文件,比如:

腳本被意外中斷,沒來得及執(zhí)行刪除

多個腳本產(chǎn)生競爭,導(dǎo)致判斷異常,比如前面有一個腳本運行,判斷沒有鎖文件,下一步準(zhǔn)備創(chuàng)建,但是另外一個腳本又先創(chuàng)建了,就會導(dǎo)致異常了。

因此我們可以考慮使用 flock:

#!/usr/bin/env bash LOCK_FILE=/tmp/test.lock exec 99 $LOCK_FILE  flock -n 99 if [  $?  != 0 ]; then echo  $0 already running  exit 1 fi # 腳本要做的其他事情  sleep 1024

解釋一下:

exec 99 $LOCK_FILE   表示創(chuàng)建文件描述符 99,指向鎖文件,為何是 99?110 其實也是可以的,只是為了和當(dāng)前腳本可能打開的文件描述符沖突 (例如和 0,1,2 沖突)。

flock -n 99 嘗試對該文件描述符加鎖,由操作系統(tǒng)保證原子性

一旦 flock 失敗了,我們這里可以退出

而即使鎖定了,腳本退出后,也會自動釋放

因此這里避免了鎖沒有釋放的情況。

另一種做法

查看 flock 的 man 手冊,我們發(fā)現(xiàn)它還有一個例子是這么做的:

[  ${FLOCKER}  !=  $0  ]   exec env FLOCKER= $0  flock -en  $0   $0   $@  || :

在腳本開頭加上上面這么一行就可以了。例如:

#!/usr/bin/env bash [  ${FLOCKER}  !=  $0  ]   exec env FLOCKER= $0  flock -en  $0   $0   $@  || : # 腳本要做的其他事情  sleep 1024

解釋一下:如果 ${FLOCKER} 環(huán)境變量沒有設(shè)置,則嘗試將腳本本身加鎖,如果加鎖成功,則運行當(dāng)前腳本,(并且?guī)显械膮?shù)),否則的話靜默退出。

總結(jié)

單例運行本身思路是很簡單的,就是探測當(dāng)前是否有實例在運行,如果有,則退出,但是這里如何判斷,卻并不是那么容易。

最后,總結(jié)一下本文出現(xiàn)的一些該掌握的信息:

$0 腳本名稱

$@ 腳本參數(shù)

$$ 當(dāng)前腳本進(jìn)程 id

$? 上一條命令執(zhí)行結(jié)果

描述符 0 標(biāo)準(zhǔn)輸入

描述符 1 標(biāo)準(zhǔn)輸出

描述符 2 標(biāo)準(zhǔn)錯誤

重定向

關(guān)于“如何正經(jīng)的實現(xiàn) shell 腳本單例運行”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-08-25發(fā)表,共計2339字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 东明县| 定南县| 临颍县| 苍山县| 阜康市| 余江县| 乌兰县| 平谷区| 金山区| 黄浦区| 辽阳市| 固阳县| 股票| 乌鲁木齐县| 敖汉旗| 哈巴河县| 普格县| 双柏县| 樟树市| 玉屏| 三台县| 阜南县| 孝义市| 广南县| 南雄市| 军事| 绥滨县| 磐石市| 中西区| 斗六市| 淮南市| 南华县| 萝北县| 呼玛县| 沈丘县| 织金县| 清水县| 洛浦县| 乌苏市| 巴里| 泾川县|