프로세스가 실행 중인지 확인하는 Linux / Unix 명령?


97

특정 프로세스가 실행 중인지 확인하는 플랫폼 독립적 (Linux / Unix | OSX) 셸 / bash 명령이 필요합니다. 예 mysqld, httpd...이 작업을 수행하는 가장 간단한 방법 / 명령은 무엇입니까?

답변:


168

동안 pidofpgrep실행의 무엇을 결정하기위한 훌륭한 도구, 그들은 불행하게도, 모두 일부 운영 체제에서 사용할 수 없습니다. 확실한 안전 장치는 다음을 사용하는 것입니다.ps cax | grep command

Gentoo Linux의 출력 :

14484? S 0:00 apache2
14667? S 0:00 apache2
19620? SL 0:00 apache2
21132? SS 0:04 apache2

OS X의 출력 :

42582? Z 0 : 00.00 (smbclient)
46529 ?? Z 0 : 00.00 (smbclient)
46539 ?? Z 0 : 00.00 (smbclient)
46547? Z 0 : 00.00 (smbclient)
46586 ?? Z 0 : 00.00 (smbclient)
46594? Z 0 : 00.00 (smbclient)

Linux와 OS X 모두에서 grep은 종료 코드를 반환하므로 프로세스가 발견되었는지 여부를 쉽게 확인할 수 있습니다.

#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

또한 PID 목록을 원하면 해당 PID도 쉽게 grep 할 수 있습니다.

ps cax | grep httpd | grep -o '^ [] * [0-9] *'

Linux 및 OS X에서 동일한 출력 :

3519 3521 3523 3524

다음의 출력은 빈 문자열로, 실행되지 않는 프로세스에 대해이 접근 방식을 안전하게 만듭니다.

에코 ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'

이 접근 방식은 간단한 빈 문자열 테스트를 작성한 다음 발견 된 PID를 반복하는 데 적합합니다.

#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
  echo "Process not running." 1>&2
  exit 1
else
  for PID in $PIDS; do
    echo $PID
  done
fi

실행 권한 (chmod + x 실행 중)을 사용하여 파일 ( "실행 중"이라고 함)에 저장하고 매개 변수를 사용하여 실행하여 테스트 할 수 있습니다. ./running "httpd"

#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

경고!!!

ps axLinux 출력에서 ​​볼 수 있듯이 단순히 출력을 구문 분석하는 것입니다. 이는 단순히 프로세스에서 일치하는 것이 아니라 해당 프로그램에 전달 된 인수도 일치한다는 것을 의미합니다. 이 방법을 사용할 때 가능한 한 구체적으로 작성하는 것이 좋습니다 (예 : ./running "mysql"'mysqld'프로세스와도 일치). which가능한 경우 전체 경로를 확인 하는 데 사용 하는 것이 좋습니다 .


참조 :

http://linux.about.com/od/commands/l/blcmdl1_ps.htm

http://linux.about.com/od/commands/l/blcmdl1_grep.htm


프로세스가 실행 중일 수 있지만 중지되었습니다. 따라서 목표가 mysqld 또는 httpd가 "작동 중"(응답)하는지 테스트하는 것이라면 중지되었는지 여부도 확인해야합니다.
oluc 2013 년

2
미안하지만 의미 론적 관점에서 볼 때 대답은 확실히 옳지 만 프로세스 arg 벡터에서 패턴 일치로 프로세스를 찾으려고 노력하는 것에 완전히 반대합니다. 그러한 접근 방식은 조만간 실패 할 운명입니다 (실제로 더 많은 검사가 필요하다고 말하면서 스스로 인정합니다). 별도의 답변에 내 추천을 추가했습니다.
peterh

