OS/Linux

[Linux] kill 프로세스를 '안전하게' 종료시켜보자

Peter Ahn 2020. 8. 7. 14:24
반응형

 

개요

 

kill 명령어는 이름 때문에 프로세스를 강제로 종료시키는 명령어로 오해를 사기 쉬운데 실제로는 프로세스에 시그널(signal)을 보내는 명령어입니다. 

이름이 kill 인 이유는 어떤 시그널을 보낼 지 지정하지 않으면 기본적으로 SIGTERM 시그널을 보내게 되는데 SIGTERM의 기본 동작이 프로그램 종료이기 때문입니다. 

 

물론 프로세스에 SIGKILL 시그널을 보내 강제로 종료시킬 수도 있습니다. 

그렇지만 일반적인 상황에서 SIGKILL 시그널을 보내는 것은 권장되지 않습니다. 

 

본래 프로그램을 설계 할 때 대부분의 경우 종료 시그널을 받았을 때 처리하고 있던 데이터가 안전하게 정리 될 수 있도록 설계합니다. 

SIGTERM, SIGINT 등의 종료 시그널에 대해 시그널 핸들러(handler)를 등록하여 시그널이 수신되었을 때 연결된 Socket 또는 File을 close 하거나 Queue에 적재된 데이터를 File로 Dump하기도 합니다. 

처리 중이던 데이터를 안전하게 정리/보관하여 데이터 유실을 방지하고 다시 실행하였을 때 기존 작업을 이어나갈 수 있게 하기 위함입니다. 

그런데 SIGKILL 시그널은 프로그램에서 핸들러를 만들 수 없는 시그널이기 때문에 위와 같은 처리들을 구현 할 수 없습니다. 따라서 SIGKILL 시그널을 통해 프로세스를 강제로 종료해버리면 데이터 유실과 같은 문제가 생길 우려가 있습니다. 

 

kill -KILL PID

or

kill -9 PID

프로세스를 안전하게 종료시키려면 위와 같이 SIGKILL을 통한 종료는 가급적 사용하지 않는게 좋습니다. 

 

 

시그널(signal)

 

[root@peterdev dev]# kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

kill 명령어에 -l 옵션을 주면 위와 같이 시그널의 숫자(number)와 이름이 출력됩니다. 

 

시그널을 보낼 때는 kill -(보낼 시그널) PID 이렇게 사용하는데, 지정된 PID를 갖는 프로세스에 지정된 시그널이 전달되는 구조입니다. 

 

시그널은 숫자로 지정해도 되고 앞에 SIG를 빼고 이름을 넣어도 됩니다. 

kill -INT PID

or

kill -2 PID

 

위에서 언급한 대로 아무런 시그널을 지정하지 않고 kill PID 이라고만 하면 SIGTERM 이 전달됩니다. 

 

 

특정 이름의 프로세스 모두 종료하기

 

kill `ps -ef | grep 프로세스이름 | grep -v grep | awk '{print $2}'`

 

파이프grep, awk, 역따옴표(backticks : 백틱)을 조합하면 특정 이름의 프로세스를 모두 찾아서 종료 시킬 수 있습니다. 

 

파이프와 grep은 리눅스에서 가장 많이 사용되는 명령어 조합 중에 하나로 이전 스트림의 출력값에 원하는 형식으로 필터링을 할 수 있습니다. 

위 스크립트에서 프로세스이름 부분에 와일드카드 문자나 정규표현식도 사용 가능합니다. 

 

grep -v 은 지정된 패턴과 일치하는 항목을 제외할 때 사용합니다.

여기서는 "grep 프로세스이름" 도 하나의 명령어기 때문에 "ps -ef | grep 프로세스이름" 의 결과에 포함되는데 kill 명령어에서 이를 제외시키기 위함입니다.

 

awk 명령어는 입력 값(record : 레코드)을 공백 문자로 분리하여 필드(field) 단위로 처리 할 수 있게 해주는 명령어입니다. 

여기서는 ps -ef 명령어의 결과에서 PID를 추출하기 위해 사용됩니다. 

 

마지막으로 `명령어` 백틱(backticks)은 치환 명령어라고도 하는데 ` ` 로 감싼 부분의 실행 결과로 치환됩니다. 

 

결과적으로 kill `ps -ef | grep 프로세스이름 | grep -v grep | awk '{print $2}'` 에서 `ps -ef | grep 프로세스이름 | grep -v grep | awk '{print $2}'` 부분이 실행된 결과로 치환되어 kill PID 형태로 실행이 되는 것입니다. 

 

 

참고

 

 

[Linux] 파이프(pipe)에 대한 이해

안녕하세요 피터입니다. 오늘은 리눅스의 파이프(pipe)에 대해서 설명드리겠습니다. 파이프는 재지향(redirection)과 더불어 리눅스의 명령어들을 훨씬 강력하게 무장시켜주는 역할을 하는 핵심 기�

gracefulprograming.tistory.com

 

[Linux] ps 로 실행 중인 프로세스 확인하기

개요 ps 명령어는 리눅스에서 현재 실행중인 프로세스를 확인하는 명령어 입니다. Process Status에서 따온 이름이죠. 이름 그대로 명령어를 실행하면 현재 실행되고 있는 프로세스들의 정보를 화면

gracefulprograming.tistory.com

 

-Peter의 우아한 프로그래밍

여러분의 댓글은 저에게 크나큰 힘이 됩니다. 오류 및 의견 주시면 감사하겠습니다.

 

 

반응형