ps: 실행 중인 프로세스의 스냅샷을 확인하는 명령어
ps는 명령을 실행한 시점의 프로세스(process) 상태를 한 번 출력하는 리눅스 명령어다. PID, 사용자, CPU·메모리 사용률, 상태, 실행 명령 같은 정보를 보여 준다. top과 달리 실시간으로 갱신하지 않고 스냅샷(snapshot)만 찍으므로 grep, awk 같은 도구와 조합해 스크립트에서 쓰기 좋다.
By 송민성
1. 개념
ps(process status)는 현재 실행 중인 프로세스(process)의 정보를 출력하는 명령어다. 프로세스는 실행 중인 프로그램의 인스턴스이며, 운영체제는 각 프로세스에 고유한 프로세스 ID(PID)를 부여한다.
ps는 호출한 순간의 상태를 한 번 출력하고 종료한다. 화면을 계속 갱신하는 top과 다른 점이다.
2. 왜 사용하는가
- 서버에서 특정 프로세스(예: Node.js 서버, nginx)가 떠 있는지 확인한다.
- 종료하거나 시그널을 보낼 대상의 PID를 찾는다.
- CPU, 메모리를 많이 쓰는 프로세스를 찾는다.
- 부모-자식 관계(PPID)를 파악해 프로세스가 어디서 시작되었는지 추적한다.
- 출력이 텍스트 한 번이므로 셸 스크립트, 파이프라인과 결합하기 쉽다.
3. 동작 원리
리눅스에서 ps는 가상 파일 시스템인 /proc을 읽어 정보를 얻는다. /proc/<PID>/ 아래에 있는 stat, status, cmdline 등의 파일에 커널(kernel)이 프로세스 정보를 노출하며, ps는 이를 읽어 사람이 보기 좋은 표로 가공한다.
자주 쓰는 출력 열은 다음과 같다.
| 열 | 의미 |
|---|---|
| PID | 프로세스 ID |
| PPID | 부모 프로세스 ID |
| USER | 프로세스 소유자 |
| %CPU | 프로세스 생존 기간 동안의 평균 CPU 사용률 (현재 순간 값이 아님) |
| %MEM | 물리 메모리 사용 비율 |
| VSZ | 가상 메모리 크기(KiB) |
| RSS | 실제 물리 메모리에 올라온 크기(KiB) |
| STAT | 프로세스 상태 |
| COMMAND | 실행 명령 |
STAT의 주요 첫 글자는 다음과 같다.
R: 실행 중이거나 실행 가능(running/runnable)S: 인터럽트 가능한 대기(sleeping)D: 인터럽트 불가능한 대기(주로 I/O 대기)T: 정지됨(stopped)Z: 좀비(zombie) 프로세스
ps는 옵션 스타일이 세 가지다. 유닉스(UNIX) 스타일은 -ef처럼 대시(-)를 쓰고, BSD 스타일은 aux처럼 대시 없이 쓰며, GNU 스타일은 --forest처럼 긴 옵션을 쓴다. 같은 글자라도 스타일에 따라 의미가 달라질 수 있다.
4. 코드 예제
# 1) 옵션 없이 실행: 현재 터미널에서 실행한 내 프로세스만 출력
ps
# 2) 시스템의 모든 프로세스를 상세하게 (BSD 스타일)
ps aux
# 3) 모든 프로세스를 PPID 포함해 출력 (UNIX 스타일)
ps -ef
# 4) 특정 프로세스 찾기 (grep 자신이 걸리지 않게 [n] 트릭 사용)
ps aux | grep '[n]ginx'
# 5) 원하는 열만 지정하고 메모리 사용량 순으로 정렬 (GNU ps)
ps -eo pid,ppid,user,%cpu,%mem,rss,stat,comm --sort=-rss | head -n 6
# 6) 프로세스 트리로 보기 (GNU ps)
ps -ef --forest
# 7) 이름으로 PID만 얻기 (procps 계열에 포함된 pgrep 사용)
pgrep -f "node server.js"
# 8) 좀비 프로세스 찾기
ps -eo pid,ppid,stat,comm | awk '$3 ~ /^Z/'macOS(BSD 계열)의 ps는 GNU 옵션인 --sort, --forest를 지원하지 않는다. macOS에서 정렬하려면 ps aux -m(메모리순) 또는 ps aux -r(CPU순)을 사용한다.
5. 시간 복잡도 또는 성능 특성
ps는 /proc의 각 프로세스 디렉터리를 순회하며 읽으므로, 실행 비용은 대략 프로세스 수 n에 비례하는 O(n)이다. 일반적인 서버에서는 순간적으로 끝나지만, 프로세스가 수만 개 이상이면 느려질 수 있다. 또 출력하는 열이 많을수록 읽어야 할 /proc 파일이 늘어난다.
%CPU는 현재 순간의 사용률이 아니라 프로세스 시작 이후 누적 CPU 시간을 경과 시간으로 나눈 값이다. 지금 CPU를 많이 쓰는 프로세스를 보려면 top이나 pidstat 같은 도구가 더 적합하다.
6. 실무 사용 사례
- 배포 후 확인:
ps aux | grep '[n]ode'로 새 버전의 서버 프로세스가 떠 있는지 확인한다. - 메모리 누수 의심:
ps -eo pid,rss,comm --sort=-rss | head로 RSS가 큰 프로세스를 찾는다. - 행(hang) 프로세스 종료: PID를 찾은 뒤
kill <PID>로 종료 시그널을 보낸다. - 컨테이너 디버깅:
docker exec <컨테이너> ps aux로 컨테이너 안의 프로세스를 확인한다. 단, 최소 이미지에는ps가 없을 수 있다. - 좀비 프로세스 점검: STAT가
Z인 프로세스의 PPID를 찾아 부모 프로세스가 자식의 종료 상태를 회수(wait)하는지 확인한다.
7. 주의할 점
ps aux | grep nginx는grep프로세스 자신도 출력에 나타난다.grep '[n]ginx'처럼 쓰거나pgrep을 사용한다.ps는 스냅샷이므로 확인한 순간 이후 프로세스가 바뀔 수 있다. PID를 얻은 뒤 시그널을 보내기까지의 사이에 PID가 다른 프로세스에 재사용될 가능성이 있다.- 긴 명령줄은 터미널 폭에 맞춰 잘릴 수 있다. 전체를 보려면
ps auxww처럼w를 중복해서 쓴다. - 옵션 스타일(
-ef와aux)을 섞으면 의도와 다르게 동작할 수 있으니 하나로 통일한다. - 좀비 프로세스는
kill로 없앨 수 없다. 이미 종료되었고 부모가 회수하지 않은 상태이므로 부모 프로세스를 고치거나 종료해야 한다. ps는/proc에 의존하므로hidepid옵션으로/proc을 마운트한 환경에서는 다른 사용자의 프로세스가 보이지 않을 수 있다.
8. 핵심 정리
ps는 호출 시점의 프로세스 상태를 한 번 출력하는 스냅샷 도구이며, 정보는/proc에서 읽는다.- 가장 흔한 형태는
ps aux와ps -ef이다. -eo로 열을 지정하고--sort로 정렬할 수 있다(GNU ps 기준).%CPU는 평균값이므로 순간 부하 확인에는top을 쓴다.- 특정 프로세스를 찾을 때는
pgrep또는grep '[x]xx'패턴을 사용한다. - STAT의
Z는 좀비 프로세스이며, 해결하려면 부모 프로세스를 확인해야 한다.