본문 중간의 쿠팡 추천 상품 구매시 쿠팡 파트너스에서 일정액의 수수료를 제공받습니다.

systemd ExecCondition 기준 정리
ExecCondition=은 systemd 서비스 시작 전에 조건을 검사하되, 조건이 맞지 않을 때 서비스를 실패로 기록하지 않고 조용히 건너뛸 수 있게 만든 옵션이다. 2026년 6월 27일 기준 upstream systemd.service 공식 문서를 보면 ExecCondition=은 ExecStartPre=보다 먼저 실행되고, 종료 코드에 따라 "실패"와 "조건 불일치"를 구분한다.
실무에서 자주 헷갈리는 부분은 세 가지다. 단순 준비 작업이면 ExecStartPre=를 써야 하는지, 조건 검사면 ExecCondition=을 써야 하는지, 그리고 시작 중간에 멈췄을 때 정리 작업을 ExecStop=와 ExecStopPost= 중 어디에 둬야 하는지다. 이 글은 그 경계를 공식 문서 기준으로만 정리한다.
ExecCondition=은 언제 쓰는 옵션일까?
공식 문서에 따르면 ExecCondition=은 ExecStartPre=와 condition check를 섞은 형태다. 서비스 시작 전에 명령을 실행한다는 점은 비슷하지만, 종료 코드 1부터 254까지는 유닛을 실패로 표시하지 않고 이후 시작 절차를 건너뛴다는 점이 다르다.
예를 들어 특정 설정 파일이 있을 때만 서비스를 올리거나, 장비 노드가 준비된 경우에만 시작하고 싶을 때가 여기에 가깝다. 이런 경우 조건이 맞지 않았다는 사실과 서비스 자체의 비정상 실패는 운영상 의미가 다르므로, ExecStartPre=보다 ExecCondition=이 더 맞다.
ExecCondition=과 ExecStartPre=는 무엇이 다를까?
| 항목 | ExecCondition= |
ExecStartPre= |
|---|---|---|
| 실행 순서 | ExecStartPre=보다 먼저 실행 |
ExecCondition= 뒤에 실행 |
| 종료 코드 0 | 다음 단계 계속 진행 | 다음 단계 계속 진행 |
| 종료 코드 1~254 | 남은 시작 절차를 건너뛰고 실패로 기록하지 않음 | 실패로 기록되고 이후 단계 중단 |
| 종료 코드 255 또는 비정상 종료 | 실패로 기록 | 실패로 기록 |
| 주된 용도 | 시작 여부를 결정하는 조건 검사 | 시작 전에 반드시 성공해야 하는 준비 작업 |
핵심은 "조건이 맞지 않아 시작하지 않음"과 "준비 작업이 실패함"을 분리할 수 있느냐이다. 조건 불일치를 정상 흐름으로 다뤄야 하면 ExecCondition=, 그 단계가 실패하면 유닛 실패로 봐야 하면 ExecStartPre=가 맞다.
종료 코드는 어떻게 해석될까?
공식 문서 기준으로 ExecCondition=은 세 구간으로 나뉜다. 첫째, 종료 코드 0 또는 SuccessExitStatus=에 포함된 값이면 다음 명령으로 진행한다. 둘째, 1부터 254까지면 남은 명령을 건너뛰고 유닛을 실패로 표시하지 않는다. 셋째, 255 또는 타임아웃, 시그널 종료 같은 비정상 종료는 유닛 실패로 처리된다.
이 차이 때문에 /usr/bin/test, grep -q, sh -c '...' 같은 조건성 명령을 붙이기 쉽다. 다만 명령 자체가 복잡해져서 종료 코드 의미가 흐려지면 운영자가 상태를 읽기 어려워질 수 있으므로, 조건 검사만 맡기는 편이 안전하다.
ExecStartPre=에는 무엇을 두는 편이 맞을까?
ExecStartPre=는 메인 프로세스를 띄우기 전에 반드시 성공해야 하는 준비 작업에 가깝다. 예를 들면 런타임 디렉터리 권한 조정, 설정 문법 검사, 필요한 파일 생성처럼 "이 단계가 실패하면 시작 자체를 중단해야 하는 작업"이 여기에 해당한다.
공식 문서는 ExecStartPre=에 장시간 실행되는 프로세스를 두지 말라고 명시한다. 여기서 파생된 프로세스는 다음 서비스 프로세스가 실행되기 전에 정리되기 때문이다. 같은 권고가 ExecCondition=에도 적용되므로, 둘 다 짧고 결정적인 명령에만 쓰는 편이 맞다.
ExecStartPost=는 언제 의미가 생길까?
ExecStartPost=는 ExecStart=가 성공적으로 시작된 뒤 실행된다. 여기서 "성공"은 Type=에 따라 달라진다. 예를 들어 Type=simple은 프로세스 시작 직후, Type=oneshot은 마지막 ExecStart= 종료 후, Type=notify는 READY=1 수신 후를 기준으로 한다.
또 하나 중요한 점은 공식 문서가 ExecStartPost= 실행 시간도 Before=, After= ordering 계산에 포함된다고 설명한다는 점이다. 즉 후속 유닛이 시작되기 전에 꼭 끝나야 하는 짧은 후처리라면 여기에 둘 수 있지만, 오래 걸리는 부가 작업을 넣으면 의존 유닛 시작도 같이 늦어진다.
시작 중간에 실패했을 때 정리 작업은 어디에 둬야 할까?
이 구간에서 ExecStop=와 ExecStopPost=를 혼동하기 쉽다. 공식 문서에 따르면 ExecStop=는 서비스가 "성공적으로 시작된 뒤"에만 실행된다. 반대로 ExecStartPre=, ExecStart=, ExecStartPost= 중 하나가 실패하거나 타임아웃이 나면 ExecStop=는 건너뛰고 ExecStopPost=로 이어진다.
따라서 시작 도중 남을 수 있는 임시 파일, 반쯤 만들어진 상태 디렉터리, 외부 락 해제 같은 정리 작업은 ExecStopPost=에 두는 편이 맞다. 공식 문서는 이 단계가 서비스 실패 결과와 종료 상태를 담은 $SERVICE_RESULT, $EXIT_CODE, $EXIT_STATUS 환경 변수를 받을 수 있다고 설명한다.
운영에서 무난한 선택 기준은 무엇일까?
| 상황 | 권장 위치 | 이유 |
|---|---|---|
| 특정 파일이나 장치가 있을 때만 시작 | ExecCondition= |
조건 불일치를 실패와 분리할 수 있음 |
| 문법 검사나 디렉터리 생성처럼 실패 시 시작 중단이 맞는 준비 작업 | ExecStartPre= |
실패를 즉시 유닛 실패로 기록함 |
| 시작 성공 직후의 짧은 후처리 | ExecStartPost= |
Type= 기준의 시작 완료 뒤 실행됨 |
| 시작 실패까지 포함해 항상 수행해야 하는 정리 작업 | ExecStopPost= |
초기화 도중 실패한 경우에도 호출됨 |
실무 기본값은 단순하다. 시작 여부를 판정하면 ExecCondition=, 시작 전에 반드시 끝내야 하는 준비면 ExecStartPre=, 시작 성공 뒤 짧은 후처리면 ExecStartPost=, 실패 포함 정리면 ExecStopPost=로 나누면 된다.
자주 묻는 질문
Q. 조건 검사도 결국 실패 아닌가?
systemd 공식 문서 기준으로는 다르다. ExecCondition=에서 종료 코드 1부터 254까지는 유닛 실패가 아니라 "나머지 시작 절차를 진행하지 않음"으로 처리된다. 운영자가 의도적으로 건너뛴 시작과 실제 장애를 분리하고 싶을 때 이 차이가 중요하다.
Q. ExecCondition= 안에서 백그라운드 프로세스를 띄워도 될까?
권장되지 않는다. 공식 문서는 ExecStartPre=에 장시간 실행 프로세스를 두지 말라고 하며, 같은 권고가 ExecCondition=에도 적용된다고 적고 있다. 두 옵션 모두 짧고 판정 가능한 명령에 한정하는 편이 안전하다.
Q. 시작 중간 실패에도 반드시 청소해야 하면 ExecStop=면 충분할까?
충분하지 않다. 공식 문서 기준으로 서비스가 성공적으로 시작되지 못한 경우 ExecStop=는 호출되지 않을 수 있다. 이런 경우까지 포함해야 하면 ExecStopPost=를 써야 한다.
정리
ExecCondition=의 역할은 "시작 전 검사"가 아니라 "조건 불일치를 실패와 분리하는 시작 전 검사"에 가깝다. 그래서 준비 작업을 넣는 용도인 ExecStartPre=와는 의도가 다르다.
2026년 6월 27일 기준 upstream systemd 공식 문서를 기준으로 보면 판단 기준은 네 가지면 충분하다. 조건 불일치를 실패로 기록하지 않아야 하는지, 준비 작업이 반드시 성공해야 하는지, 시작 성공 뒤 후처리가 필요한지, 그리고 시작 실패까지 포함한 정리가 필요한지다.
참고 자료
'프로그래밍 > 운영체제' 카테고리의 다른 글
| systemd RandomizedDelaySec 기준 정리 (0) | 2026.07.11 |
|---|---|
| systemd override.conf 사용법 (1) | 2026.07.05 |
| systemd Type=notify 기준 정리 (0) | 2026.06.22 |
| systemd Restart 정책 기준 정리 (0) | 2026.06.15 |
| systemd RuntimeDirectory와 StateDirectory 기준 정리 (0) | 2026.06.09 |





