Skip to content
블로그로 돌아가기
튜토리얼

curl 명령어 치트시트: HTTP·API 예제 40개 이상

개발자를 위한 완전한 curl 치트시트: GET/POST, 헤더, Bearer 인증, 파일 업로드/다운로드, API 테스트까지 복사해 쓰는 예제 40개 이상. 온라인 도구도 사용해 보세요.

14 분 소요

curl 명령어 치트시트: HTTP·API 예제 40개 이상

SSH로 스테이징 서버를 세 단계나 거쳐 들어왔는데 API가 엉뚱한 응답을 돌려주고, 설치된 HTTP 클라이언트라곤 curl뿐인 상황. 또는 서비스를 헬스 체크하는 CI 스크립트를 읽다가 -fsS가 실제로 무슨 일을 하는지 궁금한 상황. 아니면 동료가 Slack에 붙여 넣은 한 줄 명령을 내 상황에 맞게 고쳐 써야 하는 상황. curl은 어디에나 있지만, flag가 짧고 함축적이라 전부 외우는 사람은 거의 없습니다.

이 curl 치트시트는 바로 그런 순간을 위해 만들었습니다. 매일 쓰는 십여 개의 flag를 빠르게 찾아보는 표를 앞에 두고, 자주 하는 작업마다 복사해 붙여 넣을 수 있는 명령 예제를 이어서 정리했습니다. GET·POST 요청, 헤더 전송, Bearer token 인증, 파일 업로드와 다운로드, 스크립트에서의 API 테스트까지 모두 다룹니다. 모든 명령은 실제로 실행되는 URL(httpbin.org 또는 api.example.com 자리 표시자)을 사용하므로, 붙여 넣고 바로 시험해 볼 수 있습니다. 동작은 공식 curl 문서와 현행 HTTP 시맨틱 표준인 RFC 9110에 근거합니다.

빠른 참조 — 실제로 쓰게 되는 curl flag

매일 쓰는 curl의 90%는 십여 개의 flag로 끝납니다. 이 표를 즐겨찾기에 넣어 두세요. 가이드의 나머지 부분은 각 flag를 실행 가능한 curl 명령 예제와 함께 자세히 풀어냅니다.

Flag의미예제
-XHTTP 메서드 설정curl -X DELETE https://api.example.com/items/42
-H요청 헤더 추가(반복 가능)curl -H "Accept: application/json" https://httpbin.org/get
-d요청 본문 전송(POST 자동 적용)curl -d "name=alice" https://httpbin.org/post
--jsonJSON 본문 전송 + JSON 헤더 설정curl --json '{"id":1}' https://httpbin.org/post
-Fmultipart 폼 필드 / 파일 전송curl -F "file=@report.pdf" https://httpbin.org/post
-o지정한 이름으로 출력 저장curl -o page.html https://example.com
-O원격 파일명으로 저장curl -O https://example.com/archive.zip
-Lredirect 따라가기curl -L https://httpbin.org/redirect/2
-uBasic 인증 user:passcurl -u alice:s3cret https://httpbin.org/basic-auth/alice/s3cret
-i출력에 응답 헤더 포함curl -i https://httpbin.org/get
-I헤더만 가져오기(HEAD)curl -I https://example.com
-v자세히: 요청 + TLS handshake 표시curl -v https://example.com
-s조용히(진행 표시줄 없음)curl -s https://httpbin.org/get
-w전송 후 변수 출력curl -s -o /dev/null -w "%{http_code}" https://example.com
-bcookie 전송(문자열 또는 파일)curl -b cookies.txt https://httpbin.org/cookies
-c받은 cookie를 jar에 저장curl -c cookies.txt https://httpbin.org/cookies/set/a/1
-kTLS 인증서 검증 건너뛰기curl -k https://self-signed.example.com
--http2HTTP/2 요청curl --http2 https://example.com
--http3HTTP/3(QUIC) 요청curl --http3 https://example.com
-TPUT으로 파일 업로드curl -T backup.tar https://api.example.com/files/backup.tar
--data-urlencode본문 필드를 URL 인코딩curl --data-urlencode "q=hello world" https://httpbin.org/get -G
--max-time전체 전송 최대 시간 제한(초)curl --max-time 10 https://example.com
--connect-timeout연결 수립 최대 시간 제한(초)curl --connect-timeout 5 https://example.com
--retry실패한 전송을 N회 재시도curl --retry 3 https://example.com
--limit-rate전송 대역폭 제한curl --limit-rate 2M -O https://example.com/big.iso

