CS학습5 min read
curl: URL로 HTTP 요청을 보내고 응답을 확인하는 명령줄 클라이언트
curl은 URL을 지정해 HTTP, HTTPS, FTP 등 여러 프로토콜로 데이터를 주고받는 명령줄 도구이다. 브라우저나 별도 도구 없이 API 요청과 응답 헤더를 직접 확인할 수 있어 디버깅과 자동화에 널리 쓰인다. 이 글에서는 기본 옵션, 요청 구성 방식, 스크립트에서의 사용법과 주의점을 다룬다.
By 송민성
1. 개념
curl은 URL 문법으로 서버와 데이터를 주고받는 명령줄 클라이언트(command-line client)이다. 내부적으로는 libcurl이라는 전송 라이브러리를 사용하며, HTTP/HTTPS를 비롯해 FTP, SMTP 등 다양한 프로토콜을 지원한다.
기본 형태는 다음과 같다.
shell
curl [옵션] <URL>옵션 없이 실행하면 GET 요청을 보내고, 응답 본문(body)을 표준 출력(stdout)에 그대로 출력한다.
2. 왜 사용하는가
- 재현 가능한 요청: 브라우저 개발자 도구나 GUI 클라이언트 대신, 한 줄의 명령으로 요청을 공유하고 재현할 수 있다.
- 서버 환경에서 사용 가능: GUI가 없는 서버(SSH 접속 환경, 컨테이너)에서도 API 동작을 바로 확인할 수 있다.
- 자동화: 셸 스크립트, CI/CD 파이프라인, 헬스 체크(health check)에서 HTTP 호출을 간단히 수행한다.
- 상세한 진단: 요청 헤더, 응답 헤더, 상태 코드, 리다이렉트, TLS 협상 과정을 옵션으로 확인할 수 있다.
3. 동작 원리
curl이 URL을 처리하는 흐름은 다음과 같다.
- URL 파싱: 스킴(scheme), 호스트, 포트, 경로를 분리한다.
- 이름 해석(DNS resolution): 호스트 이름을 IP 주소로 변환한다.
- TCP 연결: 서버와 연결을 맺는다. HTTPS라면 이어서 TLS 핸드셰이크(handshake)를 수행한다.
- 요청 전송: 메서드, 경로, 헤더, 본문으로 구성된 HTTP 요청을 보낸다.
- 응답 수신: 상태 줄(status line), 헤더, 본문을 받아 stdout에 출력한다.
기본 동작은 다음과 같다.
- 리다이렉트(3xx)는 자동으로 따라가지 않는다.
-L옵션을 줘야 따라간다. - HTTP 4xx/5xx 응답도 전송 자체는 성공이므로 종료 코드(exit code)는 0이다.
-f(--fail)를 주면 오류 상태에서 비정상 종료 코드를 반환한다. -d로 본문을 지정하면 메서드가 자동으로 POST가 된다.
주요 옵션은 다음과 같다.
| 옵션 | 의미 |
|---|---|
| -X <메서드> | 요청 메서드 지정 |
| -H "헤더: 값" | 요청 헤더 추가 |
| -d <데이터> | 요청 본문 전송 (POST) |
| -i | 응답 헤더를 본문과 함께 출력 |
| -I | HEAD 요청을 보내 헤더만 출력 |
| -s | 진행률 표시 숨김(silent) |
| -S | -s와 함께 쓰면 오류 메시지는 표시 |
| -L | 리다이렉트 따라가기 |
| -o <파일> | 응답을 파일로 저장 |
| -O | URL의 파일명 그대로 저장 |
| -f | HTTP 오류 시 실패 처리 |
| -v | 요청·응답 과정을 상세 출력 |
| -w <형식> | 완료 후 지정한 형식으로 정보 출력 |
| --max-time <초> | 전체 작업 제한 시간 |
| --connect-timeout <초> | 연결 제한 시간 |
4. 코드 예제
GET 요청과 헤더 확인
shell
# 응답 본문만 출력
curl https://example.com
# 응답 헤더 + 본문
curl -i https://example.com
# 헤더만 확인 (HEAD 요청)
curl -I https://example.comJSON POST 요청
shell
curl -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-d '{"name": "kim", "age": 30}'-d를 사용하면 메서드가 이미 POST이므로 -X POST는 생략해도 동작한다.
상태 코드만 추출
shell
curl -s -o /dev/null -w "%{http_code}\n" https://example.com-o /dev/null로 본문을 버리고, -w로 상태 코드만 출력한다.
파일 다운로드
shell
# 지정한 이름으로 저장
curl -L -o page.html https://example.com
# URL의 파일명으로 저장
curl -LO https://example.com/file.txt인증 헤더 사용
shell
curl https://api.example.com/me \
-H "Authorization: Bearer $API_TOKEN"스크립트용 헬스 체크
shell
#!/bin/sh
URL="${1:-https://example.com}"
if curl -fsS --connect-timeout 3 --max-time 10 -o /dev/null "$URL"; then
echo "OK: $URL"
else
echo "FAIL: $URL" >&2
exit 1
fi-f로 HTTP 오류를 실패로 처리하고, -sS로 진행률은 숨기되 오류 메시지는 남긴다.
5. 시간 복잡도 또는 성능 특성
curl의 실행 시간은 알고리즘 복잡도보다 네트워크 지연에 좌우된다. 요청마다 DNS 조회, TCP 연결, TLS 핸드셰이크가 발생하므로 이 비용을 확인하는 것이 중요하다. -w로 단계별 시간을 볼 수 있다.
shell
curl -s -o /dev/null https://example.com -w \
"dns: %{time_namelookup}s\nconnect: %{time_connect}s\ntls: %{time_appconnect}s\nfirst byte: %{time_starttransfer}s\ntotal: %{time_total}s\n"- 별도의 curl 프로세스를 여러 번 실행하면 매번 새 연결을 맺는다.
- 하나의 curl 명령에 URL을 여러 개 주면 가능한 경우 연결을 재사용할 수 있다.
6. 실무 사용 사례
- API 디버깅: 프런트엔드나 서버 코드를 거치지 않고 엔드포인트의 응답을 직접 확인한다.
- 배포 후 검증: 배포 직후 헬스 체크 엔드포인트의 상태 코드를 확인한다.
- 리다이렉트 추적:
curl -IL <URL>로 리다이렉트 경로와 각 단계의 헤더를 본다. - 설치 스크립트 다운로드: 파일 다운로드 후 검증하고 실행하는 방식으로 도구를 설치한다.
- 브라우저 요청 재현: 개발자 도구 Network 탭에서 "Copy as cURL"로 복사해 터미널에서 재현한다.
7. 주의할 점
- 셸 따옴표 처리: JSON 본문은 작은따옴표로 감싸야 큰따옴표가 보존된다. URL에
&가 있으면 따옴표로 감싸지 않을 때 셸이 백그라운드 실행으로 해석한다. - `-k`(`--insecure`): TLS 인증서 검증을 끈다. 운영 환경에서는 사용하지 말고, 임시 테스트에서도 신중히 쓴다.
- 민감 정보 노출: 토큰을 명령줄에 직접 쓰면 셸 히스토리와 프로세스 목록에 남을 수 있다. 환경 변수나 설정 파일을 활용한다.
- `curl ... | sh` 패턴: 내려받은 스크립트를 검증 없이 바로 실행하므로 위험하다. 먼저 파일로 받아 내용을 확인한 뒤 실행한다.
- 종료 코드 오해:
-f없이는 404나 500 응답에도 종료 코드가 0이다. 스크립트에서는-f를 쓰거나 상태 코드를 직접 검사한다. - 타임아웃 미설정: 기본적으로 응답이 없으면 오래 대기할 수 있으므로 자동화에서는
--connect-timeout과--max-time을 지정한다.
8. 핵심 정리
- curl은 URL을 기반으로 여러 프로토콜의 요청을 보내는 명령줄 클라이언트이며, 기본은 GET이다.
-i,-I,-v로 헤더와 통신 과정을 확인하고,-H,-d로 요청을 구성한다.- 리다이렉트는
-L, HTTP 오류의 실패 처리는-f를 명시해야 한다. - 스크립트에서는
-fsS와 타임아웃 옵션을 함께 쓰는 것이 안전하다. -w로 상태 코드와 단계별 소요 시간을 추출해 성능 진단에 활용할 수 있다.-k사용과 토큰 노출, 검증 없는curl | sh실행은 보안 위험이 있다.