프로세스 ID (PID)가 있는지 확인하는 방법


184

bash 스크립트에서 다음을 수행하려고합니다 (의사 코드로).

if [ a process exists with $PID ]; then

    kill $PID 

fi

조건문에 대한 적절한 표현은 무엇입니까?

답변:


182

프로세스가 있는지 확인하려면 다음을 사용하십시오.

kill -0 $pid

그러나 @unwind가 말했듯이 어쨌든 그것을 죽이려면

kill $pid

또는 경쟁 조건이 있습니다.

kill종료 코드를 기반으로 텍스트 출력을 무시하고 무언가를 수행 하려는 경우

if ! kill $pid > /dev/null 2>&1; then
    echo "Could not send SIGTERM to process $pid" >&2
fi

1
매뉴얼 페이지를 보면 kill -0은 "종료 코드는 신호가 전송 될 수 있음을 나타냅니다"입니다. 실제로이 프로세스가 프로세스를 종료 시키거나 프로세스가 종료 될 수 있는지 여부를 알려줍니까?
Richard H

24
kill프로세스를 죽일 필요는 없다는 점에서 다소 잘못 명명되었습니다. 프로세스에 신호를 보냅니다. kill $PIDkill -15 $PID신호 15, SIGTERM을 프로세스로 보내는 명령 과 동일하며 이는 종료 명령입니다. 신호 0이 없습니다. 이는 신호 kill가 프로세스로 전송 될 수 있는지 여부를 확인 하는 특수한 값입니다 . 이는 대부분의 경우 존재 여부를 확인하는 것과 거의 비슷합니다. linux.die.net/man/2/killlinux.die.net/man/7/signal
Christoffer Hammarström 2016 년

43
실행중인 사용자가 프로세스를 소유하지 않으면 kill -0을 호출 할 권한이 없을 수 있습니다. ps -p $ PID> / dev / null 2> & 1을 사용하는 것이 좋습니다. 신호를 보낼 권한이없는 경우에도 프로세스 상태를 볼 수 있습니다.
mckoss

6
@ mckoss :이 경우 그는 어쨌든 그것을 죽일 수 없습니다.
Christoffer Hammarström

2
그래서, 나는 kill -0실제로 사용 하기 위해 이것을해야한다고 생각합니다 : kill -0 25667 ; echo $?-그리고 나서 0반환을 얻으면 그 PID를 가진 프로세스가 종료 될 수 있습니다. 프로세스 PID (예 :)가 존재하지 않는 경우 $?1실패를 나타냅니다. 그 맞습니까?
sdaau

264

가장 좋은 방법은 다음과 같습니다.

if ps -p $PID > /dev/null
then
   echo "$PID is running"
   # Do something knowing the pid exists, i.e. the process with $PID is running
fi

문제 :

kill -0 $PID

pid가 실행 중이고 종료 권한이 없어도 종료 코드는 0이 아닙니다. 예를 들면 다음과 같습니다.

kill -0 1

kill -0 $non-running-pid

일반 사용자를 위해 구별 할 수없는 (0이 아닌) 종료 코드를 가지고 있지만 초기화 프로세스 (PID 1)가 확실히 실행 중입니다.

토론

테스트의 본문이 "킬"인 경우 킬 및 레이스 조건에 대한 답변은 정확합니다. 나는 일반적인 " bash에서의 PID 존재를 어떻게 테스트 하는가 "를 찾고왔다 .

/ proc 메소드는 흥미롭지 만 어떤 의미에서는 "ps"명령 추상화의 정신을 깨뜨립니다. 즉, Linus가 "exe"파일을 다른 것으로 호출하기로 결정한 경우 어떻게해야합니까?


1
ps -p는 항상 0 상태를 반환합니다.
IttayD

1
ps -p ####는 우분투 14.04에서 잘 작동했습니다. +1 감사합니다!
Ligemer