curl 문법 기초 — 요청의 구조

curl 명령은 바이너리, 몇 개의 flag, 그리고 URL로 이루어집니다. URL은 flag 앞에 와도 되고 뒤에 와도 됩니다. curl은 순서를 따지지 않습니다. 대신 어떤 flag가 메서드나 본문을 암시하는지를 따집니다. 이 둘이 서로 영향을 주기 때문입니다.

간단한 GET 요청

메서드 flag가 없으면 curl은 GET을 보냅니다. 명령 전체가 이게 전부입니다.

curl https://httpbin.org/get

httpbin은 여러분의 요청을 JSON으로 그대로 되돌려 주므로 테스트에 안성맞춤입니다. 쿼리 문자열은 브라우저에서 하던 방식 그대로 붙입니다.

curl "https://httpbin.org/get?page=2&sort=desc"

URL은 따옴표로 감싸세요. 따옴표 없는 &는 셸에 명령을 백그라운드로 돌리라고 지시하면서 그 뒤의 모든 것을 조용히 버립니다. curl에서 가장 흔한 실수 중 하나이며, 아래 함정 섹션에서 다룹니다.

응답 보기: 본문, 헤더, 둘 다

기본적으로 curl은 응답 본문만 출력합니다. 무엇을 볼지는 세 개의 flag가 바꿉니다.

# 본문 + 상태 줄 + 응답 헤더
curl -i https://httpbin.org/get

# 헤더만 — HEAD 요청을 보내며 본문은 없음
curl -I https://example.com

# 전체 추적: 요청 줄, 요청 헤더, TLS handshake, 응답
curl -v https://example.com

본문과 함께 Content-Type이나 Set-Cookie를 잠깐 확인하고 싶을 때는 -i를 쓰세요. 다운로드하지 않고 리소스를 점검할 때(파일 크기, 마지막 수정 시각, redirect 대상)는 -I를 쓰세요. 무언가 잘못되어 curl이 실제로 무엇을 보냈는지 정확히 봐야 할 때는 -v를 꺼내 쓰세요.

redirect 따라가기

curl은 따로 요청하지 않으면 redirect를 따라가지 않습니다. -L 없이 301이나 302를 반환하는 URL을 치면, 목적지가 아니라 redirect 응답 자체를 받게 됩니다.

# 302에서 멈추고, 쓸 만한 건 아무것도 출력하지 않음
curl https://httpbin.org/redirect/1

# 마지막 200까지 연쇄를 따라감
curl -L https://httpbin.org/redirect/1

요청이 왜 그곳에 도착하는지 확신이 서지 않으면, -IL이 모든 단계의 상태 코드를 보여 줍니다. 각 코드가 무슨 의미인지, 그리고 301302가 왜 서로 바꿔 쓸 수 없는지는 HTTP 상태 코드 치트시트를 참고하세요.

curl로 다루는 HTTP 메서드(GET, POST, PUT, PATCH, DELETE)

curl은 여러분의 flag에 따라 메서드를 자동으로 고릅니다. -d--jsonPOST를 암시하고, 단순 URL은 GET을 암시합니다. 보내는 본문과 맞지 않는 메서드가 필요할 때만 -X를 쓰세요.

쿼리 매개변수를 포함한 GET

값에 공백이나 &가 들어가는 순간 쿼리 문자열을 손으로 만드는 일은 오류가 잦아집니다. -G flag는 --data-urlencode 필드를 제대로 인코딩된 쿼리 문자열로 만들어 URL에 덧붙이라고 curl에 지시합니다.

curl -G https://httpbin.org/get \
  --data-urlencode "q=hello world" \
  --data-urlencode "tag=c++"

이렇게 하면 ?q=hello%20world&tag=c%2B%2B가 만들어집니다. curl이 퍼센트 인코딩을 처리해 주므로 망가진 URL을 보내는 일이 없습니다.

POST: 폼 데이터 vs JSON

curl post request는 흔히 두 가지 형태로 나타납니다. 폼 인코딩(고전적인 HTML 폼 본문)은 다음과 같습니다.

curl -d "name=alice&role=admin" https://httpbin.org/post

-dContent-Type: application/x-www-form-urlencoded를 설정하고 메서드를 알아서 POST로 바꿉니다. JSON API에는 JSON을 대신 보냅니다.

