스크립트의 ps | grep에서 다른 종료 상태를 얻는 이유는 무엇입니까?

스크립트의 ps | grep에서 다른 종료 상태를 얻는 이유는 무엇입니까?

다음 스크립트를 실행하고 있습니다.

#!/bin/bash

ps ax  | grep -q [v]arnish
if [ $? -eq 0 ];then
        echo varnish is running...
        exit 0
else
        echo "Critical : varnish is not running "
        exit 2
fi

출력은 다음과 같습니다::

[root@server ~]# sh -x check_varnish_pro.sh
+ ps ax
+ grep -q '[v]arnish'
+ '[' 0 -eq 0 ']'
+ echo varnish is running...
varnish is running...
+ exit 0

명령줄에서 동일한 명령을 실행하면 종료 상태가 1로 표시됩니다.

[root@server ~]# ps ax  | grep -q [v]arnish; echo $?
1

이 상황은 서버에 바니시가 설치되지 않은 것과 같습니다. 이 스크립트는 Varnish가 설치된 서버에서 제대로 실행됩니다.

스크립트와 명령줄을 사용하여 실행할 때 종료 상태가 다른 이유는 무엇입니까? 이 스크립트를 어떻게 개선할 수 있나요?

답변1

일반적으로 주어진 프로세스가 실행 중인지 확인하기 위해 간단한 방법을 사용하는 것은 ps좋지 않습니다 grep.

pgrep다음 방법을 사용하는 것이 좋습니다 .

if pgrep "varnish" >/dev/null; then
  echo "Varnish in running"
else
  echo "Varnish is not running"
fi

설명서를 참조하십시오 pgrep. 일부 시스템(Linux가 아닐 수도 있음)에서는 -q동일한 플래그에 해당하는 플래그를 얻으므로 grep로 리디렉션할 필요가 없습니다. 프로세스 이름뿐만 아니라 전체 명령줄에서 일치를 수행하는 플래그 /dev/null도 있습니다 . -f사용된 특정 사용자에 속하는 프로세스에 대한 일치를 제한하는 것도 가능합니다 -u.

설치 후에도 pgrep액세스할 수 있으므로 pkill이름을 기준으로 프로세스에 신호를 보낼 수 있습니다.

반품,서비스 데몬인 경우, Unix 시스템에 이에 대한 정보(예: 실행 중인지 여부)를 쿼리할 수 있는 방법이 있는 경우 다음과 같습니다.적절한확인하는 방법.

Linux에서는 systemctl( systemctl is-active --quiet varnish실행 중이면 0을 반환하고, 그렇지 않으면 3을 반환) OpenBSD에서는 rcctl등이 있습니다.


이제 스크립트로:

스크립트에서 출력을 구문 분석합니다 ps ax. 이 출력에는 check_varnish_pro.sh분명히 strings 를 포함하는 스크립트 자체의 이름이 포함됩니다 varnish. 이것은 당신에게 거짓 긍정을 줄 것입니다. 테스트할 때 플래그 없이 실행하면 -q이 사실을 알 수 있습니다 .grep

#!/bin/bash
ps ax | grep '[v]arnish'

실행하세요:

$ ./check_varnish_pro.sh
31004 p1  SN+     0:00.04 /bin/bash ./check_varnish_pro.sh

grep또 다른 문제는 프로세스를 패턴으로 사용하여 자체적으로 감지되지 않도록 "숨기려고"한다는 것입니다. 지정된 파일이나 디렉터리가 포함된 디렉터리에서 스크립트나 명령줄을 실행하는 경우 이 방법은 실패합니다. 이 경우 다시 거짓 긍정이 발생합니다. 이는 패턴이 인용되지 않고 쉘에서 파일 이름 글로빙을 수행하는 데 사용되기 때문입니다.grep[v]varnish

바라보다:

bash-4.4$ set -x
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep '[v]arnish'
bash-4.4$ touch varnish
+ touch varnish
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep varnish
91829 p2  SN+p    0:00.02 grep varnish

파일이 있으면 varnish쉘이 [v]arnish파일 이름을 대체하게 되며 varnish프로세스 테이블(process)에서 패턴을 찾을 수 있습니다 grep.

답변2

check_varnish_pro.shtest라는 스크립트를 실행하면

ps ax  | grep -q [v]arnish

성공이란 이름의 사람이 있기 때문이다check_페인트_pro달리기.

답변3

@AlexP가 설명했습니다.실제로 일어난 일을 매우 간결하게 설명하고 있지만 @Kusalananda의 생각은 다음과 같습니다.주요 프로세스에 pgrep/를 사용하는 것은 다음과 같습니다.pkill매우 낙담함.더 나은 솔루션은 다음과 같습니다.

  • 묻다제공하다실행 중입니다. systemctl status varnishd이 문제는 최신 *nix 설치에서 수정되어야 합니다.
  • 불행한 상황에서 서비스를 사용할 수 없는 경우 시작 스크립트를 변경하여 프로세스가 종료되는 즉시 문제를 보고할 수 있습니다.

    varnish || true
    some_command_to_send_an_alert_that_the_service_has_died
    
  • 또는 서비스를 시작하는 스크립트를 다음으로 변경하십시오.PID 기록,그런 다음 정기적으로 상태 확인을 사용하십시오 kill -0 "$pid".

관련 정보