6
grep또한 자체가 예 (실행 찾을 수 ps cax | grep randomname있기 때문에 항상 0을 반환 grep발견이 grep randomname) ... (이 분명 희망 한 수정 예를 들어, 프로세스 이름의 첫 글자, 대괄호를 추가하는 것입니다. ps cax | grep [r]andomname.
카일 G.에게

ps cax | rev | cut -f1 -d' ' | rev더 쉬운 구문 분석을 위해 이름 열만 표시합니다.
Tyzoid

1
ps cax명령 이름 전체를 출력하지 못할 수 있습니다. 예를 들어 "chromium-browser"대신 "chromium-browse"를 인쇄합니다.
jarno

24

PID를 알아야합니다!

프로세스 인수 (예 :)에 대해 일종의 패턴 인식을 시도하여 프로세스를 찾는 것은 pgrep "mysqld"조만간 실패 할 운명의 전략입니다. 두 개의 mysqld가 실행되고 있다면 어떨까요? 그 접근법은 잊어 버리세요. 일시적으로 문제를 해결하고 1 ~ 2 년 동안 작동 할 수 있지만 생각하지 못한 일이 발생합니다.

프로세스 ID (pid) 만 진정으로 고유합니다.

백그라운드에서 무언가를 시작할 때 항상 pid를 저장하십시오. Bash에서는 Bash $!변수를 사용하여 수행 할 수 있습니다 . 그렇게함으로써 많은 문제를 해결할 수 있습니다.

프로세스가 실행 중인지 확인하는 방법 (pid로)

이제 질문은 pid가 실행 중인지 아는 방법이됩니다.

간단하게 :

ps -o pid = -p <pid>

이것은 POSIX이므로 이식 가능합니다. 프로세스가 실행 중이면 pid 자체를 반환하고 프로세스가 실행 중이 아니면 아무것도 반환하지 않습니다. 엄밀히 말하면이 명령은 단일 열인을 반환 pid하지만 빈 제목 헤더 (등호 바로 앞의 항목)를 지정했기 때문에 요청 된 유일한 열이므로 ps 명령은 헤더를 전혀 사용하지 않습니다. 파싱이 더 쉬워지기 때문에 우리가 원하는 것입니다.

이것은 Linux, BSD, Solaris 등에서 작동합니다.

또 다른 전략은 위 ps명령 의 종료 값을 테스트하는 것 입니다. 프로세스가 실행 중이면 0이고 그렇지 않으면 0이 아닙니다. POSIX 사양에 따르면 ps오류가 발생하면> 0을 종료해야하지만 '오류'를 구성하는 것이 무엇인지 명확하지 않습니다. 따라서 모든 유닉스 / 리눅스 플랫폼에서 잘 작동 할 것이라고 확신하지만 개인적으로이 전략을 사용하지는 않습니다.


1
이것은 서비스가 실행 중인지 확인하는 질문에 대한 답변이 아닙니다. 이러한 경우 PID 알 수 없으므로이 답변은 PID를 아는 경우에만 유효합니다 .
생명의 고속도로

2
잘못된. 내 의견의 요점은 한 걸음 물러서서 grep <sometext>주어진 프로세스를 찾기 위해 어떤 형태를 취해야하는 상황에 처해 있다면 IMHO라는 프로세스를 시작할 때 뭔가 잘못한 것이라고 말하는 것입니다 . 나는 OP의 질문에서 실제로 그가 프로세스가 시작되는 방법을 제어 할 수 있다는 것을 취합니다.
peterh

2
OP 질문에 대한 더 정확한 "용어"는 "서비스가 실행 중인지 확인하는 교차 플랫폼 명령"이어야합니다. 확인을 실행하는 동일한 시스템이 아니라 외부 시스템이므로 PID는 전혀 알려져 있습니다.
생명의 고속도로

2
이것은 절대 안전한 것이 아닙니다. 관심있는 프로세스는 PID가 래핑 될 수있을만큼 시스템이 충분히 가동 된 후 종료되었을 수 있으며, 확인중인 것과 동일한 PID가 다른 프로세스에 할당되었을 수 있습니다. stackoverflow.com/questions/11323410/linux-pid-recycling
클레이 메이션

1
@claymation. 공정한 포인트. 그러나 PID 충돌은 실수로 동일한 서비스의 두 인스턴스를 시작하는 것보다 훨씬 적기 때문에 프로세스 인수에 대한 패턴 일치보다 PID 방법이 여전히 좋습니다. 내 2 센트. :-)
peterh

15