curl -d '{"name":"alice","role":"admin"}' \
  -H "Content-Type: application/json" \
  https://httpbin.org/post

curl 7.82부터는 이걸 한 줄로 줄이는 방법이 생겼는데, 바로 다음 섹션에서 다룹니다.

PUT과 PATCH

PUT은 리소스를 교체하고, PATCH는 그중 일부를 갱신합니다. PUT은 idempotent합니다. 두 번 보내도 상태가 같게 유지됩니다.

# 리소스 전체를 교체
curl -X PUT -d '{"name":"alice","role":"owner"}' \
  -H "Content-Type: application/json" \
  https://api.example.com/users/7

# 필드 하나만 갱신
curl -X PATCH -d '{"role":"owner"}' \
  -H "Content-Type: application/json" \
  https://api.example.com/users/7

DELETE

DELETE는 보통 본문을 싣지 않으므로 -X만 있으면 됩니다.

curl -X DELETE https://api.example.com/users/7

헤더와 JSON 본문 보내기

실무 API 작업의 대부분은 헤더와 JSON으로 이루어집니다. 이 일을 거의 도맡는 flag가 둘 있습니다. -H--json입니다.

-H로 커스텀 curl 헤더 보내기

-H는 헤더 하나를 추가하며, 필요한 만큼 반복할 수 있습니다. 이것이 Accept, Authorization, 커스텀 X- 헤더, 요청 ID를 설정하는 방법입니다.

curl https://httpbin.org/headers \
  -H "Accept: application/json" \
  -H "X-Request-Id: 9f3c1a" \
  -H "User-Agent: my-cli/1.0"

curl이 기본으로 보내던 헤더를 제거하려면 빈 값을 주세요(-H "User-Agent:"). 값 없이 헤더만 보내려면 세미콜론을 쓰세요(-H "X-Empty;").

POST JSON: -d vs 현대적인 --json flag

curl 7.82부터 --json은 JSON curl post request를 보내는 가장 자연스러운 방법입니다. 한 번에 세 가지를 합니다. Content-Type: application/json을 설정하고, Accept: application/json을 설정하며, 본문을 그대로 보냅니다.

# 장황한 옛 방식 — 세 조각을 서로 맞춰 둬야 함
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"name":"alice"}' \
  https://httpbin.org/post

# 현대적 등가 표현
curl --json '{"name":"alice"}' https://httpbin.org/post

--json은 반복 가능하며 이어 붙여지고, --json @file.json은 파일에서 본문을 읽습니다. JSON API라면 이쪽을 택하세요.

Content-Type과 Accept

이 두 헤더가 바로 415와 406 오류가 나오는 곳입니다. Content-Type은 여러분이 보내는 본문을 설명하고, Accept는 무엇을 돌려받고 싶은지 말합니다. 폼 데이터만 받는 엔드포인트에 JSON을 보내면 415 Unsupported Media Type을 받습니다. JSON 전용 API에 XML을 요청하면 406 Not Acceptable을 받을 수 있습니다. (이 코드들은 HTTP 상태 코드 가이드에서 풀어 설명합니다.)

응답이 한 덩어리로 압축된 JSON으로 돌아오면, JSON 포맷터로 보기 좋게 정리하거나, 곧장 jq로 파이프해 필드 하나만 뽑아낼 수 있습니다.

curl -s https://httpbin.org/json | jq '.slideshow.title'

API 응답을 선택·매핑·재구성하는 jq 필터 전체는 jq 명령줄 JSON 치트시트를 참고하세요.

curl로 하는 인증

거의 모든 API는 네 가지 인증 방식으로 커버됩니다. Basic 인증, Bearer token, API 키, cookie입니다.

Basic 인증(-u user:pass)

-u는 여러분의 자격 증명을 Base64로 인코딩한 HTTP Authorization: Basic 헤더를 보냅니다.

curl -u alice:s3cret https://httpbin.org/basic-auth/alice/s3cret

비밀번호를 생략하면(-u alice) curl이 입력을 요청하므로, 셸 기록에 남지 않습니다.

Bearer token과 OAuth

대부분의 현대 API는 curl bearer token을 씁니다. OAuth 2.0 access token이나 API token을 Authorization 헤더에 담는 방식입니다. curl에는 헤더를 손으로 쓰는 것과 동등한 단축 표현 --oauth2-bearer가 있습니다.

