Devin.KR
로그인

리눅스 ps 명령어 사용법 - aux와 -ef 차이, 옵션 정리와 실전 예제

개발자 조회 2

이 명령어를 언제 쓰는가

서버가 갑자기 느려졌을 때 가장 먼저 치는 명령이다. 어떤 프로세스가 CPU와 메모리를 먹고 있는지, 죽어 있어야 할 배치가 두 번 떠 있지는 않은지, 데몬이 정상적으로 올라왔는지를 한 번에 확인한다.

top이 실시간 화면이라면 ps는 지금 이 순간의 스냅샷이다. 스냅샷이기 때문에 파이프로 grep, sort, awk에 넘겨 가공하기 좋고, 그래서 감시 스크립트와 배포 스크립트에서 압도적으로 많이 쓰인다.

기본 형식

ps [옵션]

ps는 역사적 이유로 세 가지 옵션 문법을 동시에 받는다. 하이픈이 없으면 BSD 스타일(aux), 하이픈 하나면 UNIX 스타일(-ef), 하이픈 둘이면 GNU 스타일(--sort)이다. 실무에서는 사실상 ps auxps -ef 두 개를 관용구로 외워 쓰고, 필요할 때 -o로 컬럼을 직접 고른다.

자주 쓰는 옵션

옵션의미예시
aux모든 사용자의 모든 프로세스. %CPU, %MEM, RSS가 나온다ps aux
-ef모든 프로세스를 full 포맷으로. 부모 PID(PPID)가 나온다ps -ef
-o출력 컬럼을 직접 지정ps -eo pid,rss,cmd
--sort지정 컬럼으로 정렬(앞에 -를 붙이면 내림차순)ps aux --sort=-%mem
-p특정 PID만ps -p 21874 -o etime,cmd
-C명령 이름으로 필터(grep 없이)ps -C nginx -o pid,cmd
-u특정 사용자의 프로세스ps -u mysql
-L스레드까지 펼쳐서 표시ps -L -p 21874
f / --forest부모-자식 관계를 트리로ps -ef --forest
ww긴 명령줄을 자르지 않고 전부 출력ps -efww

실전 예제

1) 특정 데몬이 떠 있는지 확인한다. 대괄호를 씌우면 grep 자기 자신이 결과에 섞이지 않는다. 따옴표는 셸이 대괄호를 파일 글롭으로 해석하는 것을 막기 위해 붙인다.

ps -ef | grep '[n]ginx'
root      1180     1  0 09:12 ?        00:00:00 nginx: master process /usr/sbin/nginx
www-data  1181  1180  0 09:12 ?        00:00:03 nginx: worker process

2) 메모리를 많이 먹는 상위 10개를 뽑는다. OOM이 난 뒤 원인을 찾을 때 쓴다. head -11인 이유는 헤더 한 줄 때문이다.

ps aux --sort=-%mem | head -11

3) 필요한 컬럼만 골라서 본다. etime은 프로세스가 살아 있던 시간이라, 재시작이 반복되는지 판단할 때 유용하다.

ps -eo pid,ppid,user,%cpu,%mem,rss,etime,cmd --sort=-%cpu | head -15

4) 프로세스가 언제 시작됐는지 정확히 확인한다. lstart는 초 단위 시각까지 보여 준다. 장애 시각과 대조할 때 쓴다.

ps -p 21874 -o pid,lstart,etime,rss,cmd

5) 누가 이 프로세스를 띄웠는지 계보를 본다. 프로세스 매니저가 물고 있는지, 셸에서 직접 뜬 고아 프로세스인지 구분한다.

ps -ef --forest | grep -B3 'worker.py'

함정과 주의점

터미널에서 보면 명령줄이 잘린다. 출력이 터미널로 갈 때 ps는 화면 폭에 맞춰 뒤를 잘라 버린다. Java나 Python처럼 인자가 긴 프로세스는 정작 필요한 옵션 부분이 안 보인다. ps -efww처럼 w를 두 번 주면 길이 제한이 풀린다. 파이프나 파일로 넘긴다고 해결되지 않는다는 점이 중요하다. 리눅스의 procps ps는 터미널 크기를 알아낼 수 없으면 80컬럼을 가정하기 때문에, 크론이나 스크립트에서 ps -ef > out.txt를 돌리면 오히려 더 짧게 잘린다(COLUMNS=200 ps -ef로 넓힐 수도 있다). 반대로 macOS/BSD ps는 출력이 터미널이 아니면 폭 제한 없이 전부 내보낸다.

%MEM과 RSS를 다 더해도 실제 사용량이 아니다. RSS에는 공유 라이브러리와 공유 메모리가 프로세스마다 중복 계산된다. 프로세스가 많은 서버에서 RSS를 합치면 실제 물리 메모리보다 큰 값이 나온다. 전체 메모리 상황은 free나 /proc/meminfo로 봐야 한다.

STAT 컬럼을 무시하지 마라. Z는 좀비로, 부모가 자식 종료를 회수하지 않은 상태다. 좀비 자체는 자원을 거의 안 쓰지만 계속 쌓이면 PID가 고갈된다. D는 인터럽트 불가능한 I/O 대기로, 이게 여러 개 보이면 CPU가 아니라 디스크나 NFS가 병목이다. D 상태 프로세스는 kill -9로도 죽지 않는다.

macOS와 BSD의 ps는 다르다. --sort, --forest 같은 GNU 확장이 없다. macOS에서는 ps aux | sort -k4 -nr처럼 sort로 대신해야 한다.

함께 보면 좋은 명령어

  • top — 같은 정보를 실시간으로 갱신해서 본다. 부하가 지금 진행 중일 때 쓴다.
  • pgrepps | grep을 한 단계로 줄여 준다. 스크립트에서 PID만 필요할 때 훨씬 안전하다.
  • lsof — PID를 알아낸 다음, 그 프로세스가 어떤 파일과 포트를 잡고 있는지 확인한다.

ps(1) 공식 man 페이지