Ubuntu 서버(14.04)에서 프로세스가 실행 중인지 확인하는 스크립트를 작성했는데 제대로 작동하지만 테스트하는 동안 다른 터미널에서 실행 중인 상위 명령 수가 포함되지 않는 것을 발견했습니다.
콘텐츠check-process.sh
#!/bin/sh
OK=1
CRITICAL=0
PROCESS_NUM=$( ps -ef | grep $1 | grep -v "grep "|grep -v "sh"|wc -l )
#echo $PROCESS_NUM
if [ $PROCESS_NUM = $OK ]
then
echo "OK"
elif [ $PROCESS_NUM = $CRITICAL ]
then
echo "CRITICAL"
elif [ $PROCESS_NUM > $OK ]
then
echo "MULTIPLE process are runing"
else
echo "error"
fi
top
두 터미널에서 명령을 실행하고 다음과 같이 이 스크립트를 실행합니다 .
./check-process.sh top
출력은 다음과 0 CRITICAL
같지만 일반 명령을 실행하면 ps -ef |grep -v "grep "| wc -l
두 개의 카운트가 제공됩니다.
답변1
질문에 대한 설명에서 지적했듯이 테스트는 >
산술 비교가 아니라 사전 비교( 2 > 100
예를 들어 정확함)를 수행하지만 일반 출력 리디렉션 연산자가 있는 [[ ... ]]
경우 에만 수행됩니다.[ ... ]
grep -v "grep "
필터링을 통해 grep -v "sh"
출력에서 합법적인 프로세스를 필터링할 수도 있습니다 (예: 프로세스에서 스크립트를 사용 ps
하려는 경우 ).grep
다음 스크립트는 동일한 논리를 구현하지만 다음을 사용합니다 pgrep
.
#!/bin/bash
cmd=$1
pids=( $( pgrep "$cmd" ) )
case "${#pids[@]}" in
0) echo 'No such process' ;;
1) echo 'One such process' ;;
*) echo 'Many such processes'
esac
top
이 스크립트를 인수로 실행하면 다른 top
터미널 에서 명령을 실행하면 보고 됩니다 One such process
.top
Many such processes
예를 들어 다음을 사용하여 변수를 사용합니다.
#!/bin/bash
cmd=$1
pids=( $( pgrep "$cmd" ) )
critical=0
ok=1
case "${#pids[@]}" in
$critical) echo 'No such process' ;;
$ok) echo 'One such process' ;;
*) echo 'Many such processes'
esac
스크립트는 반환된 PID를 pgrep
배열에 저장한 다음(이것이 bash
스크립트가 아닌 sh
스크립트인 이유입니다) 배열의 길이를 테스트합니다.
올바른 적응은 다음과 같습니다 sh
.
#!/bin/sh
cmd=$1
set -- $( pgrep "$cmd" )
critical=0
ok=1
case "$#" in
$critical) echo 'No such process' ;;
$ok) echo 'One such process' ;;
*) echo 'Many such processes'
esac
이 sh
스크립트는 우리가 액세스할 수 있는 유일한 배열인 위치 인수 배열을 사용합니다. 이러한(위치 매개변수)은 pgrep
에서 생성된 PID 로 설정되며 set
이러한 매개변수의 수는 에서 가져옵니다 $#
.