나는 뭔가가 실행되는 동안 스크립트의 다른 인스턴스가 없는지 확인하고 싶기 때문에 스크립트가 실행 중인지 확인하는 방법을 찾으려고 노력해 왔습니다. 지금까지 나는 다음을 시도했습니다.
#! /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
이 스크립트를 거의 1초 동안 실행해도 정확히 동일한 스크립트의 두 인스턴스가 계속 표시됩니다.
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
이 스크립트를 실행할 때마다 올바른 프로세스만 안정적인 방식으로 실행되도록 하는 방법을 아는 사람이 있습니까?
추신. 플래그 파일을 사용할 수 있다는 것을 알고 있지만 이는 많은 스크립트를 변경해야 함을 의미합니다.
답변1
이것을 테스트할 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}'
)
}
답변2
이 스크립트를 실행할 때마다 올바른 프로세스만 안정적인 방식으로 실행되도록 하는 방법을 아는 사람이 있습니까?
ps
현재 사용자가 소유한 프로세스 목록을 요청 -u $USER
하고 해당 프로세스의 pid, 상위 pid 및 전체 명령 문자열(명령 및 인수)을 인쇄한 다음 추가 검사를 위해 이를 awk에 전달할 수 있습니다. Awk에는 현재 스크립트의 pid( -v me=$1
)와 찾을 프로세스의 이름( -v procname=$2
)이 제공되고, 그런 다음 세 가지 요구 사항을 충족하는 행을 찾으라는 지시를 받습니다.
- 여기서 pid(열 1)는 다음과 같습니다.아니요현재 스크립트의 pid
- 여기서 ppid(열 2)는 다음과 같습니다.아니요현재 스크립트의 pid
- 여기서 명령 문자열은 지정된 매개변수와 일치합니다.
행이 이 두 가지 요구 사항을 모두 충족하면 awk는 pid를 인쇄한 다음 해당 pid(있는 경우)를 파이프하여 wc -l
인스턴스를 계산합니다. 단순히 카운터를 늘릴 수도 있지만, 다른 목적으로 PID를 조사하려는 경우 이를 검색할 수 있는 방법이 제공됩니다.
getProcessNum() {
ps -u "$USER" -o pid=,ppid=,args= |
awk -v me="$1" -v procname="$2" \
'$1 != me && $2 != me && index(substr($0,19,length(procname)), procname) { print $1 }' |
wc -l
}
이것과의 가장 큰 차이점은네현재 스크립트의 모든 하위 프로세스를 구체적으로 무시할 수 있도록 상위 프로세스 pid를 인쇄하도록 요청한다는 것입니다 ps
. 다른 차이점은 결정할 때 다음과 index
같은 거짓 긍정을 최대한 방지하기 위해 이 작업을 수행한다는 것 입니다. 물론 인공적이다 vi ksh93 myAvoidedScript.k
.
ps -o args
이러한 인스턴스가 올바르게 제외되도록 하려면 스크립트의 정확한 주문(주어진 대로)을 전달해야 합니다. 여기처럼요 getProcessNum $$ "/bin/ksh93 myAvoidedScript.k"
. 인수( /bin/ksh93 myAvoidedScrip.k foo
), 옵션( ksh93 -x myAvoidedScript.k
) 또는 전체 경로( /bin/ksh93 /path/to/myAvoidedScript.k
)를 사용하거나 다른 인터프리터 경로( ./ksh93 myAvoidedScript.k
) 또는 직접( )을 사용하여 스크립트를 호출할 수 있는 경우 ./myAvoidedScript.k
이 검사는 실패합니다 .
정확한 스크립트 호출을 보장할 수 없으면 한 번에 하나의 스크립트 복사본만 실행된다는 것을 보장하기 어렵습니다.