대부분의 Linux 배포에서는 pidof(8)을 사용할 수 있습니다 .

지정된 프로세스의 실행중인 모든 인스턴스의 프로세스 ID를 인쇄하거나 실행중인 인스턴스가 없으면 아무것도 인쇄하지 않습니다.

예를 들어, 내 시스템에서 (4 개의 인스턴스 bash와 1 개의 remmina실행 인스턴스가 있음 ) :

$ pidof bash remmina
6148 6147 6144 5603 21598

다른 Unices에서 pgrep또는 psand 의 조합은 grep다른 사람들이 정당하게 지적했듯이 동일한 것을 달성합니다.


+1 pidof httpd은 Red Hat 5에서 잘 작동하지만 내 Red Hat 4 pidof에는 존재하지 않습니다. :-(
olibre

사실,이 명령은 내가 생각했던 것보다 덜 널리 퍼져 있습니다. 저는 이것을 더 명확하게하기 위해 제 대답을 편집했습니다.
Frédéric Hamidi

참으로 좋은 깨끗한 대답. (지원되는 시스템에서). 감사합니다.
Mtl Dev

7

이것은 대부분의 Unix, BSD 및 Linux에서 작동합니다.

PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep

테스트 대상 :

  • SunOS 5.10 [따라서 PATH=...]
  • Linux 2.6.32 (CentOS)
  • Linux 3.0.0 (Ubuntu)
  • 다윈 11.2.0
  • FreeBSD 9.0- 안정
  • Red Hat Enterprise Linux ES 릴리스 4
  • Red Hat Enterprise Linux Server 릴리스 5

2
+1 예 간단히 ps. 두 번째를 피하기 위해 grep나는 제안한다 :ps aux | grep [h]ttpd
olibre

여기서는 변수를 main에 쉽게 넣을 수 있도록 대괄호 트릭을 사용하지 않았습니다 grep.
Johnsyweb

1
좋아요;) 방금 Red Hat AS 4 및 Red Hat AP 5에서 테스트했습니다. 물론 작동합니다! 따라서 Red Hat Enterprise Linux ES 릴리스 4Red Hat Enterprise Linux Server 릴리스 5를 목록에 추가 할 수 있습니다 . 건배
olibre 2012

@Downvoter : 왜? 내가 놓친 게 무엇입니까? 내가 말할 수있는 한, 받아 들여지는 대답은 동일한 조회를 수행하는 것입니다!
Johnsyweb 2012

6

가장 간단한 방법은 ps 및 grep을 사용하는 것입니다.

command="httpd"
running=`ps ax | grep -v grep | grep $command | wc -l`
if [ running -gt 0 ]; then
    echo "Command is running"
else
    echo "Command is not running"
fi

명령에 일부 명령 인수가있는 경우 'grep $ command'뒤에 'grep cmd_arg1'을 추가하여 관심이없는 다른 가능한 프로세스를 필터링 할 수도 있습니다.

예 : 제공된 인수가있는 Java 프로세스가있는 경우 표시 :

-Djava.util.logging.config.file = logging.properties

실행 중

ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l

2
실제로를 사용 ps cax하면 grep -v. 예를 들어 다음을 사용할 수 있습니다 ps cax | grep java > /dev/null || echo "Java not running"..
생명의 고속도로

1
세 번째 줄에 실수가 있습니다. "running"을 "$ running"으로 변경하십시오.
프로그래머

5

사소한 추가 : -cps에 플래그를 추가하면 grep -v나중에 grep 프로세스를 포함하는 행을 제거 할 필요가 없습니다 . 즉

ps acux | grep cron

bsd-ish 시스템에서 필요한 모든 타이핑입니다 (MacOSX 포함) -u. 정보가 덜 필요 하면 자리를 비울 수 있습니다 .

기본 ps명령 의 유전학이 SysV를 다시 가리키는 시스템에서는 다음을 사용합니다.

ps -e |grep cron

또는

ps -el |grep cron 

pid 및 프로세스 이름 이상을 포함하는 목록의 경우. 물론 -o <field,field,...>옵션을 사용하여 인쇄 할 특정 필드를 선택할 수 있습니다.


