"sudo" 프로세스를 포함하지 않고 프로세스를 "sudo pkill"하는 깔끔한 방법이 있습니까?

"sudo" 프로세스를 포함하지 않고 프로세스를 "sudo pkill"하는 깔끔한 방법이 있습니까?

sudo로 실행 중인 일부 프로세스를 종료하고 전체 이름으로 일치시키고 원시 명령 호출 수를 계산해야 합니다.

각 프로세스에는 명령 자체와 명령 sudo자체라는 두 가지 프로세스가 있지만 이 문제를 해결할 수 있습니다.

$ sudo -b perf record sleep 100

$ pgrep -fa '/perf record'
2245700 /usr/lib/linux-tools/.../perf record sleep 100

문제는 내가 호출할 때 sudo pkill자체적으로 찾아서 죽이고 계산한다는 것입니다.

$ sudo pkill -ef '/perf record' | wc -l
2

이 경우 pkill이 자신을 포함하지 않도록 하는 쉬운 방법이 있습니까?

허용되는 pid 파일을 사용해 보았지만 pgrep/pkill 문서가 누락되어 기본 형식에서는 작동하지 않는 것 같습니다.

$ pgrep -f '/perf record' | tee /tmp/pids
$ sudo pkill -F /tmp/pids
 killed (pid 2249211)

첫 번째 사람만 죽일 것이기 때문입니다. 문서에는 다음과 같이 나와 있습니다.

       -F, --pidfile file
              Read PID's from file.  This option is perhaps more useful for pkill than pgrep.

그러나 그 의미는 모호하다 PID's.

답변1

노력하다:

sudo pkill -ef '/[p]erf record' | wc -l

다음은 문자 하나만 포함하는 문자 클래스를 사용하는 요령입니다 p.

정규식에서 을(를) 찾고 있지만 /perf명령 sudo pkill줄에 가 있지만 /[p]erf일치하지 않습니다.

이 접근 방식은 다음과 같은 명령으로 수십 년 동안 사용되었습니다.ps aux | awk '/[f]oo/ {print $1}'

답변2

pkill/의 패턴은 pgrep의 패턴과 같은 확장된 정규식입니다 grep -E. 따라서 원하는 프로세스를 보다 정확하게 대상으로 하는 정규식을 제공할 수 있습니다. 귀하의 경우에는 다음과 같을 수 있습니다.

sudo pkill -ef '^(/[^/]+)+/perf record'

아니면 더 나은@cas가 설명하는 기술그의 대답에.

이 모든 것이 왜 필요한지 설명하는 것이 좋습니다.

우리 모두 알고 있듯이 pkill/는 pgrep결코 그 자체와 일치하지 않습니다. 그러나 그들이 사용하는 기준은 일치하는 것입니다.PID, 즉.일치하는 PID 중 하나가 자신의 것인지 확인합니다.그들은 정확히 그것을 제외합니다.

그러나 a를 통해 실행하면( -f전체 명령줄 모드 옵션 사용) 명령 sudo은 자체 프로세스 pkill와도 일치하게 됩니다 . 왜냐하면 명령에는 a와 일치하는 명령줄 문자열도 함께 제공되기 때문입니다.sudo없는당신이 사용한 것과 같은 패턴입니다. 분명히, sudo자체 프로세스는 해당 프로세스와 다른 PID를 가지므로 pkill해당 pkill프로세스는 목록에서 제외되지 않으며 sudo이를 생성한(그리고 여전히 남아 있는) 프로세스를 종료합니다 pkill.

고려하다:

$ sudo -b perf record sleep 1234
$ sudo pgrep -fa '/perf record'
1446 /usr/lib/linux-tools/4.2.0-42-generic/perf record sleep 1234
1466 sudo pgrep -fa /perf record  # <-- if I issued a pkill, this process, the sudo, would have been killed

위의 코드 조각에서 pgrep주의 하세요.내 자신의해당 프로세스는 실제로 목록에서 제외됩니다. 하지만 이 sudo프로세스에는 기본 정규식과 일치하는 명령줄도 함께 제공됩니다.

보다 사용자 정의된 정규식을 제공하면 프로세스 자체 명령줄(사용자 정의된 정규식 전달)이 정규식 자체와 일치하지 않기 때문에 프로세스가 더 이상 포함되지 않습니다 pkill.sudo pkill -ef <...>


옵션에 대한 마지막 참고 사항입니다 -F.

이 글을 쓰는 지금도 이 옵션은 여전히 ​​존재합니다.하나의 PID만 읽기파일에서. 그렇습니다. --help프로그램의 출력 뿐만 아니라 문서도 오해의 소지가 있습니다.출처에 있는 이 댓글추악한 진실입니다.

/* FreeBSD: arg는 포함입니다PID 매칭*/

답변3

pid를 직접 가져오고 검색하지 마세요.

pid="$(sudo bash -c 'sleep 100 >/dev/null & echo $!')"
sudo kill "$pid"

백그라운드 프로세스가 아무 것도 출력하지 않더라도 stdout의 리디렉션이 필요합니다. 그렇지 않으면 제공된 결과로 설정되어 백그라운드 작업이 stdout을 닫을 때까지 하위 프로세스에서 읽으려고 시도하는 동안 정지하게 $()되기 때문입니다 .$()

여기서 가장 큰 이점 pkill은 검색과 일치하는 다른 프로세스를 잠재적으로 종료하는 대신 항상 올바른 pid를 얻을 수 있다는 것입니다. 예를 들어, 스크립트를 동시에 여러 번 실행하는 경우 perf일치하는 프로세스가 여러 개 있을 수 있으며 [p]erf record, 각 프로세스는 각 스크립트 호출의 하위 프로세스입니다.

답변4

다가오는 procps 4.0.1에서는-A옵션은 도입되었으며 상위 항목을 무시합니다 pkill.pgrep.

sudo이는 간단히 다음을 실행하여 프로세스 종료를 피할 수 있음을 의미합니다 .

sudo pkill -Aef '/perf record'

관련 정보