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

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

나는 로그 파일을 구문 분석하여 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디렉토리가 존재하는지 확인하는 대신 구문 분석을 선호하는 이유가 있습니까 ?

답변1

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

반환 코드가 1이면 PID가 존재하며 여기에 신호를 보낼 수 있습니다.

반환 코드가 0이면 $!를 확인해야 합니다. 프로세스가 존재함을 의미하는 EPERM(Permission Denied) 또는 프로세스가 존재하지 않는 경우 ESRCH일 수 있습니다.

검사 코드가 실행 중이면 rootkill 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($$);

답변2

  • 나는 디렉토리가 존재하는지(그리고 디렉토리인지) 확인하는 것이 이 기술만큼 98% 신뢰할 수 있다고 99.9% 확신합니다. 98%가 100%가 아닌 이유는 스티븐 해리스(Stephen Harris)가 말한(그리고 반박하는) 내용입니다./proc/PIDkill 0댓글에서— 즉, /proc파일 시스템이 마운트되지 않을 수 있습니다. 가 없는 Linux 시스템은 /proc 손상되고 성능이 저하된 시스템이라고 주장하는 것이 타당할 수 있습니다. 결국 ps, , top및 , 같은 기능은 lsof작동하지 않을 수 있으므로 프로덕션 시스템에서는 문제가 되지 않을 수 있습니다. 그러나 (이론적으로는) 절대로 설치되지 않을 가능성이 있으며(이로 인해 시스템이 정상 상태로 진입하는 것을 방해할 수도 있음), 제거될 가능성도 분명히 있으며( 1번 테스트를 거쳤습니다 ), 보장할 수 없다고 생각합니다. 거기에 있을 것입니다(즉, POSIX에서는 이를 요구하지 않습니다). 그리고 시스템이 완전히 플러시되지 않으면 kill작동하지 않습니다 .
  • Stephen의 의견은 "파일 시스템 입력"과 "기본 시스템 호출 사용"에 대해 설명합니다. 나는 이것이 주로 붉은 청어라고 생각합니다.
    • 예, 액세스를 시도하려면 /proc 루트 디렉터리를 읽어야 합니다.찾다파일 /proc시스템. 이는 모든 액세스 시도에 해당됩니다.어느/bin, 및 /etc의 내용을 포함한 파일의 절대 경로 이름입니다 /dev. 이는 너무 자주 발생하므로 루트 디렉터리는 시스템의 전체 수명(가동 시간) 동안 확실히 메모리에 캐시되므로 이 단계는 디스크 I/O 없이 수행할 수 있습니다. 또한 일단 인덱스 노드가 있으면 /proc발생하는 다른 모든 일은 메모리에 있습니다.
    • 어떻게 접속하나요 /proc? stat, 등 openreaddir모두 와 유사한 기본 시스템 호출입니다 kill.
  • 이 질문은 실행 중인 프로세스에 대해 설명합니다. 난해한 문구네요. 이 과정이 정말 맞는지 테스트하고 싶다면달리기 (즉, 실행 큐에서, 아마도 일부 CPU의 현재 프로세스에서, 잠자기, 대기 또는 중지 없음) 다음을 수행하고 싶을 수도 있습니다.ps PID 그리고 출력을 읽어보세요, 또는 한번 살펴보세요. 그러나 귀하의 질문이나 의견에는 귀하가 이에 대해 우려하고 있다는 징후가 없습니다./proc/PID/stat

    그런데 방 안에 있는 코끼리는좀비2개의 프로세스는 정상적으로 실행 중인 프로세스와 구별하기 어려울 수 있습니다.  kill 0좀비에 대해 작동하며 존재합니다. 이전 단락에 나열된 기술(실행 및 출력 읽기 또는 보기)을 사용하여 좀비를 식별할 수 있습니다. 매우 빠르고 간단한(즉, 철저하지는 않은) 테스트에서는 또는 , 또는 -를 수행하여 이 작업을 수행할 수도 있음이 나타났습니다. 이는 좀비에서는 실패합니다. (그러나 귀하의 프로세스가 아닌 프로세스에서도 실패합니다.)/proc/PIDps PID/proc/PID/statreadlinklstat/proc/PID/cwd/proc/PID/root/proc/PID/exe

____________
1if-f ( 에프orce) 옵션이 작동하지 않습니다. 시도해 보십시오 -l(아즈).
2  즉, 프로세스가 종료/종료/종료되었지만 해당 상위 프로세스는 아직 실행되지 않았습니다 wait.

관련 정보