정확한 이름을 가진 프로세스의 PID를 얻는 방법은 무엇입니까?

정확한 이름을 가진 프로세스의 PID를 얻는 방법은 무엇입니까?

이 명령으로 프로세스 이름 systemctl stop Myservice의 ID를 얻으려고 하지만 정확한 pid는 얻지 못했습니다.

   if(0 == system("pidof -x systemctl stop Myservice  > /dev/null")) {
  //A process is running.
   }

이 코드는 systemctl start Myservice의 pid를 제공합니다. 시스템에서 실행 중인 경우 "systemctl stop Myservice"라는 프로세스 이름의 특정 pid만 가져와야 합니까?

답변1

귀하의 시스템에서 사용 가능한 경우 pgrep여기에 적합할 것 같습니다.

pgrep -xf "systemctl stop Myservice"

pgrep동일한 패키지로 제공됨 ps(적어도 제가 언급한 CentOS 7 시스템에서는)

$ rpm -q --whatprovides $(which pgrep)
procps-ng-3.3.10-28.el7.x86_64
$ rpm -q --whatprovides $(which ps)
procps-ng-3.3.10-28.el7.x86_64

BusyBox를 사용한 경량 배포도~인 것 같다좁은 테스트를 통과해도 괜찮습니다.

$ docker run --rm alpine pgrep --help
BusyBox v1.35.0 (2022-05-09 17:27:12 UTC) multi-call binary.

Usage: pgrep [-flanovx] [-s SID|-P PPID|PATTERN]
[...]

따라서 코드가 컨테이너 내부에서 실행되면 상황이 덜 확실해질 수 있지만(실행하려는 작업을 고려할 때 그럴 가능성은 낮아 보이지만) 에 ps의존할 수 있다고 생각합니다 .pgrep

systemctl stop ...실행 중인 명령을 캡처하시겠습니까 ? 이는 경쟁 조건 및/또는 성능 문제가 발생하기 쉬운 것 같습니다. C 프로그램이 너무 느리게 반복되어 실행 중인 명령을 놓치거나, 너무 빨라서 CPU를 너무 많이 소모한다면 어떻게 될까요?

서비스가 상태를 벗어나는 시점을 감지하는 것이 목표라면 active다음 접근 방식이 더 나을 수 있습니다.

systemctl status Myservice | grep -qE "^ +Active: active"

서비스가 활성 상태가 아닌 경우 0이 아닌 종료 코드를 반환해야 합니다.

사용 사례에 따라 몇 가지 추가 논리를 사용하여 비활성 상태가 표시될 때마다 표시하는 대신 상태가 변경될 때만 표시할 수 있습니다.

답변2

리눅스에서는,프로세스 이름프로세스 이름을 지정하는 데 사용되는 0~15바이트의 시퀀스입니다. 프로세스 이름은 명령이 실행될 때마다 실행되거나 사용되는 파일 기본 이름의 처음 15바이트까지 변경됩니다 pctrl(PR_SET_NAME).

systemctl stop Myservice이는 프로세스나 그 조상 중 하나에 의해 실행될 때 3개의 인수에 전달된 공백을 연결하는 것과 비슷해 보입니다 ./usr/bin/systemctl

/usr/bin/systemctl실행 시 systemctl, stop및 매개변수가 전달 된 현재 실행 중인 프로세스의 pid를 원한다고 가정합니다 . MyserviceLinux에서 메서드는 다음과 같습니다.

  • stat()파일에서 a를 실행 하고 합계가 반환된 것과 동일한 지 /proc/*/exe확인합니다 ( 프로세스가 실행된 이후 업데이트되지 않았다고 가정 ).st_devst_inostat("/usr/bin/systemctl")systemdsystemctl
  • 그런 다음 /proc/<pid>/cmdline해당 프로세스의 파일이 포함되어 있는지 확인합니다 systemctl<NUL>stop<NUL>Myservice<NUL>. 프로세스가 파일을 임의로 수정할 수 있지만 일반적으로 수정하지는 않는다는 점을 기억하세요.

특히 C/C++ 프로그램에서 왜 이런 일을 하는지 이해할 수 없습니다. 이것은 다음과 같습니다XY 문제.

관련 정보