이 답변은 어떻게 이식 가능합니까? (여러 플랫폼에서 서로 다른 형태의 ps 명령을 사용해야한다고
말합니다.

ps 불행히도 조상에 따라 동일한 결과에 대해 다른 옵션 세트를 가진 도구 중 하나입니다. 따라서이 문제에 대해 자신 만의 (다른 것과 호환되지 않는) 래퍼를 작성하지 않는 한, 갈 길은 유산의 주요 라인을 알고 그에 따라 적응하는 것입니다. 스크립팅 할 때는 다릅니다. 이러한 차이점을 사용하여 현재 어떤 브랜치에 있는지 확인하고 스크립트의 동작을 조정합니다. 결론 : 둘 다 알아야합니다. 유명한 예 : Larry Wall의 "configure"스크립트. 유명한 인용문 : 축하합니다. 당신은 유니스를 운영하지 않습니다.
Tatjana Heuser 씨

5

다양한 제안을 종합 해보면, (단어의 일부를 트리거하는 신뢰할 수없는 grep없이) 생각 해낼 수 있었던 가장 깨끗한 버전은 다음과 같습니다.

kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

kill -0은 프로세스를 종료하지 않지만 존재하는지 확인한 다음 true를 반환합니다. 시스템에 pidof가 없으면 프로세스를 시작할 때 pid를 저장합니다.

$ mysql &
$ echo $! > pid_stored

그런 다음 스크립트에서 :

kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

3

사용 pgrep -l httpd하지만 어떤 플랫폼에도 있는지 확실하지 않습니다.
누가 OSX에서 확인할 수 있습니까?


감사합니다 @Johnsyweb. 확인해 주 pidof시겠습니까? 알았어. 감사합니다. 그래서 우리는 OSX에서 작동하는 다른 것을 찾아야합니다 ... 당신의 기본 ps|grep은 단일 솔루션 일 수 있습니다 ;-)
olibre

1

프로세스의 PID를 알아야합니다.

실행하면 PID가 $!변수에 기록됩니다 . 이 PID를 파일에 저장하십시오.

그런 다음이 PID가 실행중인 프로세스에 해당하는지 확인해야합니다. 다음은 완전한 스켈레톤 스크립트입니다.

FILE="/tmp/myapp.pid"

if [ -f $FILE ];
then
   PID=$(cat $FILE)
else
   PID=1
fi

ps -o pid= -p $PID
if [ $? -eq 0 ]; then
  echo "Process already running."  
else
  echo "Starting process."
  run_my_app &
  echo $! > $FILE
fi

답변 을 기반으로합니다 peterh. 주어진 PID가 실행 중인지 아는 트릭은 ps -o pid= -p $PID명령어에 있습니다.


0

이 접근법은 'ps', 'pidof'및 rest 명령을 사용할 수없는 경우에 사용할 수 있습니다. 저는 개인적으로 도구 / 스크립트 / 프로그램에서 procfs를 매우 자주 사용합니다.

   egrep -m1  "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3

무슨 일이 일어나고 있는지 약간의 설명 :

  1. -m1-첫 번째 일치에서 프로세스 중지
  2. "mysqld $ | httpd $"-grep은 mysqld 또는 httpd에서 끝나는 행과 일치합니다.
  3. / proc / [0-9] *-bash는 임의의 숫자로 시작하는 행과 일치합니다.
  4. cut-구분 기호 '/'로 출력을 분할하고 필드 3을 추출합니다.

0

이것은 기본 이름이 "chromium-browser"인 프로세스 수를 인쇄합니다.

ps -e -o args= | awk 'BEGIN{c=0}{
 if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets.
 if($1==cmd){c++}
}END{print c}' cmd="chromium-browser"

"0"이 인쇄되면 프로세스가 실행되고 있지 않습니다. 이 명령은 프로세스 경로에 구분 공백이 없다고 가정합니다. 일시 중단 된 프로세스 나 좀비 프로세스로 이것을 테스트하지 않았습니다.

Linux gwak에서 awk대안으로 사용하여 테스트했습니다 .