# 명시적 헤더
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.abc" \
  https://api.example.com/me

# 단축 표현
curl --oauth2-bearer "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.abc" \
  https://api.example.com/me

백엔드가 token을 거부하면, curl을 탓하기 전에 JWT 디코더로 디코딩해 exp(만료), aud(대상), iss(발급자) 클레임을 확인하세요. 만료되었거나 대상이 잘못된 token이 흔한 원인입니다.

API 키(헤더 vs 쿼리 매개변수)

어떤 API는 키를 헤더에, 어떤 API는 쿼리 매개변수에 담길 원합니다. URL은 로그와 브라우저 기록에 새어 나가므로 헤더가 더 안전합니다.

# 권장: 키를 헤더에
curl -H "X-API-Key: sk_live_a1b2c3" https://api.example.com/data

# 덜 안전: 키를 URL에(접근 로그에 남음)
curl "https://api.example.com/data?api_key=sk_live_a1b2c3"

-c는 cookie jar에 쓰고, -b는 그것을 다시 읽습니다. 이것이 여러 요청에 걸쳐 세션을 이어 가는 방법입니다.

# 로그인하고 세션 cookie를 저장
curl -c jar.txt -d "user=alice&pass=s3cret" https://httpbin.org/cookies/set/session/abc123

# 다음 호출에서 재사용
curl -b jar.txt https://httpbin.org/cookies

보안 주의: token과 자격 증명은 오직 HTTPS 연결에만 실어야 합니다. TLS는 헤더를 암호화하지만 평문 HTTP는 그렇지 않습니다. 비밀 정보를 명령줄에 직접 넣는 일은 피하세요. 셸 기록과 ps 출력에 남습니다. -H @authfile로 파일에서 헤더를 읽거나 환경 변수에서 값을 가져오세요(-H "Authorization: Bearer $TOKEN").

파일 다운로드와 업로드

curl이라는 이름은 “client URL”에서 왔습니다. 파일을 옮기는 것이 원래 본업이기 때문입니다. 다운로드와 업로드 각각에 알아 둘 만한 flag가 몇 개 있습니다.

다운로드: -O vs -o vs -C -

-O(대문자 O)는 파일을 원격 이름 그대로 저장합니다. -o(소문자)는 이름을 직접 고르게 해 줍니다. -C -는 중단된 다운로드를 멈춘 지점부터 이어 받습니다.

# 원격 파일명으로 저장: archive.zip
curl -O https://example.com/downloads/archive.zip

# 직접 고른 이름으로 저장
curl -o backup.zip https://example.com/downloads/archive.zip

# 중단된 다운로드를 이어 받기
curl -C - -O https://example.com/downloads/archive.zip

# 실제 파일로 가는 redirect 따라가기(CDN에서 흔함)
curl -OL https://example.com/latest/archive.zip

redirect 뒤에 있는 콘텐츠를 curl download file하려면 -L을 추가하세요. 릴리스 페이지와 CDN 링크는 거의 항상 redirect합니다.

업로드: -T vs -F

-TPUT으로 파일을 업로드하며 원시 바이트를 본문으로 보냅니다(객체 스토리지와 REST 파일 엔드포인트에서 흔함). -Fmultipart/form-data 요청을 보내는데, 브라우저가 파일 입력에 쓰는 것과 같은 형식입니다.

# 원시 바이트를 PUT
curl -T report.pdf https://api.example.com/files/report.pdf

# multipart/form-data 업로드(@ 접두사 주의)
curl -F "file=@report.pdf" -F "title=Q2 report" https://httpbin.org/post

@ 접두사는 파일의 내용을 읽으라고 curl에 지시합니다. 이것이 없으면 -F "file=report.pdf"는 파일이 아니라 report.pdf라는 문자열 그대로를 보냅니다.

--data-urlencode와 퍼센트 인코딩

값에 공백, &, =, 또는 비ASCII 문자가 들어 있으면 -d는 그것을 있는 그대로 보내 요청을 망칩니다. --data-urlencode는 그것을 올바르게 인코딩합니다.

# 잘못된 예: &가 본문을 쪼개고, 공백은 유효하지 않음
curl -d "q=hello world&filter=a&b" https://httpbin.org/post

# 올바른 예: 각 필드가 퍼센트 인코딩됨
curl --data-urlencode "q=hello world" \
  --data-urlencode "filter=a&b" \
  https://httpbin.org/post

