헷갈리는 이유: 역사적으로 BSD 스타일과 UNIX 스타일 두 옵션 문법을 모두 지원한다. 실무·시험에서 압도적으로 많이 쓰는 두 조합만 익히면 된다.
명령
스타일
의미
특징
ps aux
BSD (하이픈 없음)
모든 사용자의 모든 프로세스
%CPU·%MEM·START 등 표시
ps -ef
UNIX (하이픈 있음)
모든 프로세스 전체 목록
PPID 컬럼 표시
ps -u user
UNIX
특정 사용자 프로세스
사용자별 필터
ps -p PID
UNIX
특정 PID 정보
단일 프로세스
ps aux # 전체 프로세스 + CPU/메모리 사용률ps -ef # 전체 프로세스 + PPID(부모 추적에 유리)ps -ef | grep nginx # 특정 프로그램 프로세스만 추리기ps aux --sort=-%cpu # CPU 사용률 내림차순 정렬
ps aux의 STAT(상태) 컬럼은 각 글자의 의미를 알아야 읽을 수 있다.
STAT
의미
R
실행 중 또는 실행 대기(Running)
S
인터럽트 가능한 대기(Sleeping)
D
인터럽트 불가 대기(주로 I/O)
T
정지(Stopped, Ctrl+Z 등)
Z
좀비(Zombie, 종료됐으나 회수 안 됨)
<
높은 우선순위(낮은 nice)
N
낮은 우선순위(높은 nice)
⚠️ 함정: ps aux에는 하이픈을 붙이지 않고, ps -ef에는 붙인다. ps -aux처럼 섞어 쓰면 일부 시스템에서 경고가 뜨거나 다르게 해석된다. "aux는 맨몸, ef는 하이픈"으로 구분한다. 그리고 Z(좀비)는 종료된 자식을 부모가 회수(wait)하지 않아 PID만 남은 상태다 — Day 2 핵심.
ps aux의 BSD 문법은 버클리 유닉스에서, ps -ef의 UNIX 문법은 AT&T 시스템 V에서 왔다. 리눅스의 procps는 둘을 모두 받아들이기 때문에 같은 정보를 두 방식으로 볼 수 있다. 시험에서는 "aux는 사용률, ef는 부모 추적"이라는 용도 차이로 출제되는 경우가 많다.
kill은 "죽이는" 명령이 아니라 "지정한 번호의 시그널을 보내는" 명령이다. 시그널 종류에 따라 종료·재설정·일시정지 등 동작이 달라진다.
핵심 시그널의 번호와 의미는 반드시 외운다.
번호
이름
의미
무시 가능?
1
SIGHUP
터미널 끊김 / 설정 재읽기(reload)
가능
9
SIGKILL
강제 종료(즉시, 무조건)
불가
15
SIGTERM
정상 종료 요청(기본값)
가능
2
SIGINT
인터럽트(Ctrl+C)
가능
18/19
SIGCONT/SIGSTOP
재개 / 정지
STOP은 불가
kill 1234 # PID 1234에 기본 시그널 15(SIGTERM) 전송kill -9 1234 # 9번(SIGKILL) 강제 종료kill -15 1234 # 15번(SIGTERM) 정상 종료 명시kill -1 1234 # 1번(SIGHUP) — 보통 데몬 설정 재읽기kill -HUP 1234 # 이름으로도 지정 가능kill -l # 시그널 번호↔이름 전체 목록
기본값은 15번(SIGTERM) — kill에 옵션 없이 PID만 주면 이게 간다. "정리할 시간을 줄 테니 곱게 종료하라"는 정중한 요청이라, 프로세스가 열린 파일을 닫고 임시 파일을 지운 뒤 종료할 수 있다.
9번(SIGKILL)은 통보 없이 커널이 즉시 메모리에서 제거한다. 가로채거나 무시할 수 없어 확실히 죽는다.
대신 SIGKILL은 정리 작업을 못 하므로 임시 파일·잠금 파일이 남거나 데이터가 손상될 수 있다.
⚠️ 함정: 항상 9번부터 쓰면 안 된다. 15번(정상 종료)을 먼저 시도하고, 그래도 안 죽으면 9번(강제)을 쓰는 것이 올바른 순서다. SIGKILL(9)과 SIGSTOP(19)만이 무시·차단이 불가능한 두 시그널이라는 점도 알아 둔다.
이름으로 한꺼번에 죽이려면 killall(이름 기준)이나 pkill(패턴 기준)을 쓴다.
killall httpd # httpd라는 이름의 모든 프로세스에 시그널 15killall -9 httpd # 강제 종료pkill -u alice # alice 사용자의 모든 프로세스pkill -HUP sshd # sshd에 HUP 전송(설정 재읽기)
kill은 PID로, killall/pkill은 이름/패턴으로 시그널을 보낸다. SIGHUP(1)은 데몬에게 "죽지 말고 설정 파일만 다시 읽어라"는 의미로 자주 쓰인다(예: kill -HUP $(pgrep -x sshd)). 그래서 1번은 "재시작 없는 리로드"의 대명사다.
SIGHUP의 H-U-P은 "Hang Up"(전화 끊기)의 약자다. 옛날 모뎀 터미널 연결이 끊기면 커널이 그 터미널에 붙은 프로세스에 SIGHUP을 보냈다. 오늘날 데몬들이 이 신호를 "설정 재읽기"로 재해석하면서, 서비스 무중단 리로드의 표준 신호가 되었다. nohup(no hang up) 명령이 바로 이 SIGHUP을 무시하게 만들어 로그아웃 후에도 프로세스를 살려두는 도구다.
이름이 "친절함(nice)"인 이유: 값이 높을수록 다른 프로세스에게 CPU를 양보하는 "착한" 프로세스가 된다.
범위는 -20부터 19까지, 기본값은 0.
nice 값
의미
우선순위
-20
가장 이기적(양보 안 함)
가장 높음
0
기본값
보통
19
가장 친절(가장 많이 양보)
가장 낮음
nice -n 10 ./backup.sh # nice 10으로 낮춰서 실행(양보)nice -n -5 ./urgent.sh # nice -5로 높여 실행(우선)nice ./job.sh # -n 생략 시 기본 +10 적용
이미 실행 중인 프로세스의 우선순위는 renice로 바꾼다.
renice 15 -p 1234 # PID 1234의 nice를 15로 변경renice -n 5 -p 1234 # -n 옵션으로도 지정renice 10 -u alice # alice의 모든 프로세스 nice를 10으로
음수 nice(우선순위 상승)는 root만 설정할 수 있다. 일반 사용자는 자기 프로세스의 nice를 올릴(숫자를 키울) 수만 있고, 한 번 양보한 우선순위를 다시 끌어올리지 못한다. 또한 nice는 "새로 실행할 때", renice는 "이미 도는 프로세스"라는 점이 다르다. nice의 기본 적용값(-n 생략 시)은 +10이다.
nice 값과 실제 스케줄링 우선순위(PRI)는 반대 방향처럼 보이지만 연동된다. nice가 낮을수록(-20에 가까울수록) 우선순위가 높아 CPU를 더 자주 받는다. top에서 NI 컬럼이 nice 값, PR 컬럼이 커널 우선순위다.
직접 쳐보기: nice -n 19 sleep 100 &로 가장 양보하는 프로세스를 띄운 뒤 ps -o pid,ni,cmd -p $!로 NI 컬럼이 19인지 확인한다. 이어 renice 5 -p $!로 바꾸고 다시 확인하면 NI가 5로 줄어든다(일반 사용자는 올리기만 가능).
load average가 높다는 사실만으로는 무엇을 늘려야 할지 알 수 없다. 세 갈래를 지표로 갈라낸다.
병목
결정적 지표
보조 신호
처방 방향
CPU bound
%user+%system 높고 %iowait 낮음
vmstat의 r이 코어 수보다 큼, mpstat에서 특정 코어 포화
코어 증설, 알고리즘 개선, nice로 배치 작업 양보
I/O bound
%iowait 높음
vmstat의 b가 큼, iostat의 %util 100% 근접·await 급증, ps의 D 상태
디스크 교체(SSD), I/O 분산, 쿼리·캐시 개선
메모리 부족
si·so(스왑 in/out)가 지속 발생
free의 available 바닥, sar -W의 pswpout/s 증가, OOM 로그
메모리 증설, 프로세스 사용량 축소
nproc # 코어 수 — load average 해석의 기준vmstat 1 5 # r / b / si / so / wa 를 한 화면에서 비교iostat -x 1 3 # await·%util 로 디스크 포화 확인pidstat -d 1 3 # I/O를 실제로 일으키는 프로세스 지목
free의 free(여유) 값이 작다고 메모리 부족이 아니다. 리눅스는 남는 메모리를 버퍼·캐시로 최대한 써 두었다가 필요하면 즉시 돌려준다. 실제 여유는 available 열로 판단하고, 진짜 부족의 증거는 스왑 in/out(si·so)이 계속 발생하는 것이다. 스왑 사용량이 높아도 유입·유출이 없으면 이미 잠든 페이지일 뿐 병목이 아니다.
직접 쳐보기: vmstat 1 10을 돌려 두고 다른 터미널에서 dd if=/dev/zero of=/tmp/t bs=1M count=1000 oflag=direct로 디스크 부하를 준 뒤 b와 wa가 함께 오르는지 본다. iostat -x 1에서 그 장치의 %util이 100%에 붙으면 "I/O bound"의 지표 조합이다. 끝나면 rm /tmp/t.