sh 스크립트가 최상위 명령을 계산하지 않습니다

sh 스크립트가 최상위 명령을 계산하지 않습니다

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.topMany 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이러한 매개변수의 수는 에서 가져옵니다 $#.

관련 정보