실행 인스턴스 수를 계산하는 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

실행하면 값 1이 반환되는 이유를 이해할 수 없지만 ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l이 값을 변수에 저장하고 에코로 표시하면 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스크립트가 충돌할 때에도 파일이 제거되었는지 확인하기 위해 사용 방법을 살펴보는 것입니다. 세부 사항은 정확히 무엇을 하려는지, 실행 중인 인스턴스를 감지해야 하는 이유에 따라 달라집니다.

관련 정보