주어진 PID가 실행 중인지 어떻게 확인해야합니까?


16

PID를 수집하기 위해 로그 파일을 구문 분석하고 해당 PID가 실행 중인지 확인하는 Perl 스크립트를 작성 중입니다. 확인하는 가장 좋은 방법을 생각하고 있습니다. 분명히, 나는 다음과 같은 것을 할 수 있습니다 :

system("ps $pid > /dev/null") && print "Not running\n";

그러나 가능한 경우 시스템 호출을 피하고 싶습니다. 따라서 /proc파일 시스템을 사용할 수 있다고 생각했습니다 (이동성은 문제가되지 않으며 항상 Linux 시스템에서 실행됩니다). 예를 들면 다음과 같습니다.

if(! -d "/proc/$pid"){
    print "Not running\n";
}

안전한가요? /proc/$pid/디렉토리가 없으면 연관된 PID가 실행되고 있지 않다고 항상 가정 할 수 있습니까 ? 어쨌든 AFAIK ps자체가 정보를 얻었 으므로 기대 /proc하지만 이것이 프로덕션 코드 용이므로 확실합니다.

따라서 실행중인 프로세스에 /proc/PID디렉토리가 없거나 /proc/PID디렉토리가 있고 프로세스가 실행되고 있지 않은 경우가 있습니까? ps디렉토리가 있는지 확인 하는 것보다 구문 분석을 선호하는 이유가 있습니까?


2
또한 kill신호 0을 사용 하는 펄 함수가 있습니다.
meuh

1
Linux 에서이 작업을 수행하는 경우 '/ proc / $ PID'는 괜찮습니다.
likewhoa

7
@terdon 당신이 사용하는 (그리고 kill -0가장 좋은 방법이 무엇이든 ), 이것은 주어진 PID로 실행중인 프로세스가 있는지 여부를 알려줍니다 . 프로세스가 1 밀리 초 후에도 계속 실행 될지 여부를 알려주지 않으며, 프로세스가 관심있는 프로세스인지 또는 흥미로운 프로세스가 종료 된 후 동일한 PID가 지정된 관련되지 않은 프로세스인지 여부를 알려주지 않습니다. . 주어진 PID가 실행 중인지 테스트하는 것은 거의 항상 실수 입니다. 경쟁 조건에 취약하지 않은 환경은 거의 없습니다.
Gilles 'SO- 악 그만

1
@Gilles, 프로세스 이름도 확인해야합니다. 그러나이 경우 1 밀리 초 후에 상태 변경이 있는지는 중요하지 않습니다. dB에서 활성으로 표시된 프로세스와 pid가있는 해당 파일이 있습니다. DB가 실행 중이라고 생각하는 것이 실제로 실행되고 있지 않은지 확인하고 무작위로 다시 시작할 수 없다는 것을 알기 위해 설정을 충분히 제어 할 수 있습니다.
terdon

3
@MickLH 와우, 저에게 들었습니다. 그것은 당신이 그렇게 나쁘고 위험한 것을 설명하기 위해 귀찮게 한 당신 자신의 광채를 축하하는 대신 실제로 유용한 의견이었습니다. 나는 당신이 옳다는 것을 의심하지 않습니다. 나는 프로그래머라고 주장한 적이 없기 때문에 질문을 한 이유는 있지만 모욕적이고 도움이되지 못했습니다.
terdon

답변:


20

펄 함수 kill(0,$pid) 사용할 수 있습니다.

리턴 코드가 1이면 PID가 존재하며 신호를 보낼 수 있습니다.

리턴 코드가 0이면 $!를 확인해야합니다. 프로세스가 존재 함을 의미하는 EPERM (권한 거부)이거나 프로세스가 존재하지 않는 경우 ESRCH 일 수 있습니다.

확인 코드가 다음과 같이 실행중인 경우 root kill 리턴 코드를 점검하여이를 단순화 할 수 있습니다. 0 => 오류, 1 => 확인