3
그렇지 실행중인 프로세스를 일치 할 때 그 과정의 빈 목록을 인쇄하기 때문에 PS -p 항상 OS X의에서 상태 코드 0을 반환
더글러스 코레아에게

macOS Sierra에서 작동하는지 확인할 수 있습니다. 또한 -p적어도 그 경우에는 불필요합니다. ps $PID결과는 동일합니다.
user137369

이식성은 / proc를 사용하지 않는 좋은 이유이지만 리눅스가 ABI를 깨는 것은 특히 걱정할만한 시나리오가 아닙니다.
David Roundy

67
if [ -n "$PID" -a -e /proc/$PID ]; then
    echo "process exists"
fi

또는

if [ -n "$(ps -p $PID -o pid=)" ]

후자의 형식에서는 -o pid=헤더가없는 프로세스 ID 열만 표시하기위한 출력 형식입니다. 비어 있지 않은 문자열 연산자 가 유효한 결과를 제공하려면 따옴표가 필요 합니다 -n.


1
두 번째 방법은 추가 기능으로 Mac에서도 작동합니다 (Mac OS X에는 / proc FS가 없음). 그러나 서브 쉘을 사용하지 않고 Mac과 Linux 모두에서이를 사용할 수 있습니다.if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
Will

안타깝게도 ps옵션과 기능은 플랫폼마다 다르므로 여전히 완전히 이식 가능한 것은 아닙니다.
tripleee

1
$PID비어있는 경우 디렉토리가 여전히 존재 [ -e /proc/$PID ]하므로 여전히 true를 리턴 /proc/합니다.
Magne

34

ps와 함께 명령을 수행 -p $PID할 수 있습니다 :

$ ps -p 3531
  PID TTY          TIME CMD
 3531 ?        00:03:07 emacs

11

두 가지 방법이 있습니다.

내 노트북에서 특정 응용 프로그램을 찾아 보자.

[root@pinky:~]# ps fax | grep mozilla
 3358 ?        S      0:00  \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2    S+     0:00              \_ grep mozilla

모든 예제는 이제 PID 3358을 찾습니다.

첫 번째 방법 : "ps aux"를 실행하고 두 번째 열에서 PID를 grep하십시오. 이 예제에서는 firefox를 찾은 다음 PID를 찾습니다.