%20%26 시퀀스가 무슨 뜻인지 이해해야 하거나, 이중 인코딩된 값을 디버깅해야 한다면, URL 인코더 디코더에 붙여 넣거나 URL 인코딩/디코딩 가이드의 바이트 단위 설명을 읽어 보세요.

API 테스트와 응답 살펴보기

-w로 전송에 관한 거의 모든 정보를 끄집어낼 수 있고 종료 코드로 실패를 감지할 수 있어서, curl은 스크립트와 CI에서 특히 쓸모가 많습니다.

상태 코드만 가져오기

HTTP 상태만 잡으려면, -o /dev/null로 본문을 버리고 -w로 코드를 출력하세요.

curl -s -o /dev/null -w "%{http_code}\n" https://httpbin.org/status/204
# → 204

이것이 모든 curl api testing 헬스 체크의 핵심입니다. 돌려받은 숫자를 해석하려면 HTTP 상태 코드 치트시트가 모든 범위를 다룹니다.

타이밍 분석

-w는 타이밍 변수를 드러내므로, 시간이 어디서 소요되는지 볼 수 있습니다. DNS, TCP 연결, TLS, 아니면 서버 자체인지 말이죠.

curl -s -o /dev/null \
  -w "dns=%{time_namelookup}s connect=%{time_connect}s tls=%{time_appconnect}s total=%{time_total}s\n" \
  https://example.com
# → dns=0.004s connect=0.021s tls=0.058s total=0.142s

time_appconnect가 높으면 TLS를 가리키고, time_starttransfer가 높으면 느린 백엔드를 가리킵니다.

조용하되 오류는 보여 주기

-s는 진행 표시줄을 숨기지만, 오류 메시지도 함께 숨깁니다. 스크립트에서는 함정입니다. -S와 짝지으면 curl이 성공 시에는 조용히 있다가 실패는 여전히 보고합니다.

curl -sS https://api.example.com/health

CI / 스크립트에서의 curl: HTTP 오류 시 실패 처리

기본적으로 curl은 404500에서도 0으로 종료합니다. 전송 자체는 성공했기 때문입니다. 헬스 체크에서는 원하는 것과 정반대입니다. -f(fail)는 curl이 HTTP 오류 시 0이 아닌 값으로 종료하게 만들어, 파이프라인이 그것을 잡아내게 합니다.

# 엔드포인트가 4xx/5xx를 반환하면 빌드를 실패시킴
curl -fsS https://api.example.com/health || exit 1

-fsS(fail, silent, show-errors)는 표준적인 헬스 체크 조합입니다. 더 풍부한 진단이 필요하면 --fail-with-body(curl 7.76+)가 종료 전에 오류 응답을 출력해 줍니다.

타임아웃과 재시도

영원히 멈춰 있는 헬스 체크는 빠르게 실패하는 것보다 나쁩니다. 스크립트로 만든 요청마다 --max-time(전체 전송의 상한)과 --connect-timeout(연결 수립만의 상한)으로 한계를 두세요:

# 연결 5초, 합계 10초 후 중단
curl --connect-timeout 5 --max-time 10 -fsS https://api.example.com/health

네트워크가 불안정할 때는 --retry가 지수 백오프로 실패한 전송을 재시도합니다. 기본적으로는 일시적 실패(타임아웃, 5xx)만 재시도하며, --retry-all-errors를 추가하면 연결 거부도 재시도합니다:

# 최대 3회, 사이에 간격을 두고 재시도
curl --retry 3 --retry-all-errors --max-time 30 -fsS https://api.example.com/health

스크립트가 큰 파일을 내려받으면서 회선을 포화시키고 싶지 않다면 --limit-rate가 대역폭을 제한합니다. --limit-rate 2M은 2 MB/s로 묶습니다.

curl로 다루는 HTTP/1.1, HTTP/2, HTTP/3

curl은 ALPN을 통해 TLS 위에서 HTTP 버전을 협상합니다. 특정 프로토콜 경로를 테스트해야 할 때는 버전을 강제할 수 있습니다.

--http2--http3

# HTTP/2 요청(사용할 수 없으면 1.1로 폴백)
curl --http2 https://example.com

# QUIC 위에서 HTTP/3 요청
curl --http3 https://example.com

