Linux 패턴 기반 프로세스 종료

LinuxBeginner
지금 연습하기

소개

Linux 시스템에서 프로세스를 효과적으로 관리하는 것은 시스템 안정성과 성능 유지를 위해 매우 중요합니다. kill 명령어를 사용하면 특정 프로세스 ID (PID) 를 사용하여 프로세스를 종료할 수 있지만, 패턴을 기반으로 여러 프로세스를 종료해야 하는 상황이 있습니다. 이럴 때 pkill 명령어가 매우 유용합니다.

본 랩에서는 pkill 명령어를 사용하여 프로세스 이름, 인자 또는 기타 기준에 따라 프로세스를 종료하는 방법을 다룹니다. 실행 중인 프로세스를 식별하고, 패턴 매칭을 사용하여 선택적으로 종료하며, 작업 결과를 확인하는 방법을 배우게 됩니다. 이러한 기술은 Linux 환경에서 시스템 관리 및 문제 해결에 필수적입니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 95%입니다.학습자들로부터 100%의 긍정적인 리뷰율을 받았습니다.

프로세스 관리 및 기본 프로세스 종료 이해

이 첫 번째 단계에서는 실행 중인 프로세스를 식별하고 기본 패턴 매칭을 사용하여 종료하는 방법을 살펴보겠습니다. Linux 는 ps, pgrep, pkill을 포함하여 프로세스 관리를 위한 여러 명령어를 제공합니다.

테스트 프로세스 생성

백그라운드 프로세스로 실행할 수 있는 간단한 스크립트를 만들어 보겠습니다. 여러 유사한 프로세스를 종료해야 하는 시나리오를 시뮬레이션하기 위해 이 스크립트의 여러 인스턴스를 생성합니다.

먼저 프로젝트 디렉토리로 이동하여 rogue_app.sh라는 스크립트를 생성합니다.

cd ~/project
nano rogue_app.sh

다음 내용을 스크립트에 추가합니다.

#!/bin/bash
while true; do
  echo "Process running with PID $$"
  sleep 5
done

이 스크립트는 무한 루프를 실행하며 5 초마다 프로세스 ID (PID) 를 출력합니다.

이제 스크립트를 실행 가능하게 만듭니다.

chmod +x ~/project/rogue_app.sh

이 스크립트의 여러 인스턴스를 백그라운드에서 실행해 보겠습니다.

for i in {1..5}; do
  ~/project/rogue_app.sh &
done

명령어 끝에 있는 &는 각 스크립트 인스턴스를 백그라운드에서 실행하여 터미널을 계속 사용할 수 있도록 합니다.

실행 중인 프로세스 보기

방금 시작한 프로세스를 보려면 적절한 플래그와 함께 ps 명령어를 사용합니다.

ps aux | grep rogue_app.sh

출력은 다음과 유사합니다.

labex     12345  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12346  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12347  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12348  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12349  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12350  0.0  0.0   2432   584 pts/0    S+   10:00   0:00 grep --color=auto rogue_app.sh

실제 PID (두 번째 열의 숫자) 는 시스템에 따라 다릅니다.

pkill 로 프로세스 종료

이제 pkill 명령어를 사용하여 스크립트의 모든 인스턴스를 종료해 보겠습니다.

pkill -f rogue_app.sh

-f 옵션은 pkill에게 프로세스 이름뿐만 아니라 전체 명령줄과 일치하도록 지시합니다. 스크립트가 실행될 때 프로세스 이름이 스크립트 이름이 아닌 인터프리터 (예: /bin/bash) 인 경우가 많기 때문에 중요합니다.

스크립트의 모든 인스턴스가 종료되었는지 확인합니다.

ps aux | grep rogue_app.sh

이제 출력에서 grep 명령어 자체만 볼 수 있습니다.

labex     12351  0.0  0.0   2432   584 pts/0    S+   10:01   0:00 grep --color=auto rogue_app.sh

이는 rogue_app.sh의 모든 인스턴스가 성공적으로 종료되었음을 확인합니다.

패턴 매칭을 이용한 선택적 프로세스 종료

실제 시나리오에서는 종료할 프로세스를 더 선택적으로 지정해야 하는 경우가 많습니다. pkill 명령어를 사용하면 다양한 기준에 따라 특정 프로세스를 대상으로 패턴 매칭을 사용할 수 있습니다.