[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358

따라서 코드는 다음과 같습니다.

if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
    kill $PID 
fi

두 번째 방법 : /proc/$PID디렉토리 에서 무언가를 찾으십시오 . 이 예에서는 "exe"를 사용하고 있지만 다른 것을 사용할 수 있습니다.

[root@pinky:~]# ls -l /proc/3358/exe 
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash

따라서 코드는 다음과 같습니다.

if [ -f /proc/$PID/exe ]; then
    kill $PID 
fi

BTW : 무엇이 잘못 되었나요 kill -9 $PID || true?


편집하다:

몇 달 동안 그것에 대해 생각한 후에 .. (약 24 ...) 내가 여기에 낸 원래의 아이디어는 훌륭한 해킹이지만, 매우 이식하기 어려운 것입니다. Linux에 대한 몇 가지 구현 세부 사항을 가르치고 있지만 Mac, Solaris 또는 * BSD에서는 작동하지 않습니다. 향후 Linux 커널에서는 실패 할 수도 있습니다. 다른 답변에서 설명한대로 "ps"를 사용하십시오.


적어도 kill -9 부분은 잘못된 것 같습니다 (하위 프로세스를 죽이지 않음)
nurettin

첫 번째 방법을 사용할 때 왜 [: missing`] '가 표시됩니까?
tenmiles

1
/proc/$PID/exe일반 파일이 아닙니다. 따라서 [ -f /proc/$PID/exe ]항상 false결과를 반환합니다 . 시도하십시오 [ -h /proc/$PID/exe ].
Alexander Yancharuk

8

네가 원하는 것 같아

wait $PID

$pid완료 되면 반환됩니다 .

그렇지 않으면 사용할 수 있습니다

ps -p $PID

프로세스가 여전히 살아 있는지 확인하십시오 ( kill -0 $pidpid를 소유하지 않아도 작동하기 때문에 보다 효과적입니다 ).


1
기다리는 과정이 현재 포탄의 자식이어야하므로 효과적이지 않습니다.pid 123 is not a child of this shell
Calumah

7

나는 이것이 나쁜 해결책이라고 생각합니다. 테스트와 테스트 요청 사이에 프로세스가 종료되면 어떻게됩니까? 그러면 죽일 것입니다. 그렇다면 모든 경우에 킬을 시도하고 반환 값을 확인하여 어떻게 진행되었는지 확인하십시오.


+1 불행히도 kill (1)의 종료 코드는 다른 오류 상황을 구별하지 않습니다 (신호 처리에 실패한 각 프로세스마다 종료 값을 하나씩 증가시키는 것처럼 보입니다). OP가 자체 kill (2) 래퍼를 작성하는 것을 신경 쓰지 않으면 kill (2) 호출이 실패한 후 ERRNO 값에 따라 다른 값으로 종료되도록 할 수 있습니다.
단지 누군가

지금은 확인하지 않고 kill -9를하고 있습니다-존재하지 않으면 "프로세스가 존재하지 않습니다"라는 오류가 발생합니다. 무슨 일이 있었는지 어떻게 테스트합니까?
Richard H

14
부주의하지 마십시오 kill -9. 그것은 프로세스를 즉시 중단시켜 자체적으로 정리할 기회를 제공하지 않습니다. 대신 kill에 해당 하는를 사용하십시오 kill -15. 그래도 문제가 해결되지 않으면 이유를 찾아야하며 최후의 수단으로 만 사용해야 kill -9합니다.
Christoffer Hammarström 2016 년

0

여기서 PID를 .pid (/ run / ...와 같은 파일) 파일에 저장하고 아직 실행되지 않은 경우에만 스크립트를 실행합니다.

#!/bin/bash
if [ -f .pid ]; then
  read pid < .pid
  echo $pid
  ps -p $pid > /dev/null
  r=$?
  if [ $r -eq 0 ]; then
    echo "$pid is currently running, not executing $0 twice, exiting now..."
    exit 1
  fi
fi

echo $$ > .pid

# do things here

rm .pid

참고 : pid가 어떻게 호출되는지 확인하지 않으므로 경쟁 조건이 있습니다. 시스템이 재부팅되고 .pid가 존재하지만 다른 응용 프로그램에서 사용되는 경우 '예기치 않은 결과'가 발생할 수 있습니다.


0

예를 들어 GNU / Linux에서는 다음을 사용할 수 있습니다.

Pid=$(pidof `process_name`)

if [ $Pid > 0 ]; then

   do something
else

   do something
fi 

아니면 같은

Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN

앱 이름과 ID가없는 이름 만 표시됩니다.


1
pidof음수 PID는 의미가 없으므로 음수를 반환하지 않으므로 kill 할 수 없으므로 init조건부에는 의미가 없습니다 (또한 >리디렉션을 수행하지 못하게 하려면 이스케이프해야합니다 ). 당신은 빈 결과를 확인하기를 원하지만 물론, 어떤 점잖은 도구처럼, pidof그것은 작동 여부를 적절한 솔루션입니다, 그래서 당신에게하는 종료 코드를 설정 if Pid=$(pidof 'process_name'); then ...하거나 (당신이 값이 필요하지 않을 경우 Pid나중에) 단지를if pidof 'process_name'; then...
tripleee

@tripleee가 맞습니다.이 pidof예제는 bash test작동 방식 에 대한 오해로 가득 합니다. gnu.org/software/bash/manual/html_node/…
Bruno Bronosky

0

아래 코드는 내 프로세스가 실행 중인지 확인합니다.

프로세스가 실행되고 있지 않은 경우에만 매시간 Amazon SQS에서 새 메시지를 확인하십시오.

#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
    /usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
    echo "do nothing, just smile =)"
fi
exit $?
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.