Shell-Script

在 KornShell 中檢查 AIX 7.1.0 上正在執行的程序的正確且可靠的方法

  • December 18, 2017

我一直在嘗試找到一種方法來檢查腳本是否正在執行,因為我想確保在執行某些東西時沒有任何其他實例。到目前為止,我已經嘗試過:

#! /bin/ksh93

getProcessNum(){
   processNum=$(ps -ef | grep -E "$1" \
       | grep -vE "emacs|vi |ve |grep|ps|tail|tee|runProcess|jlast|tlast|elast" \
       | awk '/'$USER'/ { if($1 == "'$USER'") print $0}' \
       | awk -v myPid=$$ '{if ($3 != myPid) print $0}' \
       | wc -l
   )
}

getProcessNum "myAvoidedScript.k"

if [[ $processNum -gt 1 ]]; then
   echo "There are $processNum instances running. Stopping..."
else
   echo "You can continue"
fi

我得到了這個:

ThisProcessID=4063450
myUser  4063450  5636606   0 19:06:48 pts/10  0:00 /bin/ksh93 myAvoidedScript.k
myUser  8978492  5964234   0 19:06:48 pts/10  0:00 /bin/ksh93 myAvoidedScript.k
myUser  3277270  9109712 113 11:07:58  pts/5 70:50 /bin/ksh93 myAvoidedScript.k

我認為這種方式就足夠了,但是即使它們是同一腳本的一部分,也有一些程序被計算在內。我注意到當我嘗試執行這個腳本時,它返回了一個大於 1 的數字,即使沒有任何執行。

所以我說:也許如果我嘗試消除在非常準確的時間開始的重複,就足夠了,我嘗試了這個:

#! /bin/ksh93

getProcessNum(){
   processNum=$(ps -ef | grep -E "$1" \
       | grep -vE "emacs|vi |ve |grep|ps|tail|tee|runProcess|jlast|tlast|elast" \
       | awk '/'$USER'/ { if($1 == "'$USER'") print $0}' \
       | awk -v myPid=$$ '{if ($3 != myPid) print $0}' \
       | sort -k 4 | awk '!x[$5]++' | wc -l
   )
}

getProcessNum "myAvoidedScript.k"
if [[ $processNum -gt 1 ]]; then
   echo "There are $processNum instances running. Stopping..."
else
   echo "You can continue"
fi

有時我得到正確的結果,但其他一些我得到這個

返回的 PID 並不總是與目前的 PID ($$) 相同:

ThisProcessID=4063450
myUser  3177476  5964232   0 19:06:49 pts/10  0:00 /bin/ksh93 myAvoidedScript.k
myUser  3277270  9109712 113 11:07:58  pts/5 70:50 /bin/ksh93 myAvoidedScript.k

當您在幾秒鐘內執行此腳本時,它仍然會帶來相同腳本的兩個實例。

ThisProcessID=4063450
myUser  4063450  5636606   0 19:07:48 pts/10  0:00 /bin/ksh93 myAvoidedScript.k
myUser  5177476  5964232   0 19:07:49 pts/10  0:00 /bin/ksh93 myAvoidedScript.k
myUser  3277270  9109712 113 11:07:58  pts/5 70:50 /bin/ksh93 myAvoidedScript.k

有誰知道我如何確保無論何時執行此腳本,它只會使正確的程序以可靠的方式執行?

PS。我知道我可以使用標誌文件,但這意味著要更改很多腳本。

我沒有 AIX 系統來對此進行測試,但是由於在執行ps. 您可以嘗試通過ps自行執行並將其輸出擷取到臨時文件或更簡單的變數中來避免這種情況。您還可以將 grep、awk 和 wc 簡化為一個 awk 命令。例如,

getProcessNum(){
   procs=$(ps -u "$USER" -f)
   processNum=$(printf '%s\n' "$procs" |
       awk -v myPid="$$" -v name="$1" '
           index($0,"ksh93 " name) != 0 && $2 != myPid {tot++}
           END {print tot}'
   )
}

引用自:https://unix.stackexchange.com/questions/404348