Linux watch 명령 완벽 가이드: 옵션과 활용법
Linux watch 명령을 사용하여 명령어를 주기적으로 실행하는 방법을 알아봅니다. -n 간격 설정, -d 변경 사항 강조, -g 종료 옵션 활용법과 파이프 사용 시 주의할 따옴표 처리 규칙을 정리했습니다. 효율적인 모니터링을 위한 실무 예제를 확인하십시오.
watch 명령의 역할
watch 명령은 지정된 간격으로 다른 명령을 반복 실행하고 그 결과를 화면의 같은 위치에 다시 그립니다. 기본 간격은 2초입니다. 디스크 용량이 차오르거나, 컨테이너가 안정화되거나, 인증서 갱신이 완료되거나, 큐가 비워지는 등 수치 변화를 기다려야 할 때 사용합니다.
watch는 procps-ng에서 제공하며, Ubuntu나 Debian VPS를 새로 설치하면 procps 패키지의 일부로 이미 포함되어 있습니다. 아래에 설명할 유용한 옵션 중 두 가지는 최근에 추가된 것이므로, 사용하기 전에 버전을 먼저 확인하십시오.
watch --versionUbuntu 24.04에서는 watch from procps-ng 4.0.4과 같은 줄이 출력됩니다. 이제 가장 간단하고 유용한 예제를 살펴보겠습니다.
watch df -h /화면이 지워지고 헤더 줄, 빈 줄, 그리고 df -h /의 출력 결과가 나타납니다.
Every 2.0s: df -h / server1: Sun Aug 9 10:21:44 2026왼쪽에는 실행 간격과 watch가 실행 중인 정확한 명령이 표시됩니다. 오른쪽에는 호스트 이름과 현재 시간이 표시됩니다. 아래쪽의 수치가 변하지 않을 때도 화면이 계속 갱신되고 있음을 증명해주므로 시계 부분은 매우 유용합니다. 종료하려면 Ctrl+C를 누르십시오.
watch는 터미널 크기에 맞는 한 프레임을 그립니다. 긴 줄은 자동으로 줄 바꿈되지만, -w 옵션을 사용하면 줄을 자릅니다. 화면 하단 범위를 벗어나는 내용은 전혀 표시되지 않습니다. 매 주기마다 이전 화면을 덮어쓰기 때문에 프레임 내부에는 스크롤백 기능이 없습니다. 이 단일한 사실이 watch의 용도를 결정짓는 핵심입니다.
watch 명령은 얼마나 자주 재실행해야 합니까?
2초는 기본값일 뿐입니다. 값의 변화 속도와 명령 실행 비용을 고려하여 간격을 선택하십시오.
-n 0.5:ss -s나 인터페이스 바이트 카운트처럼 지속적으로 변하는 카운터에 적합합니다. watch가 허용하는 최소 간격은 0.1초입니다.-n 30또는-n 60: 디스크나 인증서 확인에 적합합니다. 하루 동안 채워지는 파일 시스템을 1분에 30번씩 확인할 필요는 없습니다.
watch는 명령을 실행하고 완료될 때까지 기다린 뒤, 그 후에야 설정된 간격만큼 대기합니다. 명령 실행 시간이 대기 시간에 더해지므로, -n 2에서 8초가 걸리는 명령은 10초마다 한 번씩 화면을 갱신하며 시스템 자원을 계속 점유하게 됩니다. -p (--precise) 옵션을 추가하면, watch는 이전 실행 시작 시점부터 다음 실행 시작 시점까지를 기준으로 매 간격마다 실행을 시도합니다.
항상 다른 기본값을 사용하려면 셸 프로필에 WATCH_INTERVAL을 export하십시오. 명시적인 -n 옵션이 설정되어 있다면 해당 옵션이 우선합니다. watch --help를 실행하여 빌드 환경이 해당 변수를 읽어오는지 확인하십시오.
-d 옵션으로 변경 사항 강조하기
동일한 텍스트가 가득한 화면에서 위치가 바뀐 필드 하나를 찾는 것은 어려운 작업입니다. -d (--differences)을 사용하면 이 과정을 자동화할 수 있습니다.
watch -n 30 -d 'df -h / /var'이전 프레임과 다른 문자는 반전된 비디오로 표시되므로, Use% 셀은 이동하는 순간 강조되며 나머지 부분은 그대로 유지됩니다. 만약 /var이 별도의 파일 시스템이 아니라면 루트 파일 시스템이 두 번 나열되는 것을 볼 수 있는데, 이는 서버의 파티션 구성을 빠르게 파악하는 방법입니다.
비교는 위치 기반으로 수행되므로, watch는 새 프레임과 이전 프레임을 문자 단위로 정렬합니다. 열 너비가 변하는 출력은 거의 전체가 강조되므로, 레이아웃이 고정된 명령어를 사용하는 것이 좋습니다. 최신 procps-ng는 watch --differences=permanent 옵션도 지원하며, 이 옵션은 가장 최근의 변경 사항뿐만 아니라 변경된 적이 있는 모든 위치를 계속 강조합니다. 이 기능을 사용하기 전에 watch --help로 확인하십시오.
출력 내용이 변경될 때 watch를 종료하려면 어떻게 해야 합니까?
-g (--chgexit) 플래그를 사용하면 이전 실행 결과와 출력이 달라지는 즉시 watch가 종료됩니다. 프롬프트가 다시 나타나므로 같은 줄에 다른 명령어를 이어 붙여 실행할 수 있습니다.
watch -n 10 -g 'systemctl is-active myapp' ; echo 'state changed'이 플래그는 watch를 "배포가 완료되면 알려주는" 도구로 활용할 때 유용합니다. 다만 모든 사용자가 겪는 함정이 하나 있습니다. 비교 대상이 전체 출력이기 때문에, 출력 내용에 시간이나 PID(프로세스 식별자)가 포함되어 있으면 첫 번째 갱신 시점에 값이 달라져 watch가 즉시 종료됩니다. systemctl status myapp은 경과 시간과 메모리 사용량을 출력하므로, 여기에 -g를 사용하는 것은 의미가 없습니다. 명령어를 대기 중인 단일 고정 값만 출력하도록 줄여야 하며, systemctl is-active이 바로 그런 용도입니다.
최신 procps-ng 버전에는 반대 조건인 --equexit <cycles>이 추가되었습니다. 이 플래그는 지정된 횟수만큼 출력이 동일하게 유지되면 종료됩니다. 이는 "상태가 안정화되면 알려달라"는 요구사항을 해결해 줍니다. 구형 빌드에는 이 기능이 없을 수 있으므로 watch --help를 통해 확인하십시오.
왜 watch는 파이프와 glob을 무시합니까?
이는 누구나 한 번쯤 겪는 실패이며, 그 원인은 watch가 아닌 사용자의 셸에 있습니다.
watch docker compose ps | grep web대화형 셸은 명령이 실행되기 전에 전체 줄을 읽으며, 파이프를 기준으로 줄을 분할합니다. 셸은 watch docker compose ps을 시작하고 watch 자신의 화면 출력을 grep에 연결합니다. watch는 더 이상 터미널에 직접 쓰지 않으므로 화면이 깨지거나 비어 있게 되며, grep는 컨테이너 목록 대신 재출력(redraw) 내용을 필터링하게 됩니다.
전체 파이프라인을 따옴표로 묶어 하나의 인자로 전달하십시오.
watch 'docker compose ps | grep web'watch는 해당 문자열을 sh -c으로 전달하며, 셸은 매 주기마다 파이프라인을 실행합니다. glob도 같은 규칙을 따르지만 증상은 더 조용하게 나타납니다.
watch ls -l /var/log/*.log
watch 'ls -l /var/log/*.log'첫 번째 줄은 Enter를 누르는 순간 셸에서 glob을 한 번 확장합니다. 이후 watch는 고정된 파일 이름 목록만 반복해서 실행하므로, 1분 뒤에 생성된 로그 파일은 나타나지 않습니다. 두 번째 줄은 glob을 watch에 전달하며, watch는 매 주기마다 sh 내부에서 이를 확장하므로 새로운 파일이 자동으로 표시됩니다.
따옴표는 변수나 명령 치환이 언제 평가될지도 결정합니다. watch "echo $(date)"은 date를 셸에서 한 번 실행한 뒤, 그 고정된 문자열만 계속 출력합니다. watch 'echo $(date)'은 매 주기마다 date을 실행합니다. 작은따옴표는 나중에 평가됨을 의미하고, 큰따옴표는 지금 평가됨을 의미합니다.
sh -c를 사용할 때 발생하는 두 가지 추가적인 결과는 다음과 같습니다.
- 별칭(alias)과 셸 함수는 그 안에서 존재하지 않습니다.
watch ll은sh: 1: ll: not found오류와 함께 실패하는데, 이는sh -c가 사용자의.bashrc을 읽지 않기 때문입니다. 실제 명령어를 직접 작성하거나, 대화형PATH에만 존재하는 바이너리의 전체 경로를 입력하십시오. - 표준 에러(standard error)는 캡처할 가치가 있습니다. 에러 텍스트가 화면에 흩어지지 않고 프레임 안에 정렬되기를 원한다면 따옴표 안에
2>&1을 넣으십시오.
따옴표 사용이 번거로울 때는 -x(--exec)를 사용하면 sh -c을 거치지 않고 명령을 직접 실행합니다. 공백이 포함된 인자를 다루기는 쉬워지지만, 해석할 셸이 없으므로 파이프와 glob은 완전히 작동하지 않게 됩니다.
watch는 일반 프로세스이므로 권한도 같은 논리를 따릅니다. watch 'sudo ss -tulpn'는 볼 수도 입력할 수도 없는 비밀번호 프롬프트를 발생시킵니다. 대신 sudo watch 'ss -tulpn'을 실행하십시오. 이때 Ctrl+C를 누를 때까지 전체 루프가 root 권한으로 실행된다는 점을 기억해야 합니다.
VPS에서 모니터링할 가치가 있는 네 가지 요소
용량이 차오르는 디스크
watch -n 30 -d 'df -h / /var'df는 커널이 이미 보유한 수치를 요청하므로 반복 실행해도 부담이 적습니다. 반면 du -sh /var/log는 매 주기마다 트리 내의 모든 파일을 탐색하므로 비용이 큽니다. watch 명령어로 실행하면 디스크를 지속적으로 읽어 진단하려는 대상 머신의 속도를 저하시킵니다. du은 한 번만 실행하거나 ncdu을 사용하고, 수치가 계속 증가하는지 확인하려면 df을 watch와 함께 사용하십시오.
계속 재시작되는 컨테이너
cd /srv/myapp
watch -n 5 -d 'docker compose ps'상태 열은 각 컨테이너가 얼마나 오랫동안 실행되었는지 보여줍니다. 크래시 루프에 빠진 컨테이너는 계속 "Up 2 seconds"로 초기화되며, -d를 사용하면 이를 한눈에 파악할 수 있습니다. watch는 실행한 셸의 작업 디렉터리를 상속받으며 docker compose은 프로젝트 디렉터리가 필요하므로, 먼저 디렉터리를 이동하십시오. watch는 재시작이 발생하고 있음을 알려줍니다. docker compose logs -f web은 그 이유를 알려줍니다. 이유를 파악했다면, 컨테이너를 자동으로 재시작하는 Compose 헬스체크로 설정하여 화면을 계속 지켜볼 필요가 없도록 만드십시오.
인증서 갱신 시점
sudo -i
watch -n 60 -g 'openssl x509 -noout -enddate -in /etc/letsencrypt/live/example.com/fullchain.pem'이 명령어는 notAfter=Nov 7 09:14:22 2026 GMT라는 한 줄만 출력하므로, 파일이 갱신된 파일로 교체되는 즉시 -g이 실행됩니다. /etc/letsencrypt/live 하위의 파일은 root만 읽을 수 있으므로 root 셸에서 실행해야 합니다. 디스크상의 인증서를 감시한다는 점에 유의하십시오. 실행 중인 웹 서버는 리로드하기 전까지 메모리에 이전 인증서를 유지하므로, echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate로 실제로 서비스 중인 인증서를 확인하십시오. 해당 명령어를 공개 호스트에 대해 2초 간격으로 실행하지 마십시오. 갱신 작업 자체는 systemd 서비스 및 타이머로 관리해야 하며, systemctl list-timers을 통해 다음 실행 예정 시간을 확인할 수 있습니다.
비워지는 큐
watch -n 15 'postqueue -p | tail -n 1'이 명령어는 -- 24 Kbytes in 6 Requests.과 같은 요약 줄을 출력하며, 완료되면 Mail queue is empty을 출력합니다. 개수를 셀 수 있는 모든 큐에 동일한 형식을 사용할 수 있습니다: watch -n 5 'find /srv/queue/incoming -type f | wc -l'.
여기서 watch의 한계가 드러납니다. watch는 이전 프레임과 현재 프레임을 비교할 뿐 조건을 테스트할 수 없으므로, "개수가 0에 도달했다"는 사실을 알려줄 수 없습니다. 명령어 치환을 사용하여 매번 개수를 캡처하는 단순 셸 루프를 사용하면 가능합니다:
until [ "$(find /srv/queue/incoming -type f | wc -l)" -eq 0 ]; do sleep 5; done; echo 'queue drained'watch 명령어가 적합하지 않은 경우
watch는 이전 실행 결과를 기억하지 못하며, 실행하는 명령어가 어떤 작업을 수행하는지도 알지 못합니다. 이는 df에는 적합하지만, 다음 네 가지 상황에서는 부적절합니다.
- 로그. watch는 고정된 화면을 다시 그리기 때문에, 두 실행 주기 사이에 나타났다가 사라지는 줄은 확인할 수 없습니다. 새로운 줄이 기록될 때마다 출력하는
journalctl -fu nginx또는tail -f를 사용하십시오. - 부하가 큰 명령어.
du -sh /이나 바쁜 데이터베이스에 대한 쿼리를 watch로 실행하면, watch가 계속해서 명령을 재시작하므로 어떤 간격으로 설정하든 영구적인 백그라운드 부하가 발생합니다. - 부작용이 있는 작업. 데이터를 쓰거나, 게시하거나, 재시작하거나, 설치하는 명령어는 매 주기마다 동일한 작업을 반복합니다. 2초마다 API에
curl를 보내면 하루에 43,200번의 요청이 발생하며, 이는 무료 API 키가 정지되는 원인이 됩니다. - 장기적인 점검. watch는 터미널에서 실행되므로 세션이 종료되면 함께 종료됩니다. 노트북을 닫은 후에는 아무에게도 알림을 보내지 않으며 기록도 남지 않습니다. 이러한 목적에는 Uptime Kuma와 같은 실제 상태 모니터링 도구나 서버에서 상시 실행되는 예약된 점검 작업이 필요합니다.
명확한 기준은 시간입니다. watch는 특정 이벤트가 발생하기를 기다리는 10분 정도의 짧은 시간에 사용하기 위한 도구입니다. 내일도 계속 확인해야 하는 작업이라면 예약된 타이머나 실제 모니터링 도구에 맡겨야 합니다.
SSH 접속 시 tmux 내부에서 watch 실행하기
SSH를 통한 연결에서 watch의 지속성은 연결 상태에 의존합니다. 연결이 끊어지면 셸은 SIGHUP 신호를 받고 watch도 함께 종료됩니다. tmux는 이 문제를 해결하며, 원격 서버에서 watch를 진정으로 유용하게 만들어 줍니다.
tmux new -As ops
watch -n 30 -d 'df -h /'Ctrl+b를 누른 뒤 d를 눌러 세션을 분리(detach)하십시오. 루프는 서버에서 계속 실행됩니다. 나중에 tmux attach -t ops로 다시 연결하면 헤더의 시계가 증명하듯 화면이 여전히 업데이트되고 있을 것입니다. 창을 분할하면 한쪽에는 watch을, 다른 쪽에는 journalctl -f을 띄워둘 수 있으며, 이것이 바로 tmux 기반 터미널 작업대의 핵심 아이디어입니다. 여러 서버에 동일한 질문을 던져야 하는 상황이라면, watch 창을 여러 개 띄우는 대신 여러 Linux 서버 관리를 위해 설계된 도구를 사용하는 것이 적합합니다.
여기에 인용된 화면은 예시일 뿐입니다. 배포판과 procps-ng 릴리스에 따라 열 레이아웃과 버전 문자열이 다를 수 있으므로, 본인의 시스템에서 man watch을 읽어 실제 빌드에서 지원하는 플래그를 확인하십시오.
FAQ
watch mycmd | grep foo에서 watch가 파이프를 무시하는 이유는 무엇입니까?
셸은 watch가 시작되기 전에 파이프를 기준으로 명령어를 분리합니다. 따라서 watch의 화면 출력 자체가 grep으로 파이프 처리되며, 정작 명령어의 결과는 필터링되지 않습니다. 전체 파이프라인을 따옴표로 묶으십시오: watch 'mycmd | grep foo'. watch는 이 단일 인수를 sh -c에 전달하며, sh -c는 주기마다 파이프라인을 한 번씩 실행합니다. 이 규칙은 와일드카드(glob)와 명령어 치환에도 동일하게 적용됩니다.
watch에는 어떤 간격을 사용해야 합니까?
값의 변화 속도와 명령어 실행 비용에 맞추십시오. 빠른 카운터에는 0.5초가 적당하며, watch가 허용하는 최소 간격은 0.1초입니다. 디스크나 인증서 확인에는 30초에서 60초가 적당합니다. -p 플래그를 사용하지 않으면 명령어 실행 시간이 간격에 추가되므로, -n 1에서 느린 명령어를 실행하면 대기 시간 없이 연속으로 실행됩니다.
watch로 로그 파일을 추적할 수 있습니까?
아니요. watch는 한 프레임을 다시 그릴 뿐 기록을 유지하지 않으므로, 두 주기 사이에 나타났다가 사라진 줄은 영구적으로 유실됩니다. journalctl -fu <unit>와 tail -f은 새로운 줄이 도착하는 즉시 스트리밍하므로 로그 확인에 적합합니다. watch는 디스크 사용량이나 큐 길이와 같이 현재 상태를 보여주는 값을 확인하는 용도로 사용하십시오.
기다리는 조건이 발생했을 때 watch를 멈추려면 어떻게 해야 합니까?
-g(--chgexit)을 사용하고, 해당 이벤트가 발생하기 전까지 출력이 동일하게 유지되는 명령어를 지정하십시오. 시계나 PID가 포함된 출력은 첫 번째 새로고침에서 값이 바뀌어 즉시 종료되므로, systemctl status myapp이 아닌 systemctl is-active myapp가 작동합니다. 카운트가 0에 도달하는 것과 같은 실제 조건을 확인하려면 셸의 until 루프를 사용하십시오. watch는 출력의 변경 여부만 감지할 수 있기 때문입니다.
셸에서는 잘 작동하는 명령어가 watch에서는 왜 command not found라고 나옵니까?
watch는 명령어를 sh -c에 전달하는데, 이 셸은 .bashrc을 읽지 않으므로 사용자가 설정한 별칭(alias)이나 셸 함수가 존재하지 않습니다. 이 메시지는 보통 sh: 1: ll: not found입니다. 실제 명령어를 직접 작성하거나, 대화형 PATH에만 존재하는 바이너리의 경우 전체 경로를 사용하십시오.