HTTP/3은 QUIC 위에서 동작하며 TLS 1.3을 요구합니다. 여러분의 curl이 HTTP/3을 지원하는 백엔드로 빌드되어 있고 동시에 서버가 Alt-Svc 헤더로 그것을 알릴 때만 동작합니다. curl --version을 실행해 features 줄에 HTTP3이 보이는지 확인하세요. 보이지 않으면 --http3은 오류를 냅니다.

자세한 TLS / ALPN 정보

-v는 협상된 프로토콜과 TLS handshake를 보여 주는데, 이것이 버전이 실제로 적용되었는지 확인하는 방법입니다.

curl -v --http2 https://example.com 2>&1 | grep -i "ALPN\|HTTP/2"
# → * ALPN: server accepted h2
# → > GET / HTTP/2

handshake 출력에서 ALPN: server accepted h2(HTTP/2) 또는 h3(HTTP/3)을 찾아보세요.

흔한 curl 함정 8가지(그리고 해결법)

이 여덟 가지는 누구나 결국 한 번쯤 걸려 넘어집니다.

  1. 작은따옴표 vs 큰따옴표. 큰따옴표는 셸이 $VARS를 확장하게 하고, 작은따옴표는 모든 것을 글자 그대로 전달합니다. JSON 본문에는 작은따옴표를 써서 $!가 해석되지 않게 하세요: curl --json '{"price":"$5"}'. 확장을 원할 때는 큰따옴표를 쓰세요: -H "Authorization: Bearer $TOKEN".

  2. -d는 URL 인코딩을 하지 않는다. -d 값에 공백이나 &가 있으면 본문이 망가집니다. 아직 인코딩되지 않은 값에는 --data-urlencode로 바꾸세요.

  3. -d와 함께 쓰는 불필요한 -X POST. -d는 이미 POST를 암시합니다. -X POST -d ...라고 쓰는 건 무해하지만 중복입니다. 더 나쁜 건 -X GET -d ...인데, GET에 본문을 실어 보내 일부 서버를 당황하게 합니다. 메서드는 본문 flag가 정하게 두세요.

  4. 파일에서 읽을 때 @를 잊는 것. -d @body.json은 파일을 읽고, -d body.jsonbody.json이라는 글자 그대로의 텍스트를 보냅니다. -F "file=@upload.png"-F "file=upload.png"도 같은 함정입니다.

  5. 인증서 오류에 -k부터 꺼내 드는 것. -k는 TLS 검증을 끄고 진짜 문제(만료된 인증서, 잘못된 호스트명, 빠진 중간 인증서)를 가립니다. 근본 원인을 고치세요. --cacert ca.pem으로 CA를 설치하거나 시스템 신뢰 저장소를 업데이트하세요. -k는 여러분이 완전히 통제하는 self-signed 개발 서버용으로 아껴 두세요.

  6. -s가 오류를 삼키는 것. 조용한 모드는 스크립트에서 실패를 가립니다. 오류가 그래도 드러나도록 항상 -sS를 쓰세요.

  7. URL 안의 [ ] { }가 globbing되는 것. curl은 [1-5]{a,b}를 URL 범위/목록으로 취급합니다. 대괄호가 글자 그대로 들어간 URL(배열 쿼리 매개변수 arr[]=1에서 흔함)은 망가집니다. -g로 globbing을 끄세요: curl -g "https://api.example.com/items?id[]=1&id[]=2".

  8. 헤더 대소문자와 중복. HTTP 헤더 이름은 대소문자를 구분하지 않지만, 같은 헤더를 두 번 보내면 보통 둘 다 전송됩니다. 어떤 서버는 첫 번째를, 어떤 서버는 마지막을 취하고, 어떤 서버는 거부합니다. User-Agent 같은 기본값을 덮어쓸 때는 순서에 기대지 말고 -H로 한 번만 설정하세요.

curl vs wget vs HTTPie — 무엇을 쓸까

셋 다 HTTP로 가져오지만, 최적화하는 작업이 서로 다릅니다. curl vs wget 선택(그리고 HTTPie까지)을 한눈에 정리하면 다음과 같습니다.

작업curlwgetHTTPie
빠른 API 호출 / 디버깅우수제한적우수
JSON 본문양호(--json)번거로움우수(기본 지원)
재귀적 사이트 다운로드 / 미러링불가우수(-r)불가
대용량 다운로드 이어받기 + 재시도양호(-C -)우수(내장)불가
스크립팅 / CI(종료 코드, -w)우수양호양호
기본적으로 보기 좋게 색상 입힌 출력불가불가우수
거의 어디에나 사전 설치됨자주드물게