예를 들면 다음과 같습니다.

% perl -d -e 0

Loading DB routines from perl5db.pl version 1.37
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(-e:1):   0
  DB<1> print kill(0,500)
0
  DB<2> print $!
No such process
  DB<3> print kill(0,1)
0
  DB<4> print $!
Operation not permitted
  DB<5> print kill(0,$$)
1

이것은 간단한 기능으로 만들 수 있습니다

use Errno;

sub test_pid($)
{
  my ($pid)=@_;

  my $not_present=(!kill(0,$pid) && $! == Errno::ESRCH);

  return($not_present);
}

print "PID 500 not present\n" if test_pid(500);
print "PID 1 not present\n" if test_pid(1);
print "PID $$ not present\n" if test_pid($$);

FWIW, 나는 당신이 이것을 할 수있는 방법을 보여주는 간단한 기능을 추가했습니다.
Stephen Harris

그래, 나는 이것과 함께 갈 것이라고 생각한다. 필요한 모든 것이 if (!kill(0,$pid) && $! =~ /No such process/){ exit; }비슷 하다는 것을 알기 때문에 의견을 삭제했습니다 . 당신처럼 내가 Errno더 나은 생각 솔루션, 감사합니다. 아마도 이것과 함께 갈 것이지만, 누군가 근본적인 Linux 질문에 대답 할 수 있도록 잠시 기다릴 것입니다.
terdon

2
경우 /procIS가 탑재 된 다음 있도록 공간에서 볼 수있는 모든 PID는 존재합니다 -d /proc/$pid테스트 일 ...하지만 오히려 기본 시스템 호출을 사용하는 것보다 파일 시스템에 외출이 포함됩니다.
Stephen Harris

정확히 내가 피하고 싶었던 것입니다.
terdon

2
@ terdon : 나는 단지 "시스템 호출"이 실제로 " system호출"을 의미한다는 사실에서 혼란을 겪었다는 것을 깨달았다. 즉 "시스템 호출"이system 아니라 함수 자체에 대한 호출 . 후자는 피할 수 없지만 전자는 피할 수 없습니다. 이제 말이 되네요!
user541686

