- Published on
linux timeout man: 타임아웃 명령어 사용법과 옵션 정리
- Authors

- Name
- Indo Yoon
한눈에 보기
timeout은 GNU coreutils에 포함된 명령으로, 자식 프로세스를 실행하고 정해진 시간이 지나면 시그널을 보내 종료시키는 역할을 합니다. man 페이지의 개요는 timeout [OPTION] DURATION COMMAND [ARG]... 형태라서, 옵션 다음에 시간, 그다음에 실행할 명령이 온다는 순서만 익히면 바로 쓸 수 있습니다.
- 배포와 운영 스크립트에서 응답 없이 매달린 작업을 정리할 때 가장 먼저 꺼내는 도구입니다.
- 기본 시그널은 TERM이며, 그래도 정리되지 않으면
--kill-after로 KILL을 추가로 보낼 수 있습니다. - 시간이 지나 종료되면 종료 코드 124를 돌려주므로, 성공과 시간 초과를 스크립트에서 나눠 처리할 수 있습니다.
핵심은 "무엇을 언제까지 기다릴지"를 명시적으로 적는 것입니다. 무한 대기 가능성이 있는 명령 앞에 timeout을 붙이는 것만으로 배포 파이프라인이 영원히 멈추는 사고를 크게 줄일 수 있습니다.
기본 문법과 주요 옵션
인자 순서는 고정되어 있습니다. 옵션, 실행 허용 시간, 실행할 명령, 그리고 그 명령의 인자가 차례로 옵니다. 시간 자리에는 숫자와 접미사를 조합해 쓰며, 접미사를 생략했을 때의 기본 단위는 매뉴얼에 명시되어 있으니 스크립트에서는 가급적 접미사를 붙여 의도를 드러내는 편이 좋습니다.
| 옵션 | 의미 | 사용 예 |
|---|---|---|
DURATION | 실행을 허용할 시간. 접미사로 단위를 지정합니다. | timeout 5m ./backup.sh |
-s, --signal | 시간이 지났을 때 보낼 시그널을 지정합니다. | timeout -s INT 3s ./worker |
-k, --kill-after | 지정한 시간이 더 지나도 살아 있으면 KILL을 보냅니다. | timeout -k 5s 30s ./job |
--preserve-status | 시간 초과로 끝나도 원래 명령의 종료 상태를 유지합니다. | timeout --preserve-status 10s ./check |
--foreground | 별도 프로세스 그룹을 만들지 않고 전면에서 실행합니다. | timeout --foreground 1m ./interactive |
-v, --verbose | 종료 시 어떤 시그널을 보냈는지 화면에 남깁니다. | timeout -v 2s sleep 10 |
접미사는 s, m, h, d를 지원합니다. 즉 가장 작은 단위부터 하루 단위까지 표현할 수 있어서, 배포 스크립트처럼 "얼마나 기다릴지"가 중요한 곳에서 읽기 쉬운 표기가 됩니다.
단계별 사용 방법
- 먼저 기다릴 상한을 정합니다. 헬스 체크처럼 짧게 끝나야 하는 작업인지, 마이그레이션처럼 오래 걸릴 수 있는 작업인지에 따라 값이 달라집니다.
- 실행할 명령 앞에
timeout과 시간을 붙입니다. 예를 들어 배포 스크립트 안의 외부 호출이라면timeout 2m ./scripts/wait-for-db.sh처럼 씁니다. - 시그널을 바꿀지 결정합니다. 정상 종료 절차를 태우고 싶다면 TERM을 유지하고, 즉시 정리가 필요하면 INT나 KILL을 검토합니다.
-k를 함께 쓰는 것을 권합니다. TERM을 무시하는 프로세스가 있어도 KILL까지 도달하므로 스크립트가 멈추지 않습니다.- 종료 코드를 확인합니다. 124는 시간 초과, 125는 timeout 자체의 실패, 126과 127은 명령을 실행할 수 없었던 경우로 구분됩니다.
- 마지막으로 로그를 남깁니다.
-v를 붙이거나 감싼 스크립트에서 종료 코드를 기록해 두면 나중에 원인을 추적하기 쉬워집니다.
상황별 선택 기준
모든 대기에 timeout을 쓰는 것이 답은 아닙니다. 도구마다 이미 시간 제한 기능을 가지고 있는 경우가 많기 때문입니다.
- HTTP 클라이언트:
curl은 자체 연결·전체 시간 제한 옵션을 제공하므로 그것을 우선 쓰고, 래퍼 스크립트 단위에서timeout을 한 번 더 감싸는 식이 안전합니다. - 서비스 관리: systemd 유닛으로 돌아가는 프로세스라면 유닛의 타임아웃 설정이 우선입니다.
timeout은 유닛 안에서 실행되는 보조 스크립트에 적용하는 편이 맞습니다. - 컨테이너 기동 대기: 데이터베이스가 올라오기를 기다리는 스크립트에
timeout을 걸어 두면, 실패 시 배포가 무한 대기 대신 명확한 오류로 끝납니다. - 대화형 명령: 입력을 기다리는 프로그램은
--foreground를 검토해야 합니다. 그렇지 않으면 터미널 제어권 문제로 예상과 다르게 동작할 수 있습니다. - 파이프라인:
timeout은 자신이 직접 실행하는 명령에만 적용됩니다.cmd1 | cmd2형태라면 어느 쪽에 걸 것인지 명시적으로 결정해야 합니다.
주의할 점
시간 초과는 "죽였다"는 뜻이지 "정리됐다"는 뜻이 아닙니다. TERM을 받은 프로세스가 핸들러에서 락을 놓지 않으면 다음 단계가 막힐 수 있으므로, -k로 KILL 단계를 두는 것이 일반적입니다.
종료 코드를 그대로 성공으로 취급하는 실수도 흔합니다. 124를 별도로 처리하지 않으면 시간 초과가 정상 종료처럼 보일 수 있으니, 스크립트에서는 0과 124를 반드시 나눠 판단해야 합니다. --preserve-status를 쓰면 반대 상황이 되어, 원래 명령의 상태가 남는 대신 시간 초과 여부가 가려질 수 있다는 점도 기억해야 합니다.
또한 timeout은 자식 프로세스 하나를 대상으로 동작합니다. 명령이 내부에서 워커를 여러 개 띄우는 구조라면 종료 후 잔여 프로세스가 남지 않는지 확인해야 하고, 필요하면 프로세스 그룹 단위로 정리하는 별도 수단을 함께 써야 합니다. 셸 내장 명령에 직접 걸면 의도한 프로세스가 아닌 셸이 대상이 될 수 있으므로, 내장 명령은 별도 셸로 감싸 실행하는 편이 안전합니다.
자주 묻는 질문
timeout의 기본 시간 단위는 무엇인가요?
접미사를 생략하면 매뉴얼에 정의된 기본 단위로 해석됩니다(https://man7.org/linux/man-pages/man1/timeout.1.html). s, m, h, d 접미사를 지원하므로 긴 작업에는 m이나 h를 붙이는 편이 읽기 좋습니다. 스크립트에서는 단위를 생략하지 않는 습관을 권합니다.
종료 코드 124는 무엇을 뜻하나요?
명령이 지정한 시간 안에 끝나지 않아 timeout이 종료시켰다는 의미입니다. 즉 명령 자체가 실패한 것이 아니라 시간 안에 완료되지 못한 것이므로, 재시도 여부를 판단할 때 이 코드를 기준으로 삼습니다.
TERM을 보냈는데 프로세스가 계속 살아 있으면 어떻게 하나요?
-k 옵션으로 KILL 단계를 추가하면 됩니다. 예를 들어 timeout -k 5s 30s ./job처럼 쓰면 TERM 이후 유예 시간이 지나 KILL이 전달됩니다. 유예 시간은 정리 작업에 필요한 만큼만 잡는 것이 좋습니다.
배포 스크립트 어디에 넣는 것이 좋나요?
외부 시스템을 기다리는 모든 지점이 후보입니다. 데이터베이스 연결 대기, 마이그레이션 호출, 헬스 체크 폴링처럼 상대방 상태에 따라 끝나지 않을 수 있는 호출에 걸어 두면, 배포가 무한 대기 대신 명확한 실패로 마무리됩니다.
서비스 재시작 명령에도 쓸 수 있나요?
가능하지만 서비스 관리자와 역할이 겹칠 수 있습니다. systemd 같은 관리자가 이미 타임아웃을 다룬다면 중복 설정이 되므로, 관리자 설정을 우선 확인하고 보조 스크립트에만 적용하는 편이 깔끔합니다.
출처
- https://man7.org/linux/man-pages/man1/timeout.1.html
- https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html
- https://www.gnu.org/software/coreutils/
배포 자동화에서 시간 제한을 어떻게 설계하는지 더 보고 싶다면, 서비스 유닛의 기동·종료 대기 시간을 다룬 systemd 타임아웃 운영 글을 함께 읽어 보시면 좋습니다. timeout은 스크립트 한 줄을 지켜 주는 도구이고, 유닛 설정은 서비스 전체의 수명을 지켜 주는 장치라는 차이를 비교해 보시면 상황에 맞는 선택이 쉬워집니다.