이 명령으로 프로세스 이름 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를 원한다고 가정합니다 . Myservice
Linux에서 메서드는 다음과 같습니다.
stat()
파일에서 a를 실행 하고 합계가 반환된 것과 동일한 지/proc/*/exe
확인합니다 ( 프로세스가 실행된 이후 업데이트되지 않았다고 가정 ).st_dev
st_ino
stat("/usr/bin/systemctl")
systemd
systemctl
- 그런 다음
/proc/<pid>/cmdline
해당 프로세스의 파일이 포함되어 있는지 확인합니다systemctl<NUL>stop<NUL>Myservice<NUL>
. 프로세스가 파일을 임의로 수정할 수 있지만 일반적으로 수정하지는 않는다는 점을 기억하세요.
특히 C/C++ 프로그램에서 왜 이런 일을 하는지 이해할 수 없습니다. 이것은 다음과 같습니다XY 문제.