다음은 몇 가지 예제 사용과 함께 더 다양한 솔루션입니다.

#!/bin/sh
isProcessRunning() {
if [ "${1-}" = "-q" ]; then
 local quiet=1;
 shift
else
 local quiet=0;
fi
ps -e -o pid,args= | awk 'BEGIN{status=1}{
 name=$2
 if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets.
 if(name==cmd){status=0; if(q){exit}else{print $0}}
}END{exit status}' cmd="$1" q=$quiet
}

process='chromium-browser'

printf "Process \"${process}\" is "
if isProcessRunning -q "$process" 
 then printf "running.\n"
 else printf "not running.\n"; fi

printf "Listing of matching processes (PID and process name with command line arguments):\n"
isProcessRunning "$process"

0

여기 내 버전입니다. 풍모:

  • 정확한 프로그램 이름 (함수의 첫 번째 인수)을 확인합니다. "mysql"검색은 "mysqld"실행과 일치하지 않습니다.
  • 프로그램 인수 (함수의 두 번째 인수)를 검색합니다.

스크립트:

#!/bin/bash

# $1 - cmd
# $2 - args
# return: 0 - no error, running; 1 - error, not running
function isRunning() {
    for i in $(pidof $1); do
        cat /proc/$i/cmdline | tr '\000' ' ' | grep -F -e "$2" 1>&2> /dev/null
        if [ $? -eq 0 ]; then
            return 0
        fi
    done
    return 1
}

isRunning java "-Djava.util.logging.config.file=logging.properties"
if [ $? -ne 0 ]; then
    echo "not running, starting..."
fi

0

대답 중 어느 것도 나를 위해 일하지 않았으므로 여기에 내 것입니다.

process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
  echo "Process is not running."
else
  echo "Process is running."
fi

설명:

|tr -d '\n'

이렇게하면 터미널에서 만든 캐리지 리턴이 제거됩니다. 나머지는 게시물에서 설명 할 수 있습니다 .


-1

POSIX 표준 명령 및 옵션만을 기반으로하는 다음 셸 기능은 대부분의 Unix 및 Linux 시스템에서 작동합니다. :

isPidRunning() {
  cmd=`
    PATH=\`getconf PATH\` export PATH
    ps -e -o pid= -o comm= |
      awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}'
  `
  [ -n "$cmd" ] &&
    printf "%s is running\n%s\n\n" "$1" "$cmd" ||
    printf "%s is not running\n\n" $1
  [ -n "$cmd" ]
}

$ isPidRunning httpd
httpd is running
586 /usr/apache/bin/httpd
588 /usr/apache/bin/httpd

$ isPidRunning ksh
ksh is running
5230 ksh

$ isPidRunning bash
bash is not running

모호한 "0]"명령 이름이 전달되면 질식하고 이름에 공백이 포함 된 프로세스를 식별하지 못합니다.

가장 많이 찬성되고 수용된 솔루션은 이식성이없는 ps옵션을 필요로 하며 인기에도 불구하고 모든 Unix / Linux 시스템에 존재한다고 보장 할 수없는 셸을 무상으로 사용합니다 ( bash).


$ isPidRunning 0]예를 들어 "0]이 실행 중입니다. 3 [ksoftirqd / 0] 8 [rcuop / 0] 17 [rcuos / 0] 26 [rcuob / 0] 34 [migration / 0] 35 [watchdog / 0]"여기에서.
jarno 2015-06-19

그 PATH는 무엇을 위해 필요합니까?
jarno 2015-06-20

여기 에서 솔루션을 더 개발했습니다 .
jarno 2015-06-20

@jarno PATH 설정은 스크립트를 이식하기위한 요구 사항입니다. 그렇지 않으면 적어도 Solaris 10 및 이전 버전 및 기타 Unix 구현에서 실패합니다.
jlliagre

1
@jarno 나는 그것을 할 수 있지만 awk에 대해서도이 PATH 설정을 반복해야합니다. POSIX 이전 구문 bourne 쉘로 이식 할 수 있도록 이전 백틱 구문으로 되돌 렸습니다.
jlliagre 2015-06-22
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.