KornShell의 AIX 7.1.0에서 실행 중인 프로세스를 확인하는 정확하고 안정적인 방법

KornShell의 AIX 7.1.0에서 실행 중인 프로세스를 확인하는 정확하고 안정적인 방법

나는 뭔가가 실행되는 동안 스크립트의 다른 인스턴스가 없는지 확인하고 싶기 때문에 스크립트가 실행 중인지 확인하는 방법을 찾으려고 노력해 왔습니다. 지금까지 나는 다음을 시도했습니다.

#! /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. psgrep, 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)이 제공되고, 그런 다음 세 가지 요구 사항을 충족하는 행을 찾으라는 지시를 받습니다.

  1. 여기서 pid(열 1)는 다음과 같습니다.아니요현재 스크립트의 pid
  2. 여기서 ppid(열 2)는 다음과 같습니다.아니요현재 스크립트의 pid
  3. 여기서 명령 문자열은 지정된 매개변수와 일치합니다.

행이 이 두 가지 요구 사항을 모두 충족하면 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이 검사는 실패합니다 .

정확한 스크립트 호출을 보장할 수 없으면 한 번에 하나의 스크립트 복사본만 실행된다는 것을 보장하기 어렵습니다.

관련 정보