작동하지 않는 실행 인스턴스 수를 계산하는 Bash 스크립트

작동하지 않는 실행 인스턴스 수를 계산하는 Bash 스크립트

인스턴스가 내 Linux 시스템에서 이미 실행 중인지 감지하고 화면에 인스턴스 수를 표시하는 스크립트를 작성 중입니다.

"Detect_itself.sh" 스크립트의 내용은 다음과 같습니다.

#!/bin/sh

INSTANCES_NUMBER=`ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`
echo "Number of detect_itself.sh instances running now =" $INSTANCES_NUMBER
echo "Second method:"
ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l
echo "Third method:"
echo `ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`
echo "Please, press a key"
read -r key

스크립트를 실행하면 화면에 다음이 표시됩니다.

Number of detect_itself.sh instances running now = 2
Second method:
1
Third method:
2
Please, press a key

하지만 나는 그것이 보여주기를 원합니다:

Number of detect_itself.sh instances running now = 1
Second method:
1
Third method:
1
Please, press a key

왜 실행하면 ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l값 1이 반환되는지 이해가 안 되지만, 이 값을 변수에 저장하고 에코로 표시하면 2가 표시됩니다.

답변1

이는 ps서브셸에서 명령을 실행하기 때문에 발생합니다. 이것을 실행하면:

INSTANCES_NUMBER=`ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`

이는 명령을 실행하기 위해 새로운 하위 쉘을 효과적으로 포크합니다. 이 포크는 상위 항목의 복사본이므로 이제 두 개의 detect_itself.sh인스턴스가 실행 중입니다. 이를 설명하려면 다음 명령을 실행하십시오.

#!/bin/sh
echo "Running the ps command directly:"
ps -ef | grep detect_itself.sh | grep -v -i grep
echo "Running the ps command in a subshell:"
echo "`ps -ef | grep detect_itself.sh | grep -v -i grep`"

다음을 인쇄해야 합니다:

$ test.sh
Running the ps command directly:
terdon   25683 24478  0 14:58 pts/11   00:00:00 /bin/sh /home/terdon/scripts/detect_itself.sh
Running the ps command in a subshell:
terdon   25683 24478  0 14:58 pts/11   00:00:00 /bin/sh /home/terdon/scripts/detect_itself.sh
terdon   25688 25683  0 14:58 pts/11   00:00:00 /bin/sh /home/terdon/scripts/detect_itself.sh

다행히도 이를 수행하는 앱이 있습니다! 이런 일이 바로 pgrep존재하는 이유이다. 따라서 스크립트를 다음과 같이 변경하십시오.

#!/bin/sh
instances=`pgrep -fc detect_itself.sh`
echo "Number of detect_itself.sh instances running now = $instances"
echo "Second method:"
ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l
echo "Third method (wrong):"
echo `ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`

다음을 인쇄해야 합니다:

$ detect_itself.sh
Number of detect_itself.sh instances running now = 1
Second method:
1
Third method (wrong):
2

중요한: 이것은 안전한 것이 아닙니다. 예를 들어 이라는 스크립트가 있는 경우 this_will_detect_itself해당 스크립트가 계산됩니다. 텍스트 편집기에서 파일을 연 경우 해당 파일도 계산됩니다. 이런 종류의 일에 대한 보다 안정적인 방법은 잠금 파일을 사용하는 것입니다. 그것은 다음과 같습니다:

#!/bin/sh

if [[ -e /tmp/I_am_running ]]; then
    echo "Already running! Will exit."
    exit
else
    touch /tmp/I_am_running
fi
## do whatever you want to do here

## remove the lock file at the end
rm /tmp/I_am_running

또는 더 나은 방법은 trap스크립트가 충돌하더라도 파일이 삭제되도록 하기 위해 사용하는 것을 고려하는 것입니다. 세부 사항은 정확히 수행하려는 작업과 실행 중인 인스턴스를 계측해야 하는 이유에 따라 달라집니다.

관련 정보