다음과 같은 스크립트가 있습니다.
pid = $(ps -ef | grep my-service | awk '{print $2}')
이것은 나에게 실행 중인 프로세스의 PID를 제공합니다 my-service
. 실행 중인 여러 프로세스를 처리하고 my-service
최신 프로세스를 제외한 모든 이전 프로세스를 종료하도록 스크립트를 업데이트하고 싶습니다 . 그러나 실행 중인 프로세스가 하나만 있으면 해당 프로세스를 종료합니다. 어떻게 해야 하나요?
답변1
pgrep
( 및 ) 에는 프로세스 수 계산을 위한 ( ), 최신 PID만 가져오기 위한 ( ) 와 같은 이 pkill
작업에 대한 몇 가지 유용한 매개변수가 있습니다 . ( 더 알아보기)-c
--count
-n
--newest
man pgrep
그래서 우리는 이 case
진술을 사용할 수 있습니다. pid가 반환되지 않으면 종료하고, 그렇다면 프로세스를 종료합니다. 여러 프로세스가 발견되면 grep -v
최신 PID를 제외한 모든 PID를 대상으로 하고 이를 kill
.
#!/bin/bash
die="my-service"
case $(pgrep -cf "$die") in
0) exit 0 ;;
1) pkill -f "$die" ;;
*) grep -v $(pgrep -nf "$die") <(pgrep -f "$die") | xargs kill ;;
esac
참고: -f
위에서 사용된 매개변수는 전체 명령과 일치시키기 위해 사용되었습니다. 프로세스 이름만 일치시키려면 이 매개변수를 사용하면 안 됩니다. 에서 man pgrep
:
-f, --완료
이 패턴은 일반적으로 프로세스 이름과만 일치합니다. -f를 설정하면 전체 명령줄이 사용됩니다.
답변2
procps-ng ps
및 unmodified 를 가정하면 $IFS
다음을 수행할 수 있습니다.
set -- $(ps -o pid= --sort=-start_time -C my-service)
case $# in
(0) ;;
(1) kill "$1";;
(*) shift; kill "$@"
esac
set
분배하다위치 매개변수( $1
, $2
...)를 이름이 지정된 프로세스의 pid에 추가 하고 역순 my-service
으로 정렬합니다 (가장 최근에 시작된 것부터).start_time
그런 다음 숫자( $#
)를 기준으로 0이면 아무것도 하지 않고, 1이면 죽이고, 다른 숫자에 대해서는 shift
가장 작은 것을 버리고 나머지는 죽입니다.
( ps -C name
일치하는 것을 참고하세요정확히보고된 인수 목록이 아닌 전체 프로세스 이름에 있음 ps -f
)