다른 인수를 사용하여 프로세스 생성

다른 명령줄 인수를 사용하여 실행할 새 스크립트를 만들어 보겠습니다.

cd ~/project
nano service_worker.sh

다음 내용을 스크립트에 추가합니다.

#!/bin/bash
while true; do
  echo "Running service worker with argument: $1"
  sleep 5
done

스크립트를 실행 가능하게 만듭니다.

chmod +x ~/project/service_worker.sh

이제 이 스크립트의 여러 인스턴스를 다른 인수로 실행해 보겠습니다.

~/project/service_worker.sh normal &
~/project/service_worker.sh normal &
~/project/service_worker.sh --malfunctioning &
~/project/service_worker.sh --malfunctioning &
~/project/service_worker.sh emergency &

이렇게 하면 두 개의 "normal" 작업자, 두 개의 "malfunctioning" 작업자, 하나의 "emergency" 작업자, 총 5 개의 백그라운드 프로세스가 생성됩니다.

다른 인수를 가진 프로세스 보기

실행 중인 프로세스를 확인합니다.

ps aux | grep service_worker.sh

다음과 유사한 출력이 표시됩니다.

labex     12360  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex     12361  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex     12362  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh --malfunctioning
labex     12363  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh --malfunctioning
labex     12364  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh emergency
labex     12365  0.0  0.0   2432   584 pts/0    S+   10:05   0:00 grep --color=auto service_worker.sh

패턴 매칭을 사용한 선택적 종료

이제 --malfunctioning 인수가 있는 프로세스만 선택적으로 종료해 보겠습니다.

pkill -f "service_worker.sh --malfunctioning"

-f 옵션은 pkill이 인수를 포함한 전체 명령줄과 일치하도록 합니다.

대상 프로세스만 종료되었는지 확인합니다.

ps aux | grep service_worker.sh

이제 "normal" 및 "emergency" 프로세스만 표시됩니다.

labex     12360  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex     12361  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex     12364  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh emergency
labex     12366  0.0  0.0   2432   584 pts/0    S+   10:06   0:00 grep --color=auto service_worker.sh

이는 명령줄에서 특정 패턴을 기반으로 프로세스를 선택적으로 종료하는 방법을 보여줍니다.

이제 나머지 모든 서비스 작업자 프로세스를 종료해 보겠습니다.

pkill -f service_worker.sh

모든 서비스 작업자 프로세스가 종료되었는지 확인합니다.

ps aux | grep service_worker.sh

이제 grep 명령어 자체만 표시됩니다.

labex     12367  0.0  0.0   2432   584 pts/0    S+   10:07   0:00 grep --color=auto service_worker.sh

고급 프로세스 종료 옵션

이 단계에서는 보다 정교한 프로세스 관리를 가능하게 하는 pkill 명령어의 고급 옵션들을 살펴보겠습니다.

다양한 시그널 유형 사용하기

기본적으로 pkill은 프로세스에 SIGTERM 시그널 (시그널 15) 을 보냅니다. 이 시그널은 프로세스가 파일을 닫고 정리 작업을 수행하며 우아하게 (gracefully) 종료할 수 있도록 허용합니다. 하지만 다른 시그널을 사용해야 하는 경우도 있습니다.

시그널을 처리하는 스크립트를 생성해 보겠습니다:

cd ~/project
nano signal_handler.sh

스크립트에 다음 내용을 추가합니다:

#!/bin/bash
trap 'echo "Received SIGHUP (1)"; exit 0' SIGHUP
trap 'echo "Received SIGINT (2)"; exit 0' SIGINT
trap 'echo "Received SIGTERM (15)"; exit 0' SIGTERM

echo "Process started with PID $$"
echo "Use: pkill -[signal] -f signal_handler.sh to send signals"
while true; do
  sleep 1
done

스크립트에 실행 권한을 부여합니다:

chmod +x ~/project/signal_handler.sh

스크립트를 백그라운드에서 실행합니다:

~/project/signal_handler.sh &

이제 프로세스에 다른 시그널들을 보내 보겠습니다:

  1. SIGHUP 시그널 (시그널 1) 보내기:
pkill -HUP -f signal_handler.sh
  1. 스크립트를 다시 시작하고 SIGINT(시그널 2) 보내기:
~/project/signal_handler.sh &
pkill -INT -f signal_handler.sh
  1. 스크립트를 다시 시작하고 기본 SIGTERM(시그널 15) 보내기:
~/project/signal_handler.sh &
pkill -f signal_handler.sh ## Default is SIGTERM

각 시그널에 대해, 프로세스가 종료되기 전에 터미널 출력에서 해당 메시지를 확인해야 합니다.

프로세스 실행 시간에 따른 종료

pkill--newest 옵션을 사용하여 프로세스의 실행 시간에 따라 대상을 지정할 수 있으며, 이 옵션은 가장 최근에 시작된 프로세스를 선택합니다.

다양한 시작 시간을 가진 몇 가지 프로세스를 생성해 보겠습니다:

cd ~/project
nano age_test.sh

스크립트에 다음 내용을 추가합니다:

#!/bin/bash
while true; do
  echo "Process running with PID $$"
  sleep 5
done

스크립트에 실행 권한을 부여합니다:

chmod +x ~/project/age_test.sh

첫 번째 프로세스를 시작합니다:

~/project/age_test.sh &

몇 초 기다린 후, 두 개의 프로세스를 더 시작합니다:

sleep 5
~/project/age_test.sh &
~/project/age_test.sh &

이제 --newest 옵션을 사용하여 가장 최근에 시작된 두 개의 프로세스만 종료해 보겠습니다:

pkill -f --newest 2 age_test.sh

아직 실행 중인 프로세스를 확인합니다:

ps aux | grep age_test.sh

첫 번째 프로세스만 계속 실행 중인 것을 볼 수 있습니다. 이는 다른 두 프로세스보다 먼저 시작되었기 때문입니다.

나머지 프로세스를 종료합니다:

pkill -f age_test.sh

프로세스 소유자로 pkill 제한하기

특정 사용자가 소유한 프로세스로 pkill의 작업을 제한할 수도 있습니다. 다중 사용자 시스템에서는 이것이 특히 유용합니다.

시연을 위해 현재 사용자로 몇 가지 프로세스를 실행해 보겠습니다:

~/project/rogue_app.sh &
~/project/rogue_app.sh &

이제 이 프로세스들을 종료하되, 현재 사용자가 소유한 프로세스만 종료하도록 하겠습니다:

pkill -f -u $(whoami) rogue_app.sh

-u 옵션은 프로세스 소유자의 사용자 이름을 지정합니다. $(whoami) 명령어 치환 (command substitution) 은 현재 사용자 이름을 가져옵니다.

모든 프로세스가 종료되었는지 확인합니다:

ps aux | grep rogue_app.sh

출력에는 grep 명령어 자체만 보여야 합니다.

이처럼 소유자별로 프로세스를 대상으로 지정하는 기능은 다른 사용자의 프로세스에 영향을 미치지 않으려는 다중 사용자 환경에서 특히 유용합니다.

요약

이 랩에서는 Linux 환경에서 pkill 명령어를 사용하여 프로세스를 관리하는 방법을 배웠습니다. 이 강력한 명령어를 사용하면 다양한 기준에 따라 프로세스를 종료할 수 있으며, 이는 시스템 관리에 필수적인 도구입니다.

다룬 주요 개념:

  1. 기본 프로세스 종료: ps 명령어를 사용하여 실행 중인 프로세스를 식별하고 기본 패턴 매칭을 사용하여 pkill로 종료하는 방법을 배웠습니다.

  2. 선택적 프로세스 종료: 명령줄 인수를 기반으로 프로세스를 선택적으로 타겟팅하기 위해 패턴 매칭을 사용하는 방법을 탐구하여 종료할 프로세스를 정밀하게 제어할 수 있었습니다.

  3. 고급 프로세스 종료 옵션: pkill의 고급 옵션을 발견했습니다. 여기에는 다음이 포함됩니다.

    • 프로세스에 다른 신호 유형을 보내는 방법
    • 프로세스 연령을 기준으로 프로세스를 종료하는 방법
    • pkill의 범위를 특정 사용자가 소유한 프로세스로 제한하는 방법

이러한 기술은 Linux 환경에서 시스템 안정성을 유지하고, 리소스를 관리하며, 문제를 해결하는 데 유용합니다. pkill 명령어를 마스터함으로써 Linux 시스템 관리 도구 상자에 중요한 도구를 추가했습니다.