- Published on
man timeout: 리눅스 timeout 명령어 사용법과 종료 코드 정리
- Authors

- Name
- Indo Yoon
man timeout은 GNU coreutils가 제공하는 timeout 명령어의 매뉴얼 페이지를 여는 명령입니다. 이 페이지에는 DURATION 표기법, -s·-k·--preserve-status 같은 핵심 옵션, 그리고 시간 초과 시 반환되는 종료 코드가 한 화면에 정리되어 있습니다. 배포 스크립트나 헬스 체크에서 외부 명령을 감쌀 때는 옵션을 추측하지 말고 man timeout으로 현재 시스템의 구현과 지원 범위를 먼저 확인하는 편이 안전합니다.
한눈에 보기
timeout은 "명령을 실행하고, 정해진 시간이 지나도 끝나지 않으면 종료시킨다"는 단일 목적의 래퍼입니다. 매뉴얼 페이지의 NAME 절도 timeout - run a command with a time limit 정도로 짧게 정의되어 있어서, 처음 읽을 때 확인할 지점은 다섯 가지로 압축됩니다.
- SYNOPSIS:
timeout [OPTION] DURATION COMMAND [ARG]...구조인지 확인합니다. - DURATION: 초가 기본 단위이고
s,m,h,d접미사와 소수점 표기를 지원하는지 봅니다. - 시그널: 기본값이 TERM이며
-s로 바꿀 수 있다는 점을 확인합니다. - 유예 종료:
-k로 KILL을 한 번 더 보내는 2단계 구조를 이해합니다. - 종료 코드: 124, 125, 126, 127, 137의 의미를 구분합니다.
이 다섯 가지만 파악하면 매뉴얼 페이지의 나머지 설명은 대부분 응용입니다. 반대로 이 중 하나라도 놓치면 "타임아웃을 걸었는데 프로세스가 남아 있다"거나 "실패를 성공으로 처리했다"는 형태의 운영 사고가 생깁니다.
man timeout 출력에서 먼저 볼 항목
매뉴얼 페이지에서 실무에 바로 쓰이는 옵션은 다음 정도입니다. 표의 표현은 coreutils 기준이며, 다른 구현에서는 이름이나 지원 여부가 다를 수 있으므로 SYNOPSIS와 OPTIONS 절을 함께 읽어야 합니다.
| 옵션 | 의미 | 쓰는 상황 |
|---|---|---|
-s, --signal=SIGNAL | 시간 초과 시 보낼 시그널을 지정합니다. 기본은 TERM입니다. | 정상 종료 절차를 유도하고 싶을 때 |
-k, --kill-after=DURATION | 지정한 시그널을 보낸 뒤 유예 시간이 지나도 살아 있으면 KILL을 보냅니다. | TERM을 무시하는 프로세스를 정리할 때 |
--preserve-status | 시간 초과로 끝났더라도 명령의 종료 코드를 그대로 돌려줍니다. | 원래 실패 원인을 로그로 남기고 싶을 때 |
--foreground | TTY 입력과 TTY 시그널이 필요한 실행을 허용합니다. 이 모드에서는 COMMAND의 자식 프로세스에 타임아웃이 적용되지 않습니다. | 셸 프롬프트에서 대화형 명령을 감쌀 때 |
-v, --verbose | 시그널을 보냈다는 사실을 표준 오류로 알려 줍니다. | 왜 종료됐는지 확인할 때 |
여기서 눈여겨볼 부분은 -k와 --foreground입니다. -k는 타임아웃을 "한 번 더 기다리는" 옵션이라서 실제 최대 대기 시간이 늘어납니다. --foreground는 편의 옵션이 아니라 동작 범위를 바꾸는 옵션이므로, 자식 프로세스까지 정리되어야 하는 배포 스크립트에서는 기본 모드를 유지하는 편이 좋습니다.
단계별로 man timeout 확인하기
매뉴얼 페이지를 정확히 읽는 순서는 다음과 같습니다.
command -v timeout으로 실제 실행 파일 경로를 확인합니다./usr/bin/timeout이면 coreutils 구현이고, BusyBox 링크이거나 다른 경로라면 옵션 집합이 다를 수 있습니다.man 1 timeout처럼 섹션을 지정합니다. 섹션 1은 사용자 명령, 섹션 8은 관리자 명령이므로, 같은 이름의 다른 페이지가 있을 때 원하는 문서를 정확히 열 수 있습니다.- SYNOPSIS를 먼저 읽습니다. DURATION이 COMMAND 앞에 온다는 순서를 잘못 기억하면
timeout curl ... DURATION형태로 쓰게 되고, 이때는 타임아웃이 걸리지 않습니다. man -w timeout으로 페이지 파일 경로를 확인합니다. 배포판마다 문서 패키지가 분리되어 있어서, 경로가 나오지 않으면 문서 패키지가 빠진 상태입니다.man -a timeout으로 같은 이름의 모든 페이지를 차례로 봅니다. 구현이 여러 개 깔린 이미지에서 유용합니다.man -k timeout으로 색인을 검색합니다. 이 기능은mandb(Debian 계열)나makewhatis(RHEL 계열)로 색인을 갱신해 두어야 결과가 나옵니다.- 페이지가 길어서 옵션만 훑고 싶다면
MANWIDTH=100 man timeout처럼 폭을 넓히거나PAGER=cat man timeout으로 페이저를 끕니다.col이 설치되어 있다면man timeout | col -b로 서식 문자를 제거한 뒤 필요한 절만 검색할 수 있습니다. - 옵션 철자가 기억나지 않을 때는
timeout --help가 더 빠릅니다. 다만--help는 요약이고, 종료 코드와 세부 동작은 매뉴얼 페이지와info coreutils 'timeout invocation'에 더 자세히 나옵니다.
이 순서에서 1번과 2번이 특히 중요합니다. 컨테이너 이미지에는 coreutils 대신 BusyBox가 들어 있는 경우가 많고, 그 경우 -k 지원 여부나 DURATION 접미사 처리가 달라질 수 있기 때문입니다.
timeout의 동작 방식과 종료 코드
timeout은 COMMAND를 자식 프로세스로 실행하고, DURATION이 지나면 지정된 시그널을 보냅니다. 기본 시그널이 TERM이라는 점이 핵심입니다. TERM은 프로세스가 정리 작업을 하고 스스로 종료할 기회를 주는 시그널이므로, 정상적인 종료 경로를 가진 프로그램에는 이것으로 충분합니다.
문제는 TERM을 무시하거나 처리하지 않는 프로그램입니다. 이때는 -k로 KILL을 보내는 유예 단계를 두어야 합니다. KILL은 프로세스가 무시할 수 없으므로 확실하게 정리되지만, 정리 작업 없이 강제로 끝나기 때문에 임시 파일이나 잠금이 남을 수 있습니다.
종료 코드는 다음처럼 구분됩니다. 스크립트에서 성공과 실패를 나눌 때 이 표를 기준으로 삼으면 됩니다.
| 종료 코드 | 의미 |
|---|---|
| 124 | 시간 초과로 종료되었습니다. --preserve-status를 쓰지 않았을 때의 기본값입니다. |
| 125 | timeout 자체가 실패했습니다. |
| 126 | COMMAND를 찾았지만 실행할 수 없었습니다. |
| 127 | COMMAND를 찾을 수 없었습니다. |
| 137 | COMMAND 또는 timeout이 KILL 시그널을 받았습니다. |
여기서 자주 하는 착각이 "시간 초과는 실패가 아니니 0으로 처리해도 된다"는 판단입니다. 배포 스크립트에서는 124를 별도 분기로 두고, 재시도할지 롤백할지를 명시적으로 결정하는 편이 안전합니다. set -e를 쓰는 스크립트라면 124가 즉시 중단을 유발하므로, 허용 가능한 경우에는 조건문으로 감싸서 처리해야 합니다.
시그널을 보내는 범위도 기억해 두어야 합니다. timeout은 명령이 만든 자식 프로세스까지 함께 정리되도록 프로세스 그룹 단위로 시그널을 보내는 방식으로 동작하지만, 명령이 스스로 새 세션을 만들거나 백그라운드로 분리되면 그 범위를 벗어납니다. 이 경우 매뉴얼 페이지의 설명만으로는 해결되지 않으므로, 서비스 관리자나 컨테이너 런타임 수준의 정리 정책을 함께 봐야 합니다.
상황별 선택: 어떤 타임아웃 수단을 쓸까
timeout은 만능이 아닙니다. 제어하려는 경계가 프로세스 안쪽인지 바깥쪽인지에 따라 수단이 달라집니다.
| 상황 | 권장 수단 | 이유 |
|---|---|---|
| 배포 스크립트에서 외부 명령 하나를 감쌀 때 | timeout | 옵션과 종료 코드가 단순하고 이식성이 좋습니다. |
| 파이프라인이나 여러 명령을 묶어서 제한할 때 | timeout과 셸 실행을 조합 | 셸이 전체 묶음을 자식으로 실행하므로 한 번에 제한할 수 있습니다. |
| TERM을 무시하는 프로세스를 정리할 때 | timeout -k | 강제 종료 유예 단계를 둘 수 있습니다. |
| systemd로 관리되는 서비스 | 유닛의 실행 시간 제한 설정 | 서비스 관리자가 재시작 정책과 함께 제어합니다. |
| 애플리케이션 내부의 외부 API 호출 | 언어나 클라이언트 라이브러리의 타임아웃 | 연결·읽기 단계별로 세밀하게 나눌 수 있습니다. |
특히 파이프라인은 자주 틀리는 지점입니다. timeout DURATION cmd1 | cmd2 형태로 쓰면 제한은 cmd1에만 적용되고 cmd2는 그대로 남습니다. 전체를 제한하려면 셸을 통해 묶어서 실행해야 합니다. 셸 내장 명령이나 셸 함수에는 timeout이 적용되지 않는다는 점도 같은 맥락입니다. timeout은 외부 실행 파일을 대상으로 동작합니다.
주의할 점
운영에서 문제가 되는 경우는 대부분 옵션 사용법이 아니라 경계 설정입니다.
- 종료 코드 124를 성공으로 처리하지 않습니다. 배포 단계에서는 재시도, 알림, 롤백 중 하나로 반드시 연결합니다.
-k를 쓰면 전체 대기 시간이 늘어납니다. DURATION과 유예 시간을 합친 값이 실제 최대 대기 시간이라고 생각해야 합니다.- 셸 내장 명령, 별칭, 함수에는 적용되지 않습니다. 이들은 별도 프로세스가 아니므로 감쌀 대상이 없습니다.
- 컨테이너에서 PID 1로 실행되는 프로세스는 시그널 처리 규칙이 일반 프로세스와 다릅니다. 진입점 스크립트에서
timeout을 쓸 때는 시그널이 실제 애플리케이션까지 전달되는지 확인해야 합니다. - 구현 차이를 확인합니다. BusyBox 등 다른 구현은 옵션 이름과 지원 범위가 다를 수 있으므로, 이미지가 바뀌면
man timeout을 다시 확인하는 편이 좋습니다. - 문서 패키지가 없는 최소 이미지에서는
man자체가 동작하지 않습니다. 이때는timeout --help와 공식 매뉴얼 페이지를 대조합니다.
자주 묻는 질문
man timeout을 실행했더니 매뉴얼 항목이 없다고 나옵니다. 왜 그런가요?
timeout 실행 파일은 있는데 매뉴얼 페이지 패키지가 설치되지 않은 경우입니다. 최소 이미지나 컨테이너에서는 문서가 분리되어 있는 일이 흔하므로, 배포판의 문서 패키지를 확인하거나 timeout --help로 대체해야 합니다. 구현 자체가 BusyBox라면 애초에 별도 매뉴얼 페이지가 없을 수 있습니다.
타임아웃을 걸었는데 프로세스가 계속 살아 있습니다. 무엇을 확인해야 하나요?
기본 시그널이 TERM이라서 해당 시그널을 무시하는 프로그램은 종료되지 않을 수 있습니다. -k로 KILL 유예 단계를 추가했는지, 그리고 그 프로세스가 스스로 새 세션이나 백그라운드로 분리되었는지를 차례로 확인해 보세요. 후자라면 timeout의 적용 범위를 벗어난 것이므로 서비스 관리자 수준의 정리가 필요합니다.
파이프라인 전체에 타임아웃을 걸려면 어떻게 해야 하나요?
제한하려는 명령 묶음을 셸을 통해 하나의 자식 프로세스로 실행하고, 그 셸을 timeout으로 감싸면 됩니다. 이렇게 하면 묶음 전체가 하나의 대상으로 취급됩니다. 반대로 개별 명령 앞에 각각 timeout을 붙이면 단계마다 별도로 제한되므로, 의도한 최대 대기 시간과 달라질 수 있습니다.
종료 코드 124와 137은 어떻게 다른가요?
124는 정해진 시간이 지나 timeout이 종료를 유발했다는 뜻이고, 137은 KILL 시그널을 받고 끝났다는 뜻입니다. -k를 사용하는 구성에서는 두 코드가 모두 나타날 수 있으므로, 로그에서 어느 경로로 끝났는지 구분해 두면 원인 파악이 쉬워집니다.
애플리케이션 코드의 타임아웃과 timeout 명령 중 무엇을 써야 하나요?
프로세스 경계를 넘는 제어가 필요하면 timeout이 유용하고, 연결·읽기처럼 단계별 제어가 필요하면 클라이언트 라이브러리의 타임아웃이 적합합니다. 둘은 대체 관계가 아니라 계층이 다르므로, 외부 호출에는 라이브러리 타임아웃을, 배치나 스크립트 단위에는 timeout을 두는 식으로 함께 쓰는 편이 좋습니다.
출처
- GNU coreutils 매뉴얼의 timeout 항목: https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html
- man7.org의 timeout(1) 매뉴얼 페이지: https://man7.org/linux/man-pages/man1/timeout.1.html
- man-db 공식 사이트: https://man-db.nongnu.org/
- GNU coreutils 공식 사이트: https://www.gnu.org/software/coreutils/
배포 자동화에서 타임아웃은 단독 옵션보다 재시작 정책, 로그 수집, 헬스 체크와 함께 설계할 때 효과가 있습니다. 서비스 유닛의 실행 시간 제한과 재시작 정책을 함께 정리한 글로 이어서 읽어 보시면, 스크립트 수준의 timeout과 서비스 관리자 수준의 제어를 어떻게 나눌지 판단하는 데 도움이 됩니다. 관련 운영 글: systemd 서비스 타임아웃과 재시작 정책 정리