6
  • 나는 99.9 % 가 존재 하는지 (그리고 디렉토리 인지) 확인하는 것이 기술 만큼 신뢰할 수 있는지 98 % 확신합니다 . 98 %가 100 %가 아닌 이유는 Stephen Harris가 주석에서 손을 대고 튕겨 버린 지점입니다. 즉, 파일 시스템이 마운트되지 않았을 수 있습니다. 그것은 제에 유효 할 수없는 리눅스 시스템 손상, 저하 된 시스템입니다 - 모든 후, 일이 좋아 , 하고/proc/PIDkill 0/proc/procpstoplsof 아마 작동하지 않습니다 -이 힘 프로덕션 시스템에 문제가되지 않도록. 그러나 (이론적으로는) 마운트되지 않은 것이 가능합니다 (시스템이 정상 상태가되는 것을 막을 수는 있지만) 확실히 마운트 해제 될 수 있습니다 (테스트했습니다 1), 그리고 그것이 존재할 것이라는 보장이 없다고 생각합니다 (즉, POSIX에 필요하지 않음). 그리고 시스템이 완전히 호스로 연결되어 있지 않으면 kill작동합니다.
  • Stephen의 의견은 "파일 시스템으로 나가기"및 "기본 시스템 호출 사용"에 대해 설명합니다. 나는 이것이 주로 붉은 청어라고 생각합니다.
    • 예, 액세스를 시도 /proc 하려면 파일 시스템 을 찾기 위해 루트 디렉토리를 읽어야합니다 /proc. 이 시도가 액세스 마찬가지입니다 어떤 에서 일을 포함하여, 절대 경로로 파일을 /bin, /etc하고 /dev. 루트 디렉토리가 시스템의 전체 수명 (가동 시간) 동안 반드시 메모리에 캐시되기 때문에 디스크 I / O없이이 단계를 수행 할 수 있습니다. 그리고 일단 inode /proc가 있으면 다른 모든 일은 메모리에 있습니다.
    • 어떻게 액세스 /proc합니까? 와 stat, open, readdir, 등의 기본 시스템은만큼 모든 비트를 호출있는 kill.
  • 이 질문은 프로세스 실행에 대해 이야기합니다. 이것은 미끄러운 문구입니다. 실제로 프로세스가 실행 중인지 (예 : 실행 큐에서, 일부 CPU의 현재 프로세스, 휴면, 대기 또는 중지되지 않은지) 테스트하려는 경우 a를 수행 하고 출력을 읽 거나 . 그러나 나는 당신이 이것에 대해 당신의 질문이나 의견에 힌트를 보지 못합니다.ps PID /proc/PID/stat

    그러나 방 안에있는 코끼리는 좀비 2 프로세스가 살아있는 프로세스와 구별하기 어려울 수 있다는 것입니다.  kill 0좀비에서 작동하며 존재합니다. 이전 단락에 나열된 기술을 사용하여 좀비를 식별 할 수 있습니다 ( 출력 수행 및 읽기 또는 ). 내 매우 빠른 & 캐주얼 (즉, 매우 철저하지 않음) 테스트 당신은 또한을 수행하여이 작업을 수행 할 수 있음을 시사 나 에 , 또는 -이 좀비에 실패합니다. 그러나 소유하지 않은 프로세스에서도 실패합니다./proc/PIDps PID/proc/PID/statreadlinklstat/proc/PID/cwd/proc/PID/root/proc/PID/exe

____________
1  경우 -f( f를 ORCE) 옵션이하지 않는 일, 시도 -l( 리터 AZY).
2  즉, 종료 된 프로세스는 / / 종료 죽었지 만 그의 부모는 아직 일을하지 않았습니다 wait.


답변이 잘못되어 삭제 한 내 답변에 대한 귀하의 의견에 감사드립니다. kill(2)맨 페이지가 사용자가 지적한 동작을 직접 나타내는 것으로 생각하지 않지만 perlfunc맨 페이지는 그렇지 않습니다. Michael Kerrisk에게 전자 메일을 보내 시스템 맨 페이지에 대해 말한 내용을 확인하겠습니다.
jrw32982는 Monica

kill(2)신호 0을 "보내기"권한 에 대한 맨 페이지를 명확하게하기 위해 버그 보고서를 제출했습니다.
jrw32982는 Monica

@ jrw32982 : 글쎄, 그 사람 페이지가 가지는 "좋아 말한다 시그 "경우 오류 검사가 ... 수행되는, 0이 될 수 있습니다 ... 인수를 "및 에러 - 죽 () 시스템 호출이 실패하고 신호가있는 경우 전송되지 않습니다 : … 전송 프로세스가 수퍼 유저가 아니며 유효 사용자 ID가 수신 프로세스의 유효 사용자 ID와 일치하지 않습니다. …”이제 언급했듯이, 여러 가지 방법으로 해석 될 수 있지만 유감스럽게도 많은 유닉스 매뉴얼 페이지가이 스타일로 작성되어 있으므로 줄 사이를 읽어야합니다. 마이클은 그것이 충분히 명확하다고 믿을 수도 있습니다.
G-남자 '는 분석 재개 모니카'말한다

Michael은 kill(2)맨 페이지를 변경 했습니다 (아직 온라인에 표시되지 않음). "시그가 0이면 신호가 전송되지 않지만 존재 및 권한 검사는 여전히 수행됩니다.이 정보를 사용하여 발신자가 신호를 보낼 수있는 프로세스 ID 또는 프로세스 그룹 ID "
jrw32982는 Monica
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.