curl로 API를 확인할 때는 HTTP 상태 코드와 curl 종료 코드를 따로 봅니다. 서버가 404를 응답해도 기본 curl은 전송을 마치면 종료 코드 0을 낼 수 있습니다. 자동화에서 요청 성공을 판단하려면 이 차이를 먼저 정해야 합니다.
아래 명령은 macOS·Linux의 셸 문법 기준입니다. 로컬 테스트 서버가 200과 404를 돌려주도록 만든 뒤 curl 8.7.1에서 상태 코드와 종료 코드를 비교했습니다. 예제의 127.0.0.1:8765는 연습 주소이며 실제 API 주소로 바꿔 사용합니다.
1. 본문과 상태 코드를 따로 남기기
curl -sS --connect-timeout 5 --max-time 15 \
-o response.json \
-w 'HTTP %{http_code}\n' \
http://127.0.0.1:8765/ok
printf 'curl exit=%s\n' "$?"
-o는 본문을 파일에 저장하고, -w는 전송 뒤 필요한 정보를 출력합니다. -sS는 진행률을 숨기면서 오류 메시지는 표시합니다. response.json은 덮어써질 수 있으므로 연습용 디렉터리에서 실행하거나 새 파일명을 정합니다.
확인한 로컬 응답은 HTTP 200, curl exit=0이었습니다. 파일 확장자를 json으로 정했다고 서버 응답까지 JSON이 되는 것은 아닙니다. Content-Type과 실제 본문을 확인한 다음 JSON 도구로 읽어야 합니다.
종료 코드의 $?는 바로 앞 명령의 결과입니다. curl 뒤에 다른 명령을 먼저 실행하면 그 명령의 종료 코드로 바뀝니다. 위 예제에서 printf를 바로 다음 줄에 둔 이유입니다.
2. 404를 자동화 실패로 처리하려면
curl -sS --fail-with-body \
--connect-timeout 5 --max-time 15 \
-o error-response.txt \
-w 'HTTP %{http_code}\n' \
http://127.0.0.1:8765/missing
printf 'curl exit=%s\n' "$?"
같은 로컬 404 응답을 두 조건으로 비교했습니다. --fail-with-body를 사용한 경우에도 본문은 파일에 남았습니다.
| 조건 | HTTP 코드 | curl 종료 코드 |
| 기본 요청 | 404 | 0 |
| --fail-with-body 사용 | 404 | 22 |
--fail-with-body는 curl 7.76.0부터 제공됩니다. curl --version으로 설치된 버전을 확인하세요. HTTP 오류 응답을 받았다는 사실과 네트워크 연결 자체가 성립하지 않은 상황은 다릅니다. HTTP 코드가 000으로 나왔다면 정상적인 HTTP 응답 코드를 얻지 못한 것이므로 오류 메시지와 종료 코드를 함께 봅니다.
3. 헤더는 HEAD와 GET을 구분해서 확인하기
curl -I --max-time 15 https://example.com/
curl -sS --max-time 15 \
-D headers.txt -o body.txt \
https://example.com/
첫 명령의 -I는 HTTP에서 HEAD 요청을 사용합니다. 두 번째 명령은 GET 응답의 헤더와 본문을 파일로 나눕니다. API가 HEAD를 별도로 처리한다면 브라우저 GET과 결과가 다를 수 있으므로, 실제로 확인할 메서드와 맞추는 편이 정확합니다.
주소 이동을 따라가야 하는 조회 요청에는 -L을 사용합니다. 최종 URL과 상태를 함께 출력하면 어느 주소의 응답인지 알 수 있습니다. 아래 명령은 사용법 예제이며 외부 사이트의 현재 응답값을 측정한 표는 아닙니다.
curl -sS -L --max-time 15 -o /dev/null \
-w 'HTTP %{http_code}\nURL %{url_effective}\n' \
https://example.com/
4. 시간 제한과 오류 본문을 같이 남기기
| 옵션 | 확인 목적 |
| --connect-timeout 5 | 연결 단계의 대기 제한 |
| --max-time 15 | 전송 전체의 시간 제한 |
| -D headers.txt | 응답 헤더 보관 |
| -o body.txt | 본문을 별도 파일로 보관 |
본문에 오류 원인과 요청 식별자가 들어 있는 API도 있습니다. HTTP 코드만 남기면 확인에 필요한 문맥이 사라질 수 있어 헤더와 본문을 구분해서 보관합니다. 공유할 때는 인증 헤더, 쿠키, 개인 데이터가 들어 있는지 먼저 확인합니다.
앱에서도 같은 주소 호출을 확인한다면 adb로 로그를 추출하는 방법을 이어 사용할 수 있습니다. Android에서 HTTP 요청 허용 여부가 관여하는 상황은 Cleartext 통신 설정과 분리해 점검하세요. 터미널 요청이 성공했다고 앱 환경까지 같아지는 것은 아닙니다.
자주 묻는 질문
HTTP 200이면 업무 처리가 끝난 건가요?
HTTP 응답 단계의 성공입니다. API가 본문에 별도 업무 결과 코드를 제공한다면 그 값도 확인해야 합니다. 비동기 작업은 이후 상태 조회가 필요할 수도 있습니다.
--fail과 --fail-with-body의 차이는 무엇인가요?
HTTP 오류를 종료 코드로 표시하는 목적은 같습니다. --fail-with-body는 응답 본문을 남겨 오류 내용을 확인할 수 있게 합니다. 옵션의 세부 조건은 설치 버전의 도움말을 함께 확인합니다.
Windows에서도 같은 명령을 쓰나요?
curl 옵션은 참고할 수 있지만 줄 연결과 종료 코드 문법은 셸마다 다릅니다. PowerShell에서는 curl.exe로 실행 대상을 명확히 하고 $LASTEXITCODE를 확인합니다. 이 글의 역슬래시 줄 연결을 그대로 붙이는 방식은 macOS·Linux 셸 기준입니다.
옵션과 지원 버전의 근거는 curl 공식 매뉴얼입니다. 직접 확인한 범위는 로컬 200·404 응답과 --fail-with-body 비교이며, 외부 API의 인증·리디렉션 동작을 보장하는 결과는 아닙니다.
'개발 문제 해결' 카테고리의 다른 글
| MySQL EXPLAIN 보는 법: type·key·rows 읽는 순서 (0) | 2026.09.12 |
|---|---|
| Docker 로그 확인: 최근 100줄·시간 범위·Compose 조회 (0) | 2026.09.12 |
| 파이썬 JSON 파일 저장·읽기: 한글과 JSONDecodeError 확인 (0) | 2026.09.12 |
| 리눅스 용량 큰 파일 찾기: df·du·find로 범인 잡는 순서 (0) | 2026.09.11 |
| adb 명령어 모음: 기기 연결 안 될 때부터 apk 설치와 로그 추출까지 (0) | 2026.09.11 |
댓글