다음 스크립트를 실행하고 있습니다.
#!/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.sh
test라는 스크립트를 실행하면
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"
.