Linux 강좌 / PID와 PPID 이해하기 - 프로세스 확인과 관리
PID(Process ID)는 실행 중인 프로세스를 식별하는 번호이고, PPID(Parent Process ID)는 그 프로세스의 부모 PID입니다. 리눅스에서는 이 번호로 프로세스를 찾고 부모·자식 관계를 확인하며, 필요한 경우 특정 프로세스에 종료 신호를 보냅니다. 번호 자체는 커널이 부여하므로 사용자가 직접 관리하는 대상은 PID가 아니라 실행 중인 프로세스입니다.
PID와 PPID는 어떻게 다를까요?
프로세스는 실행 중인 프로그램의 한 인스턴스입니다. 같은 프로그램을 두 번 실행하면 보통 서로 다른 PID를 가진 두 프로세스가 만들어집니다. 다른 프로세스가 새 프로세스를 만들면 새 프로세스에는 부모를 가리키는 PPID도 기록됩니다.
| 항목 | 뜻 | 주요 용도 |
|---|---|---|
| PID | 현재 프로세스의 식별 번호 | 특정 프로세스를 조회하거나 신호를 보낼 때 사용 |
| PPID | 현재 프로세스의 부모 프로세스 PID | 어떤 프로세스가 만들었는지, 부모·자식 관계가 어떻게 되는지 확인 |
예를 들어 셸의 PID가 4250이고 그 셸에서 실행한 sleep의 PID가 4321이라면, sleep의 PPID는 4250으로 표시될 수 있습니다. 이 숫자는 설명용 예시입니다. PID는 시스템 전체에서 영구히 고정되는 번호가 아니며, 종료 후 다른 프로세스에 재사용될 수 있습니다. 컨테이너처럼 PID 네임스페이스를 사용하는 환경에서는 관찰하는 네임스페이스에 따라 같은 프로세스의 PID가 다르게 보일 수도 있습니다.
현재 프로세스의 PID와 PPID 확인하기
가장 직접적인 방법은 ps에서 원하는 열을 지정하는 것입니다. 다음 명령은 Bash가 $$를 현재 셸의 PID로 확장한 뒤 그 셸의 정보를 보여 줍니다.
ps -p "$$" -o pid,ppid,user,stat,etime,args
출력은 환경에 따라 다르지만, 열의 의미는 다음과 같습니다. PID는 셸 자신의 번호, PPID는 그 셸을 만든 부모의 번호입니다. USER는 소유 사용자, STAT는 상태, ELAPSED는 실행 경과 시간, COMMAND 또는 ARGS는 실행 명령을 나타냅니다.
PID PPID USER STAT ELAPSED COMMAND 4250 4110 learner Ss 00:42 -bash
위 숫자와 사용자 이름은 실제 결과가 아닌 예시입니다. ps -p 4321 -o pid,ppid,args처럼 알고 있는 PID를 지정해 조회할 수도 있지만, 프로세스가 이미 끝났다면 그 PID에 대한 행이 표시되지 않습니다. 현재 실행 중인 프로세스 목록 전체를 보고 싶다면 ps -eo pid,ppid,user,stat,args를 사용하세요. 열이 많으면 less에 연결해 탐색할 수 있습니다.
프로세스 이름으로 PID를 찾을 때는 pgrep -a -x sleep처럼 사용합니다. -x는 프로세스 이름을 정확히 일치시키고 -a는 명령줄도 보여 줍니다. 같은 이름의 프로세스가 여러 개일 수 있으므로, 결과의 PID 하나만 보고 내가 찾는 작업이라고 단정하지 마세요. 옵션과 출력 형식은 ps 명령어 설명과 pgrep 명령어 설명에서도 자세히 다룹니다.
실습: 부모 셸과 자식 프로세스 확인하기
다음 실습은 대화형 Bash의 같은 터미널에서 일반 사용자로 순서대로 진행하세요. sleep 300은 약 5분 동안 기다리기만 하므로 별도의 시스템 설정이나 파일을 바꾸지 않습니다. 이미 실행 중인 다른 sleep 프로세스가 있어도, 아래에서는 방금 시작한 프로세스의 PID만 변수에 보관합니다.
sleep 300 & practice_pid=$! printf '셸 PID: %s, 실습 PID: %s\n' "$$" "$practice_pid" ps -p "$practice_pid" -o pid,ppid,user,stat,etime,args
&는 명령을 백그라운드에서 실행하고, Bash의 $!는 가장 최근에 백그라운드로 시작한 작업의 PID로 확장됩니다. 따라서 practice_pid에는 방금 만든 sleep의 번호가 저장됩니다. 첫 줄 직후 셸이 [1] 4321 같은 작업 알림을 표시할 수도 있습니다.
예상되는 ps 결과의 핵심은 sleep 행의 PID가 실습 PID와 같고 PPID가 셸 PID와 같다는 점입니다. 실제 번호·사용자·경과 시간은 환경마다 다릅니다.
PID PPID USER STAT ELAPSED COMMAND 4321 4250 learner S 00:02 sleep 300
부모·자식 관계를 다른 방식으로 확인하려면 ps --ppid "$$" -o pid,ppid,args를 실행하세요. 현재 셸의 직접 자식이 나옵니다. pstree가 설치돼 있다면 pstree -p "$$"로 관계를 나무 모양으로 볼 수도 있습니다. 단, pstree는 최소 설치 환경에 없을 수 있고, ps나 pstree 명령 자체도 조회 순간에 셸의 자식으로 잠시 나타날 수 있습니다.
PID로 안전하게 종료 요청하기
종료 대상의 번호를 알더라도 즉시 신호부터 보내지 마세요. PID가 재사용될 수 있으므로 명령, 사용자, 시작 시각을 다시 확인하는 것이 중요합니다. 실습을 시작한 직후 같은 셸에서 다음을 실행합니다.
ps -p "$practice_pid" -o pid,ppid,user,lstart,args kill -TERM "$practice_pid" wait "$practice_pid" ps -p "$practice_pid" -o pid,stat,args
첫 줄에서 sleep 300이 맞는지 확인한 뒤에만 kill을 실행하세요. TERM(SIGTERM)은 프로세스에 정상 종료를 요청하는 신호입니다. wait는 현재 셸이 만든 자식의 종료를 기다리며, 신호로 종료됐다면 0이 아닌 상태를 반환할 수 있습니다. 마지막 ps에서 해당 행이 더 이상 나오지 않으면 실습 프로세스가 종료된 것입니다. 이미 종료됐다면 kill이 실패할 수 있으므로 오래된 practice_pid를 다시 사용하지 마세요.
일반적으로 kill은 이름과 달리 지정한 PID에 신호를 보내는 명령입니다. TERM에 반응하지 않는 프로세스에 KILL(SIGKILL)을 보낼 수도 있지만, 이는 프로세스가 정리 작업을 수행할 기회를 주지 않습니다. 먼저 대상과 원인을 재확인하고 최후의 수단으로만 사용하세요. kill 명령어 설명에서 신호별 사용법을 더 확인할 수 있습니다.
부모가 종료되거나 PID가 바뀌면 어떻게 될까요?
부모 프로세스를 종료한다고 자식 프로세스가 항상 함께 종료되는 것은 아닙니다. 살아 있는 자식은 다른 프로세스에 재부모화될 수 있으므로 PPID가 달라질 수 있습니다. 따라서 부모 PID 하나만 종료하면 그 아래 작업도 모두 정리된다고 가정하면 안 됩니다.
반대로 자식이 종료됐는데 부모가 아직 종료 상태를 수거하지 않으면 잠시 좀비 프로세스로 남을 수 있습니다. 이 상태의 자식은 이미 실행을 마쳤으므로 그 PID에 KILL을 반복해서 보내는 방식으로 해결되지 않습니다. 부모 프로그램의 자식 수거 동작을 확인해야 합니다. 실습에서 사용한 Bash의 wait가 바로 자신이 만든 자식의 종료 상태를 받는 예입니다.
PID는 실행 중인 프로세스를 가리키는 현재 시점의 식별자입니다. 오래된 PID 파일이나 메모에 적힌 번호만으로 종료 대상을 정하지 마세요. 이름·소유자·시작 시각을 함께 확인하고, 컨테이너 안팎에서는 서로 다른 PID 네임스페이스의 번호를 혼동하지 않아야 합니다.
서비스 프로세스는 무엇으로 관리할까요?
systemd로 관리되는 서비스는 프로세스가 다시 시작되면서 PID가 바뀔 수 있습니다. 이 경우 PID 하나에 직접 신호를 보내기보다 서비스 단위를 확인하고 관리하는 편이 적절합니다. 예를 들어 nginx.service가 실제로 설치된 시스템에서는 systemctl status nginx.service로 상태를 확인하고, 운영상 재시작이 필요한 경우에만 sudo systemctl restart nginx.service를 사용합니다. nginx가 없거나 다른 서비스 관리자를 쓰는 환경에서는 해당 이름과 관리 방식을 확인해야 합니다.
PID는 프로세스를 정확히 찾는 단서이고, PPID는 그 프로세스가 맺은 부모 관계를 이해하는 단서입니다. 작업을 중지할 때는 이름 검색만으로 여러 프로세스에 일괄 신호를 보내기보다 대상을 먼저 좁히고, 시스템 서비스라면 서비스 관리자에 맡기는 것이 안전합니다.
근거 문서
ps(1), pgrep(1), pstree(1), kill(1) 문서는 조회와 신호 전송 동작을 설명합니다. Bash 특수 매개변수 문서와 Bash 작업 제어 문서는 $$·$!·wait의 의미를 설명합니다. 부모 종료와 좀비 상태는 wait(2)를 참고할 수 있습니다.









