조회수: 0
목차
ps aux grep 패턴이 가진 한계
많은 리눅스 사용자가 프로세스를 찾을 때 습관적으로 다음 명령을 사용한다
ps aux | grep nginx
겉보기에는 잘 동작하지만 몇 가지 문제가 있다
첫째 grep 자기 자신이 함께 잡힌다
명령어를 실행한 직후에는 ps 결과에 grep 프로세스가 포함되기 때문에 보통 다음처럼 한 줄을 더 붙인다
ps aux | grep nginx | grep -v grep
이제 grep 줄 하나는 빠지지만 여전히 완벽하지 않다
둘째 부분 문자열 매칭으로 오탐이 생긴다
nginx를 찾고 싶었는데 다른 옵션에 nginx라는 문자열이 포함된 전혀 다른 프로세스가 함께 보일 수 있다
셋째 스크립트에서 쓰기에는 애매하다
ps 출력 형식이 환경마다 조금씩 달라서 awk cut 조합으로 pid를 뽑다가 깨지는 경우가 많고, 공백이나 로케일에 의존하는 코드가 생기기 쉽다
이런 이유로 ps aux grep 패턴은 눈으로 한두 번 확인하는 용도라면 괜찮지만, 자동화 스크립트나 모니터링에서는 더 안전한 도구를 쓰는 편이 낫다
pgrep과 pidof가 해결해 주는 지점
pgrep과 pidof는 특정 조건을 만족하는 프로세스의 pid를 깔끔하게 출력해 주는 도구다
pgrep
pgrep nginx
위 명령은 이름에 nginx가 들어가는 프로세스 pid만 줄 단위로 출력한다
grep 프로세스가 섞이지 않고, ps 출력 형식도 신경 쓸 필요가 없다
pidof
pidof nginx
이 명령은 이름이 정확히 nginx인 프로세스를 찾고 pid들을 공백으로 구분해 한 줄에 출력한다
두 도구 모두
프로세스 이름 기준 검색
옵션으로 사용자 이름, 전체 명령행, 세션 등 다양한 조건 조합
조용한 출력과 명령 종료 코드 활용
을 지원해 스크립트에서 쓰기에 적합하다
pgrep 기본 사용법
pgrep은 이름 기준 검색을 기본으로 하지만, 실제로는 다양한 조건을 조합할 수 있다
가장 단순한 예
pgrep sshd
sshd라는 이름을 가진 프로세스 pid를 모두 출력한다
정확한 이름만 찾고 싶을 때는 다음처럼 Anchoring 옵션을 쓴다
pgrep -x sshd
x 옵션은 전체 이름이 sshd와 정확히 일치하는 프로세스만 찾는다
예를 들어 mysshd 같은 이름은 제외한다
현재 로그인한 사용자 프로세스 안에서 찾고 싶다면 u 옵션을 활용한다
pgrep -u myuser python
myuser 계정이 실행한 프로세스 중 이름에 python이 들어간 것들의 pid를 출력한다
전체 명령행 기준으로 찾기
ps aux grep을 쓰는 이유 중 하나가 옵션까지 포함한 전체 명령행에서 문자열을 찾고 싶기 때문인 경우가 많다
pgrep에서도 a 옵션을 이용하면 전체 명령행을 대상으로 검색할 수 있다
pgrep -a python
이 명령은 pid와 함께 전체 명령행을 표시해 주기 때문에 ps aux grep과 비슷한 느낌으로 사용할 수 있다
특정 옵션을 포함한 프로세스를 찾고 싶다면 예를 들어 서비스 이름을 인자로 받은 경우 다음처럼 쓸 수 있다
pgrep -a myapp | grep api
또는 정규식을 직접 활용할 수도 있다
pgrep -af 'myapp .*api'
f 옵션은 이름뿐 아니라 전체 명령행을 대상으로 매칭을 수행하고, a 옵션은 매칭된 명령행을 함께 보여 준다
스크립트에서 pgrep을 안전하게 쓰는 패턴
쉘 스크립트에서 ps aux grep을 많이 쓰는 이유는 특정 프로세스가 떠 있는지 확인하고 조건 분기를 하기 위해서다
pgrep을 사용하면 이 부분을 훨씬 깔끔하게 쓸 수 있다
예시
if pgrep -x myapp >/dev/null 2>&1; then
echo "myapp 실행 중"
else
echo "myapp 꺼져 있음"
fi
여기서 중요한 점은
출력은 버리고 종료 코드만 사용한다
정확한 프로세스 이름 매칭을 위해 x 옵션을 사용한다
오탐을 줄이고, grep -v grep 같은 꼼수를 쓸 필요도 없어 코드가 훨씬 읽기 쉬워진다
프로세스 개수를 확인하고 싶다면 wc와 함께 사용할 수도 있다
count=$(pgrep -x myapp | wc -l)
echo "myapp 프로세스 개수는 ${count}"
이 역시 ps와 awk 조합보다 직관적이다
pidof로 단일 데몬 pid 가져오기
pidof는 주로 시스템 데몬 하나의 pid를 가져올 때 많이 쓰인다
pidof sshd
위 명령은 sshd 프로세스 pid를 한 줄에 출력한다
동일한 이름의 프로세스가 여러 개 있으면 공백으로 구분해 나열한다
특정 데몬의 pid가 하나만 떠 있어야 하는 상황이라면 다음처럼 사용할 수 있다
pid=$(pidof myapp)
여기서 변수 pid에 여러 값이 들어갈 수 있다는 점은 염두에 두어야 한다
여러 개가 뜨면 안 되는 상황이라면 wc나 배열 처리를 통해 검증하는 절차를 넣는 편이 좋다
일부 배포판에서는 pidof가 busybox에 포함돼 있거나 procps 패키지에 들어 있으므로, 환경에 따라 동작이 조금씩 다를 수 있다는 정도만 기억해 두면 된다
프로세스를 바로 종료할 때 pkill 활용
pgrep이 프로세스를 찾는 명령이라면 pkill은 조건에 맞는 프로세스를 종료하는 명령이다
둘은 옵션 체계가 유사해 자연스럽게 함께 쓰인다
예를 들어 이름이 myapp인 프로세스를 모두 종료하려면
pkill -x myapp
현재 사용자 소유의 프로세스만 종료하고 싶다면
pkill -u myuser -x myapp
처럼 조건을 추가하면 된다
다만 pkill은 정말로 프로세스를 죽이는 명령이기 때문에, 스크립트에 넣기 전에 pgrep으로 먼저 어떤 프로세스가 매칭되는지 확인하는 습관을 들이는 것이 안전하다
ps aux grep과 pgrep pidof를 함께 쓰는 좋은 패턴
실무에서는 ps aux grep을 완전히 버리기보다 상황에 따라 적절히 섞어서 쓰는 편이 현실적이다
사람이 터미널에서 눈으로 확인할 때
대략적인 전체 상황을 보고 싶다면 ps aux grep이 빠르게 대답을 준다
이때도 정규식이나 옵션을 적절히 써서 노이즈를 줄이는 정도만 신경 쓰면 된다
스크립트나 자동화에서 사용할 때
프로세스 유무를 체크하거나 pid를 다른 명령 인자로 넘기는 작업이라면 pgrep pidof가 훨씬 안전하다
특히
정확한 이름 매칭이 필요할 때 x 사용
특정 사용자 프로세스만 볼 때 u 사용
종료 코드 기반 분기가 필요할 때 q 또는 출력 리다이렉트
같은 패턴을 익혀 두면 거의 모든 상황을 커버할 수 있다
흔한 실수와 디버깅 팁
pgrep을 쓰다가 결과가 예상과 다르게 나오는 경우는 대개 다음 중 하나다
프로세스 이름이 실제와 다르다
실행 파일 이름과 systemd 서비스 이름이 다를 때가 많다
이럴 때는 ps나 systemctl status로 실제 프로세스 이름을 먼저 확인해야 한다
전체 명령행 기준 매칭이 필요한데 기본 모드만 쓰고 있다
옵션을 많이 쓰는 애플리케이션이라면 이름만으로 찾기 어렵다
이 경우 f와 a 옵션을 붙여 전체 명령행을 대상으로 검색한다
정확한 매칭이 필요한데 부분 매칭만 하고 있다
우연히 비슷한 이름이 섞여 있을 수 있으므로 x 옵션을 활용해 정확히 일치하는 이름만 찾도록 한다
pgrep이나 pidof가 아예 없는 환경이라면 패키지 설치가 필요할 수 있다
보통은 procps나 psmisc 같은 패키지에 포함돼 있으니, 관련 패키지가 설치돼 있는지만 확인하면 된다
마무리 프로세스를 더 정확하게 찾는 습관 만들기
정리하면 ps aux grep 패턴은 간편하지만
grep 자신이 결과에 섞이고
부분 문자열 매칭으로 오탐이 많고
스크립트에서 pid를 뽑기에는 불안정
하다는 약점이 있다
반면 pgrep과 pidof를 활용하면
조건에 맞는 pid만 깔끔하게 추출할 수 있고
사용자 이름과 전체 명령행까지 포함해 세밀한 검색이 가능하며
종료 코드를 이용해 스크립트에서 안전하게 분기할 수 있다
터미널에서 상황을 훑어볼 때는 ps aux grep을 쓰더라도, 자동화와 운영 스크립트에서는 pgrep pidof pkill 조합을 기본 도구로 삼는 습관을 들이면 프로세스 관리가 훨씬 안정적이고 예측 가능해진다