요약하면 이렇습니다. API 디버깅과 스크립트에는 curl(어디에나 있고 -w는 따라올 게 없습니다), 내 컴퓨터에서 읽기 좋은 JSON 사용성을 원할 때는 HTTPie, 사이트를 미러링하거나 자동 재시도로 파일을 일괄 다운로드할 때는 wget을 꺼내 쓰세요.

자주 묻는 질문

curl은 어디에 쓰나요?

curl은 HTTP, HTTPS, FTP를 비롯한 여러 프로토콜로 서버에 데이터를 주고받는 명령줄 도구입니다. 개발자는 curl로 API를 호출하고 디버깅하며, 파일을 다운로드하고 업로드하고, 스크립트와 CI 파이프라인에서 헬스 체크를 실행합니다.

curl로 POST 요청을 어떻게 보내나요?

폼 데이터에는 -d, JSON에는 --json을 쓰세요: curl --json '{"name":"alice"}' https://httpbin.org/post. 두 flag 모두 메서드를 자동으로 POST로 설정하므로 -X POST는 필요 없습니다.

curl에서 헤더를 어떻게 추가하나요?

-H "Name: value"를 쓰고, 헤더가 여러 개면 반복하세요: curl -H "Accept: application/json" -H "X-Request-Id: 9f3c1a" https://httpbin.org/headers. -H를 몇 번 넘기든 제한은 없습니다.

curl로 bearer token을 어떻게 보내나요?

Authorization 헤더를 넘기거나(curl -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/me), 단축 표현 --oauth2-bearer YOUR_TOKEN을 쓰세요. token은 오직 HTTPS로만 보내고, 디버깅할 때는 JWT 디코더로 디코딩하세요.

curl로 파일을 어떻게 다운로드하나요?

원격 파일명을 유지하려면 -O, 직접 이름을 고르려면 -o name을 쓰세요: curl -O https://example.com/archive.zip. redirect를 따라가려면 -L을, 중단된 다운로드를 이어 받으려면 -C -를 추가하세요.

curl로 HTTP 상태 코드만 어떻게 보나요?

본문을 버리고 코드를 출력하세요: curl -s -o /dev/null -w "%{http_code}" https://example.com. 스크립트에서 헬스 체크를 하는 표준 패턴입니다.

curl과 wget의 차이는 무엇인가요?

curl은 단일 리소스를 전송하며 기본적으로 stdout에 출력하므로 API 호출과 스크립팅에 안성맞춤입니다. wget은 재귀적 미러링과 자동 재시도를 포함해 다운로드에 특화되어 있습니다. API 테스트에는 curl을, 대량 파일 다운로드에는 wget을 쓰세요.

curl은 Windows에서 쓸 수 있나요?

네. curl은 Windows 10(빌드 1803+)과 Windows 11에 기본 포함되어 있으며, 명령 프롬프트와 PowerShell에서 curl로 사용할 수 있습니다. 다만 PowerShell은 과거에 curlInvoke-WebRequest의 별칭으로 두었으므로, flag가 예상과 다르게 동작하면 curl.exe를 명시적으로 호출하세요.

마무리

curl은 조금만 외워 두면 그만큼 돌려받습니다. 맨 위의 flag 표가 여러분이 실제로 입력하게 될 명령의 대부분을 덮고, 나머지는 어떤 flag가 메서드를 암시하는지, 어떤 flag에 따옴표가 필요한지, 어떤 flag가 스크립트에서 여러분을 속이는지(맞아요, 단독 -s, 당신 얘깁니다)를 아는 것으로 충분합니다. 이 curl 치트시트를 터미널 옆에 열어 두세요. 명령을 직접 조립하기 어려울 때는 cURL 명령 빌더를 이용해 시각적으로 생성해 보세요.

다음 단계도 어렵지 않습니다. curl로 요청을 보내고, 돌아온 응답을 HTTP 상태 코드 치트시트로 읽은 다음, JSON 포맷터로 JSON을 보기 좋게 정리하거나 jq 명령줄 JSON 치트시트로 잘라내세요. 전체 옵션 목록은 curl 매뉴얼에 빠짐없이 정리되어 있고, MDN의 HTTP 레퍼런스는 모든 메서드와 헤더 뒤에 있는 시맨틱을 설명합니다.

태그: curl http rest-api command-line developer-reference