하나의 프로세스가 없으면 하나의 프로세스를 제외하고 모두 종료하는 방법

하나의 프로세스가 없으면 하나의 프로세스를 제외하고 모두 종료하는 방법

다음과 같은 스크립트가 있습니다.

pid = $(ps -ef | grep my-service | awk '{print $2}')

이것은 나에게 실행 중인 프로세스의 PID를 제공합니다 my-service. 실행 중인 여러 프로세스를 처리하고 my-service최신 프로세스를 제외한 모든 이전 프로세스를 종료하도록 스크립트를 업데이트하고 싶습니다 . 그러나 실행 중인 프로세스가 하나만 있으면 해당 프로세스를 종료합니다. 어떻게 해야 하나요?

답변1

pgrep( 및 ) 에는 프로세스 수 계산을 위한 ( ), 최신 PID만 가져오기 위한 ( ) 와 같은 이 pkill작업에 대한 몇 가지 유용한 매개변수가 있습니다 . ( 더 알아보기)-c--count-n--newestman 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)

관련 정보