- 技術 💻
curlコマンドの使い方とオプション一覧|エラー対処・Windows・wget比較
結論
curl(カール)は、URL を指定してデータを送受信するコマンドで、書式は curl [オプション] URL です。curl https://example.com で GET を送ります。
この記事でわかること
- よく使うオプション約70個の一覧(短い形・長い形・例)
- 終了コード22種と、エラー5つの実際の文と直し方
- PowerShell での引用符と、wget との違い9項目
curl はオプションでリクエストを組み立てて送り、返ってきたレスポンスの見せ方もオプションで決めます。
flowchart TD
A[curl コマンド] --> B[リクエスト<br>-X メソッド・-H ヘッダー・-d 本文]
B --> C[サーバー]
C --> D[レスポンス]
D --> E[画面に表示<br>-i ヘッダー・-w 情報]
D --> F[ファイルに保存<br>-o・-O]
API の動作確認、ファイルのダウンロード、サーバーの疎通確認に使われ、Linux・macOS・Windows 10 以降に入っています。
まず、よく使う形を目的別に並べます。どれも、この記事のために立てたローカルのサーバーに向けて実行し、結果を本文に載せています。
| やりたいこと | コマンド |
|---|---|
| ページや API の結果を見る(GET) | curl https://api.example.com/users |
| レスポンスヘッダーも見る | curl -i URL |
| JSON を POST する | curl --json '{"name":"山田"}' URL |
| ファイルとして保存 | curl -L -O URL(-LO と同じ) |
| ヘッダーを付ける | curl -H 'Authorization: Bearer TOKEN' URL |
| Windows の PowerShell で使う | curl.exe ...(.exe まで書く) |
| 通信の中身を詳しく見る | curl -v URL |
| ステータスコードだけ表示 | curl -s -o /dev/null -w '%{http_code}\n' URL |
| フォームを POST する | curl -d 'name=yamada' URL |
| ヘッダーだけ見る(HEAD) | curl -I URL |
| エラー(4xx・5xx)を失敗にする | curl -sS --fail-with-body URL |
確認環境:curl 8.22.0(2026-09-02 リリース。GitHub の curl-8_22_0 タグのソースを OpenSSL 3.0.13・nghttp2 1.59.0 でビルド)と、Ubuntu 24.04 の curl 8.5.0 を Linux で実行しました。相手は Python で作ったテスト用 HTTP サーバーと、自作の認証局で証明書を発行した nginx 1.24.0(HTTPS・HTTP/2)です。比較に GNU Wget 1.21.4、PowerShell 7.6.4(Linux 版)を使いました。Windows 同梱の curl、Windows PowerShell 5.1、HTTP/3 については、curl 公式と Microsoft のドキュメントで確かめています(確認日 2026年10月14日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「curlコマンドの使い方とオプション一覧|エラー対処・Windows・wget比較」
curlコマンドとは:書式とバージョンの確かめ方
curl は、HTTP・HTTPS をはじめ、FTP・SFTP・SMTP など多くのプロトコルでデータを転送するコマンドラインツールです。中身の部品は libcurl というライブラリで、PHP や多くのアプリが同じ libcurl を使っています。
curl [オプション...] URL [URL...]
使えるオプションや機能は、curl の版とビルドによって変わります。 まず curl -V(--version)で確かめます。
$ curl -V
curl 8.22.0 (Linux) libcurl/8.22.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 nghttp2/1.59.0
Release-Date: 2026-09-02
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt mqtts pop3 pop3s rtsp smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTPS-proxy IPv6 Largefile libz SSL threadsafe UnixSockets
- 1行目:curl と libcurl の版、TLS ライブラリ(OpenSSL など)
Protocols:使えるプロトコルFeatures:使える機能。HTTP2があれば HTTP/2、HTTP3があれば HTTP/3 が使えます
上のビルドは Features に HTTP3 が無いので、--http3 を付けると次のエラーになりました。
$ curl --http3 https://localhost:47443/echo
curl: option --http3: the installed libcurl version does not support this
同じ Linux でも、OS に入っている curl は版が違います。
| 環境 | curl の版 | 確かめ方 |
|---|---|---|
| curl 公式の最新版 | 8.22.0(2026-09-02) | 公式の変更履歴とソース |
| Ubuntu 24.04 の apt 版 | 8.5.0(2023-12-06 の版に修正を当てたもの) | curl -V の出力 |
| Windows 10・11 の同梱版 | 公式ページの例では 8.13.0 | curl 公式の Windows 向け説明 |
オプションの一覧は curl --help all で表示できます。 8.22.0 では 274 行、8.5.0 では 258 行でした。1つのオプションの説明は curl --help -i のように引けます。
curlのオプション一覧(よく使うものを用途別に)
curl --help all の 274 個のうち、よく使うものを用途別に並べました。短い形(-o)と長い形(--output)は同じ意味です。 「追加」の列は、curl のドキュメントに書かれた、そのオプションが入った版です。
リクエストを組み立てる
| 短い形 | 長い形 | 意味 | 例 | 追加 |
|---|---|---|---|---|
-X |
--request |
メソッドを指定 | -X PUT |
6.0 |
-H |
--header |
リクエストヘッダーを付ける | -H 'Accept: application/json' |
5.0 |
-d |
--data |
本文を送る(POST になる) | -d 'name=yamada' |
4.0 |
| なし | --data-raw |
@ をファイル指定と見なさずに送る |
--data-raw '@home' |
7.43.0 |
| なし | --data-binary |
改行などを変えずにそのまま送る | --data-binary @a.bin |
7.2 |
| なし | --data-urlencode |
URL エンコードして送る | --data-urlencode 'q=東京 駅' |
7.18.0 |
| なし | --json |
JSON を POST(ヘッダー2つを自動で付ける) | --json '{"a":1}' |
7.82.0 |
-F |
--form |
multipart/form-data で送る | -F 'file=@photo.jpg' |
5.0 |
-G |
--get |
-d の内容を URL のクエリにして GET |
-G -d 'page=2' |
7.8.1 |
| なし | --url-query |
URL にクエリを足す | --url-query 'q=東京' |
7.87.0 |
-T |
--upload-file |
ファイルを PUT でアップロード | -T data.csv |
4.0 |
-A |
--user-agent |
User-Agent を変える | -A 'MyApp/1.0' |
4.5.1 |
-e |
--referer |
Referer を付ける | -e 'https://example.com/' |
4.0 |
| なし | --compressed |
圧縮して受け取り、展開して出す | --compressed |
7.10 |
-r |
--range |
範囲を指定して一部だけ取る | -r 0-99 |
4.0 |
表示・出力
| 短い形 | 長い形 | 意味 | 例 | 追加 |
|---|---|---|---|---|
-i |
--show-headers |
レスポンスヘッダーも出す(旧名 --include) |
curl -i URL |
4.8 |
-I |
--head |
HEAD を送り、ヘッダーだけ出す | curl -I URL |
4.0 |
-v |
--verbose |
送受信の詳細を出す | curl -v URL |
4.0 |
| なし | --trace-ascii |
送受信の全データを記録 | --trace-ascii log.txt |
7.9.7 |
-s |
--silent |
進捗とエラー表示を消す | curl -s URL |
4.0 |
-S |
--show-error |
-s でもエラーは出す |
curl -sS URL |
5.9 |
| なし | --no-progress-meter |
進捗表示だけ消す | --no-progress-meter |
7.67.0 |
-o |
--output |
ファイルに保存 | -o result.json |
4.0 |
-O |
--remote-name |
URL のファイル名で保存 | -O |
4.0 |
-J |
--remote-header-name |
サーバーが示すファイル名で保存 | -OJ |
7.20.0 |
| なし | --output-dir |
保存先のディレクトリ | --output-dir dl |
7.73.0 |
| なし | --create-dirs |
保存先のディレクトリを作る | -o a/b/c.txt --create-dirs |
7.10.3 |
-D |
--dump-header |
受け取ったヘッダーをファイルへ | -D headers.txt |
5.7 |
-w |
--write-out |
終了後に情報を出す | -w '%{http_code}' |
6.5 |
| なし | --out-null |
本文を捨てる(-o /dev/null の代わり) |
--out-null |
8.16.0 |
-# |
--progress-bar |
進捗を棒グラフで出す | -# |
5.10 |
リダイレクト・ダウンロード
| 短い形 | 長い形 | 意味 | 例 | 追加 |
|---|---|---|---|---|
-L |
--location |
リダイレクトをたどる | curl -L URL |
4.9 |
| なし | --follow |
仕様どおりにメソッドを変えてたどる | --follow -X POST |
8.16.0 |
| なし | --max-redirs |
たどる回数の上限(既定 50) | --max-redirs 5 |
7.5 |
-C |
--continue-at |
途中から再開(- で自動) |
-C - |
4.8 |
| なし | --no-clobber |
同名ファイルを上書きしない | --no-clobber -O |
7.83.0 |
| なし | --skip-existing |
ファイルがあればダウンロードしない | --skip-existing -O |
8.10.0 |
| なし | --limit-rate |
速度を制限する | --limit-rate 1M |
7.10 |
| なし | --etag-save |
ETag を保存する | --etag-save etag.txt |
7.68.0 |
| なし | --etag-compare |
保存した ETag と比べて取得 | --etag-compare etag.txt |
7.68.0 |
認証・Cookie
| 短い形 | 長い形 | 意味 | 例 | 追加 |
|---|---|---|---|---|
-u |
--user |
ユーザー名とパスワード(Basic 認証) | -u user:pass |
4.0 |
| なし | --oauth2-bearer |
Bearer トークンを付ける | --oauth2-bearer TOKEN |
7.33.0 |
-b |
--cookie |
Cookie を送る(文字列かファイル) | -b cookies.txt |
4.9 |
-c |
--cookie-jar |
受け取った Cookie を保存 | -c cookies.txt |
7.9 |
| なし | --location-trusted |
リダイレクト先の別ホストにも認証情報を送る | --location-trusted |
7.10.4 |
失敗の扱い・タイムアウト・再試行
| 短い形 | 長い形 | 意味 | 例 | 追加 |
|---|---|---|---|---|
-f |
--fail |
400 以上を失敗(終了コード 22)にし、本文を出さない | -f |
4.0 |
| なし | --fail-with-body |
400 以上を失敗にし、本文は出す | --fail-with-body |
7.76.0 |
-m |
--max-time |
全体の制限時間(秒) | -m 30 |
4.0 |
| なし | --connect-timeout |
接続までの制限時間(秒) | --connect-timeout 5 |
7.7 |
| なし | --retry |
一時的なエラーで再試行する回数 | --retry 3 |
7.12.3 |
| なし | --retry-delay |
再試行の間隔(秒) | --retry-delay 2 |
7.12.3 |
| なし | --retry-max-time |
再試行を続ける上限時間(秒) | --retry-max-time 60 |
7.12.3 |
| なし | --retry-connrefused |
接続拒否でも再試行する | --retry-connrefused |
7.52.0 |
| なし | --retry-all-errors |
すべてのエラーで再試行する | --retry-all-errors |
7.71.0 |
TLS・証明書・接続先
| 短い形 | 長い形 | 意味 | 例 | 追加 |
|---|---|---|---|---|
-k |
--insecure |
証明書の検証を省く | -k |
7.10 |
| なし | --cacert |
信頼する CA 証明書を指定 | --cacert ca.pem |
7.5 |
| なし | --ca-native |
OS の証明書ストアを使う | --ca-native |
8.2.0 |
| なし | --http1.1 |
HTTP/1.1 を使う | --http1.1 |
7.33.0 |
| なし | --http2 |
HTTP/2 を使う | --http2 |
7.33.0 |
| なし | --http3 |
HTTP/3 を試す(つながらなければ HTTP/2 などへ) | --http3 |
7.66.0 |
| なし | --http3-only |
HTTP/3 だけを使う | --http3-only |
7.88.0 |
-x |
--proxy |
プロキシを使う | -x http://proxy:8080 |
4.0 |
| なし | --noproxy |
プロキシを使わないホスト | --noproxy localhost |
7.19.4 |
| なし | --resolve |
名前解決の結果を指定 | --resolve host:443:10.0.0.5 |
7.21.3 |
| なし | --connect-to |
別のホスト・ポートへ接続 | --connect-to host:443:stg:8443 |
7.49.0 |
-4 / -6 |
--ipv4 / --ipv6 |
IPv4・IPv6 だけを使う | -4 |
7.10.8 |
並列・変数・設定ファイル
| 短い形 | 長い形 | 意味 | 例 | 追加 |
|---|---|---|---|---|
-Z |
--parallel |
複数の URL を並列に転送 | -Z URL1 URL2 |
7.66.0 |
| なし | --parallel-immediate |
多重化を待たずに接続を増やす | -Z --parallel-immediate |
7.68.0 |
| なし | --variable |
変数を定義(環境変数も取り込める) | --variable %API_TOKEN |
8.3.0 |
| なし | --expand-(オプション名) |
オプションの中で {{変数}} を展開 |
--expand-header |
8.3.0 |
-K |
--config |
オプションをファイルから読む | -K api.curlrc |
4.10 |
-V |
--version |
版と機能を表示 | -V |
4.0 |
-h |
--help |
ヘルプ(all で全部) |
--help all |
4.0 |
curl -i・-I・-v の違い(ヘッダーを見る)
-i・-I・-v は、どれもヘッダーを見るためのオプションですが、出るものが違います。
| オプション | 送るメソッド | 出るもの |
|---|---|---|
-i(--show-headers) |
そのまま(GET など) | レスポンスヘッダー+本文 |
-I(--head) |
HEAD | レスポンスヘッダーだけ |
-v(--verbose) |
そのまま | 接続・TLS・リクエストヘッダー・レスポンスヘッダー(* > < 付き)+本文 |
curl -i は「本文の前にレスポンスヘッダーも出す」という意味です。 8.10.0 で長い名前が --include から --show-headers に変わりました。以前の名前も使えます。
$ curl -i http://localhost:47180/status/404
HTTP/1.1 404 Not Found
Server: demo/1.0
Date: Tue, 13 Oct 2026 16:17:21 GMT
Content-Type: application/json
Content-Length: 38
{"status": 404, "error": "demo error"}
-I は HEAD リクエストなので、本文は返りません。GET と HEAD で動きが違うサーバーもあるため、GET のヘッダーを見たいときは -i か、本文を捨てて -D - でヘッダーだけ出す形が使えます。
$ curl -s -D - -o /dev/null http://localhost:47180/echo
HTTP/1.1 200 OK
Server: demo/1.0
Date: Tue, 13 Oct 2026 16:21:27 GMT
Content-Type: application/json
Content-Length: 104
-v は、名前解決・接続・TLS の手順まで出します。* は curl からの説明、> は送った内容、< は受け取った内容です(一部省略)。
$ curl -v --cacert ca.pem https://localhost:47443/echo -o /dev/null
* Host localhost:47443 was resolved.
* Trying 127.0.0.1:47443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / RSASSA-PSS
* ALPN: server accepted h2
* Server certificate:
* subject: CN=localhost
* issuer: CN=RJC Demo CA
* subjectAltName: "localhost" matches cert's "localhost"
* SSL certificate verified via OpenSSL.
* using HTTP/2
> GET /echo HTTP/2
> Host: localhost:47443
> User-Agent: curl/8.22.0
> Accept: */*
>
< HTTP/2 200
< server: nginx/1.24.0 (Ubuntu)
< content-type: application/json
< content-length: 128
HTTPS のサーバーに対しては、何も指定しなくても HTTP/2 が使われました(ALPN: server accepted h2)。送った本文まで見たいときは --trace-ascii - を使います。
$ curl -s --trace-ascii - http://localhost:47180/echo -d x=1
=> Send header, 152 bytes (0x98)
0000: POST /echo HTTP/1.1
0015: Host: localhost:47180
002c: User-Agent: curl/8.22.0
0045: Accept: */*
0052: Content-Length: 3
0065: Content-Type: application/x-www-form-urlencoded
0096:
=> Send data, 3 bytes (0x3)
0000: x=1
GET・POST・JSON・PUT・DELETE(APIの確認)
テスト用サーバーの /echo は、受け取ったメソッド・ヘッダー・本文をそのまま JSON で返します。curl が実際に何を送ったかが分かります。
GET
$ curl http://localhost:47180/echo
{"method": "GET", "path": "/echo", "headers": {"user-agent": "curl/8.22.0", "accept": "*/*"}, "body": ""}
POST(フォーム形式)
$ curl -d 'name=yamada&age=30' http://localhost:47180/echo
{"method": "POST", ..., "content-type": "application/x-www-form-urlencoded"}, "body": "name=yamada&age=30"}
-d を付けると、自動で POST になり、Content-Type は application/x-www-form-urlencoded になりました。 -X POST は付けなくても POST です。
JSON を送る(--json)
$ curl --json '{"name":"山田"}' http://localhost:47180/echo
{"method": "POST", "path": "/echo", "headers": {"user-agent": "curl/8.22.0", "content-type": "application/json", "accept": "application/json", "content-length": "17"}, "body": "{\"name\":\"山田\"}"}
--json(7.82.0 以降)は、ドキュメントでは次の3つをまとめたものです。
--data-binary '...' -H 'Content-Type: application/json' -H 'Accept: application/json'
中身が正しい JSON かどうかは確かめません。 7.82.0 より前の curl では、上の3つを自分で書きます。長い JSON はファイルに書いて @ で読むと、引用符で迷いません。
$ curl -s --json @user.json http://localhost:47180/echo
{"method": "POST", ..., "body": "{\"name\":\"山田\",\"tags\":[\"a\",\"b\"]}"}
レスポンスの JSON は jq に渡すと整形・抽出できます。関連記事「jqの使い方|逆引き40例と実務レシピを全部実行結果つきで解説」で扱っています。
$ curl -s http://localhost:47180/api/users/1 | jq -r '.method, .path'
GET
/api/users/1
PUT・DELETE
$ curl -X PUT --json '{"name":"佐藤"}' http://localhost:47180/api/users/1
{"method": "PUT", "path": "/api/users/1", ..., "body": "{\"name\":\"佐藤\"}"}
$ curl -X DELETE http://localhost:47180/api/users/1
{"method": "DELETE", "path": "/api/users/1", ...}
--json と -X PUT を組み合わせると、JSON の PUT になりました。メソッドの違いは、関連記事「HTTPメソッド一覧|GET・POST・PUT・PATCHの違い早見表」で扱っています。
ヘッダー・トークンを付ける
$ curl -H 'Authorization: Bearer TOKEN123' -H 'X-Request-Id: 42' http://localhost:47180/echo
{"method": "GET", ..., "authorization": "Bearer TOKEN123", "x-request-id": "42"}, "body": ""}
-H 'Accept:' のように値を空にすると、curl が自動で付けるヘッダーを消せます。-H 'User-Agent;'(コロンではなくセミコロン)は、値が空のヘッダーを送ります。
クエリ文字列を付ける(日本語・空白)
$ curl -G --data-urlencode 'q=東京 駅' -d page=2 http://localhost:47180/echo
{"method": "GET", "path": "/echo?q=%E6%9D%B1%E4%BA%AC+%E9%A7%85&page=2", ...}
$ curl --url-query 'q=東京 駅' http://localhost:47180/echo
{"method": "GET", "path": "/echo?q=%E6%9D%B1%E4%BA%AC+%E9%A7%85", ...}
URL に空白をそのまま書くと、curl: (3) URL rejected: Malformed input to a URL function になりました。日本語や空白は --data-urlencode か --url-query でエンコードします。
ステータスコード・応答時間を表示(-w の変数一覧)
-w(--write-out)は、転送が終わった後に、指定した情報を出します。監視やデプロイ後の確認スクリプトで、いちばんよく使う組み合わせはこれです。
$ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:47180/echo
200
-s:進捗表示を消す-o /dev/null:本文を捨てる(Windows では-o NUL。8.16.0 以降は--out-nullでも同じ)-w '%{http_code}\n':ステータスコードを出す
ステータスコードごとの意味は、関連記事「HTTPステータスコード 一覧|全コードの原因と対処・curl実例つき」で扱っています。
よく使う変数
| 変数 | 意味 | 実行した値の例 |
|---|---|---|
%{http_code} |
ステータスコード(接続できないと 000) | 404 |
%{http_version} |
実際に使った HTTP の版 | 2 |
%{remote_ip} / %{remote_port} |
接続先の IP とポート | 127.0.0.1:47443 |
%{size_download} |
受け取った本文のバイト数 | 128 |
%{content_type} |
Content-Type | application/json |
%{redirect_url} |
リダイレクト先(-L なしのとき) |
http://localhost:47180/echo |
%{num_redirects} |
たどったリダイレクトの回数 | 3 |
%{url_effective} |
最後にアクセスした URL | http://localhost:47180/echo |
%{num_retries} |
再試行した回数(8.9.0) | 2 |
%{exitcode} / %{errormsg} |
終了コードとエラー文(7.75.0) | 7 / Failed to connect ... |
%{onerror} |
ここから後ろは失敗したときだけ出す(7.75.0) | なし |
%header{名前} |
レスポンスヘッダーの値(7.84.0) | demo/1.0 |
%{json} |
すべての変数を JSON で出す(7.70.0) | 下の例 |
%output{ファイル} |
ここから後ろをファイルに書く(8.3.0) | %output{>>stats.log} で追記 |
%time{書式} |
現在の UTC 時刻(8.16.0) | 2026-10-13 16:17:44 |
応答時間を区間ごとに測る
$ curl -s -o /dev/null --cacert ca.pem \
-w 'DNS:%{time_namelookup} 接続:%{time_connect} TLS:%{time_appconnect} 最初の応答:%{time_starttransfer} 合計:%{time_total}\n' \
'https://localhost:47443/slow?sec=0.3'
DNS:0.000058 接続:0.000131 TLS:0.003469 最初の応答:0.304884 合計:0.304973
0.3 秒待ってから返すように作った URL では、最初の応答 の値が 0.3 秒増えました。接続・TLS までが短く、最初の応答までが長ければ、サーバー側の処理に時間がかかっています。
| 変数 | 開始から、いつまでの秒数か |
|---|---|
time_namelookup |
名前解決(DNS)が終わるまで |
time_connect |
TCP 接続が終わるまで |
time_appconnect |
TLS のハンドシェイクが終わるまで |
time_pretransfer |
転送を始める直前まで |
time_starttransfer |
最初の1バイトを受け取るまで |
time_total |
全体 |
失敗したときだけエラーを出す(%{onerror})
$ curl -s -o /dev/null -w '%{http_code}\n%{onerror}エラー:%{exitcode} %{errormsg}\n' http://localhost:47180/echo
200
$ curl -s -o /dev/null -w '%{http_code}\n%{onerror}エラー:%{exitcode} %{errormsg}\n' http://localhost:1/
000
エラー:7 Failed to connect to localhost:1 after 0 ms: Could not connect to server
ヘッダーの値・全項目を JSON で出す
$ curl -s -o /dev/null -w '%header{content-type} / %header{server}\n' http://localhost:47180/echo
application/json / demo/1.0
$ curl -s -o /dev/null -w '%{json}' http://localhost:47180/status/404 | jq '{http_code, http_version, num_connects, size_download, time_total}'
%{json} は、8.22.0 では 69 項目、8.5.0 では 63 項目の JSON になりました。上の例で抜き出した部分は次のとおりです。
{
"http_code": 404,
"http_version": "1.1",
"num_connects": 1,
"size_download": 38,
"time_total": 0.000900
}
最新のcurlで増えたオプション(--json・--variable・--follow など)
curl は、通常8週間ごとに新しい版が出ます(curl のリリース手順書)。ここ数年で入った、API の確認やスクリプトで役に立つ機能をまとめました。
| 版 | 追加された主なもの |
|---|---|
| 7.82.0 | --json |
| 7.83.0 | --no-clobber、-w '%{header_json}' |
| 7.84.0 | -w '%header{名前}' |
| 7.87.0 | --url-query |
| 8.2.0 | --ca-native |
| 8.3.0 | --variable と --expand-*、-w '%output{}' |
| 8.9.0 | -w '%{num_retries}' |
| 8.10.0 | --skip-existing、-i の長い名前が --show-headers に |
| 8.16.0 | --follow、--out-null、-w '%time{}' |
| 8.22.0 | HTTP Message Signatures(RFC 9421)への対応 |
Ubuntu 24.04 の curl 8.5.0 では、--out-null は option --out-null: is unknown になりました。 使う前に curl -V で版を確かめます。
--variable:環境変数を安全に埋め込む(8.3.0)
--variable %名前 で環境変数を取り込み、--expand- を付けたオプションの中で {{名前}} として使えます。
$ export API_TOKEN=secret-123
$ curl -s --variable %API_TOKEN --expand-header 'Authorization: Bearer {{API_TOKEN}}' http://localhost:47180/echo
{"method": "GET", ..., "authorization": "Bearer secret-123"}, "body": ""}
環境変数が無いときは、エラーで止まりました。%名前=既定値 と書くと、無いときに既定値を使います。
$ curl -s --variable %NOPE http://localhost:47180/echo
curl: option --variable: variable expansion failure
$ curl -s --variable %ENVNAME=dev --expand-url 'http://localhost:47180/api/{{ENVNAME}}/health'
{"method": "GET", "path": "/api/dev/health", ...}
{{名前:url}} は URL エンコード、{{名前:json}} は JSON の文字列としてエスケープします。JSON に " を含む値を埋め込んでも、壊れませんでした。
$ curl -s --variable 'name=山田 太郎' --expand-url 'http://localhost:47180/echo?q={{name:url}}'
{"method": "GET", "path": "/echo?q=%E5%B1%B1%E7%94%B0%20%E5%A4%AA%E9%83%8E", ...}
$ curl -s --variable 'msg=He said "hi"' --expand-json '{"text":"{{msg:json}}"}' http://localhost:47180/echo
{"method": "POST", ..., "body": "{\"text\":\"He said \\\"hi\\\"\"}"}
--follow と -L の違い(8.16.0)
-L と -X POST を一緒に使うと、302 のリダイレクト先にも POST を送ります。このとき本文は送られず、「本文の無い POST」になりました。 --follow は、HTTP の仕様どおり 301・302・303 では GET に変え、307・308 では POST のまま本文も送ります。
| コマンド | 302 のとき、転送先が受け取ったもの | 307 のとき |
|---|---|---|
-L -d 'a=1' |
GET(本文なし) | POST(本文 a=1) |
-L -X POST -d 'a=1' |
POST(本文なし) | POST(本文 a=1) |
--follow -X POST -d 'a=1' |
GET(本文なし) | POST(本文 a=1) |
$ curl -s -L -X POST -d 'a=1' http://localhost:47180/redirect/1
{"method": "POST", "path": "/echo", "headers": {"user-agent": "curl/8.22.0", "accept": "*/*"}, "body": ""}
$ curl -s --follow -X POST -d 'a=1' http://localhost:47180/redirect/1
{"method": "GET", "path": "/echo", "headers": {"user-agent": "curl/8.22.0", "accept": "*/*"}, "body": ""}
-L はドキュメントのとおり、-u などの認証情報を最初のホストにしか送りません。リダイレクト先の別ホストにも送るのが --location-trusted です。
--parallel:複数の URL を同時に取る
1秒かかる URL を3つ取ったときの時間です。
| コマンド | 全体の時間 |
|---|---|
| オプションなし(順番に取る) | 3.094 秒 |
-Z |
2.048 秒 |
-Z --parallel-immediate |
1.006 秒 |
$ curl -s -Z --parallel-immediate -w '%{http_code} %{time_total}\n' \
-o /dev/null -o /dev/null -o /dev/null \
'http://localhost:47180/slow?sec=1' 'http://localhost:47180/slow?sec=1' 'http://localhost:47180/slow?sec=1'
200 1.001463
200 1.001536
200 1.001529
-Z だけでは、同じホストへの2本目以降が待たされました。ドキュメントによると、-Z は HTTP/2 の多重化(1本の接続で複数を送る)に乗せられるかを待つためで、--parallel-immediate は待たずに接続を増やします。
HTTP/3(--http3)
--http3 は HTTP/3 を試し、つながらなければ HTTP/2・HTTP/1.1 に切り替えます。--http3-only は切り替えません。どちらも curl -V の Features に HTTP3 がある curl でだけ使えます。ドキュメントでは、HTTP/3 は HTTPS の URL だけで、プロキシ経由では使えません。
スクリプトやCIでの使い方:--fail・タイムアウト・再試行
404 や 500 でも「成功」になる
curl は、404 や 500 が返っても、通信が終わっていれば終了コード 0(成功)で終わります。 スクリプトや CI では、エラーに気づけません。
$ curl -s http://localhost:47180/status/404; echo " 終了コード=$?"
{"status": 404, "error": "demo error"} 終了コード=0
$ curl -s -f http://localhost:47180/status/404; echo "終了コード=$?"
終了コード=22
$ curl -sS -f http://localhost:47180/status/404; echo "終了コード=$?"
curl: (22) The requested URL returned error: 404
終了コード=22
$ curl -sS --fail-with-body http://localhost:47180/status/404; echo " 終了コード=$?"
curl: (22) The requested URL returned error: 404
{"status": 404, "error": "demo error"} 終了コード=22
| 書き方 | 本文 | エラー文 | 終了コード |
|---|---|---|---|
| オプションなし | 出る | 出ない | 0 |
-s -f |
出ない | 出ない | 22 |
-sS -f |
出ない | 出る | 22 |
-sS --fail-with-body |
出る | 出る | 22 |
スクリプトでは -sS --fail-with-body が扱いやすい組み合わせです。 進捗は消え、エラー文とサーバーが返したエラーの本文は残り、失敗は失敗として終わります。$? の扱い方は、関連記事「シェルスクリプトの終了ステータス $?とexitコード一覧・判定方法」で扱っています。
タイムアウト
$ curl -sS --max-time 2 http://localhost:47181/
curl: (28) Operation timed out after 2001 milliseconds with 0 bytes received
接続は受け付けるが何も返さないサーバーに向けると、--max-time 2 で 2 秒後に終わりました。タイムアウトを指定しないと、このような相手には待ち続けます。 --connect-timeout は接続までの上限、--max-time は全体の上限です。
再試行(--retry)
ドキュメントでは、--retry が再試行するのは「一時的なエラー」だけです。タイムアウト、FTP の 4xx、HTTP の 408・429・500・502・503・504・522・524 が対象で、待ち時間は1秒から倍々に増え、Retry-After ヘッダーがあれば従います。
3回に1回だけ 200 を返し、それ以外は 503 を返す URL で試しました。
$ curl --no-progress-meter --retry 3 -o /dev/null -w '%{http_code} retries=%{num_retries}\n' http://localhost:47180/flaky
Warning: Problem : HTTP error. Retrying in 1 second. 3 retries left.
Warning: Problem : HTTP error. Retrying in 1 second. 2 retries left.
200 retries=2
| 状況 | --retry 2 だけ |
追加するオプション |
|---|---|---|
| 503 が返る | 再試行した | なし |
| 接続拒否(終了コード 7) | 再試行しなかった(retries=0) | --retry-connrefused で 2 回再試行 |
| 404 が返る | 再試行しなかった(終了コード 0) | --retry-all-errors -f で 2 回再試行 |
--retry-all-errors は、ドキュメントで「大ハンマー」と書かれ、データの二重送信が起こりうるため、既定の設定には入れないよう注意されています。POST を送る API には向きません。
設定ファイル(-K)でオプションをまとめる
$ cat api.curlrc
silent
show-error
fail-with-body
max-time = 10
header = "Accept: application/json"
$ curl -K api.curlrc http://localhost:47180/status/500; echo " exit=$?"
curl: (22) The requested URL returned error: 500
{"status": 500, "error": "demo error"} exit=22
設定ファイルでは、長い形のオプション名から -- を取って書きます。
ファイルのダウンロードとアップロード
-O・-o・-LO(curl -lo の意味)
$ curl -s -O http://localhost:47180/files/report.txt && ls -l report.txt
-rw-r--r-- 1 root root 12000 Oct 14 01:18 report.txt
$ curl -s -o out/latest.txt --create-dirs http://localhost:47180/files/report.txt
curl -LO URL は -L(リダイレクトをたどる)と -O(URL のファイル名で保存)を並べた形です。 GitHub のリリースのように、リダイレクトの先にファイルがある URL でよく使います。小文字の -l は FTP の --list-only で、意味が違います。
| 書き方 | 保存される名前 |
|---|---|
-o 名前 |
指定した名前 |
-O |
URL の最後の部分(report.txt) |
-OJ |
サーバーの Content-Disposition の名前(report-2026.txt) |
-O --no-clobber |
同名があれば report.txt.1 |
$ curl -s -OJ http://localhost:47180/download -w '%{filename_effective}\n'
report-2026.txt
途中から再開する(-C -)
$ head -c 5000 report.txt > partial.txt
$ curl -s -C - -o partial.txt http://localhost:47180/files/report.txt -w '%{http_code} %{size_download}\n'
206 7000
5000 バイトまであるファイルに対して、残りの 7000 バイトだけを受け取り(206 Partial Content)、12000 バイトのファイルになりました。
連番・まとめて取る(URL のグロブ)
$ curl -s -o 'page_#1.json' 'http://localhost:47180/api/users/[1-3]' && ls page_*
page_1.json
page_2.json
page_3.json
[1-3] は連番、{users,orders} は列挙です。#1 は1つ目の [] か {} に当てはまった値に置き換わります。
圧縮して受け取る(--compressed)
| コマンド | 受け取ったバイト数(%{size_download}) |
画面に出たバイト数 |
|---|---|---|
curl URL |
6000 | 6000 |
curl --compressed URL |
60 | 6000 |
アップロード(-F・-T)
$ curl -s -F 'file=@photo.jpg' -F 'title=写真' http://localhost:47180/upload
{"content-type": "multipart/form-data; boundary=------------------------ZNHUtSHZUZodjvpaoegaeH", "bytes": 312}
-F は、HTML のフォームからファイルを送るときと同じ multipart/form-data で送ります。-T ファイル は本文にファイルをそのまま入れて PUT します。
Cookie・Basic認証
$ curl -s -c cookies.txt http://localhost:47180/login
{"login": "ok"}
$ curl -s -b cookies.txt http://localhost:47180/mypage
{"user": "yamada"}
$ grep sid cookies.txt
#HttpOnly_localhost FALSE / FALSE 0 sid abc123
$ curl -s -u user:pass http://localhost:47180/basic
{"auth": "ok"}
$ curl -s -u user:wrong -w ' %{http_code}\n' http://localhost:47180/basic
{"error": "unauthorized"} 401
-u user のようにパスワードを省くと、curl が入力を求めます。コマンドにパスワードを直接書くと、シェルの履歴に残ります。
curlの終了コード一覧
curl は、失敗すると 0 以外の終了コードで終わり、エラー文の先頭に curl: (番号) を付けます。ドキュメントの一覧から、よく出るものを抜き出しました。「出た例」は、この記事で実際に出たエラー文です。
| 番号 | 意味 | 出た例・よくある原因 |
|---|---|---|
| 0 | 成功 | 404・500 でも -f が無ければ 0 |
| 1 | 対応していないプロトコル | Protocol "htps" not supported(つづり間違い) |
| 2 | 初期化の失敗 | オプションの書き間違い、--cacert のファイルが無い |
| 3 | URL の形式が正しくない | URL に空白を含めた |
| 5 | プロキシの名前解決に失敗 | -x や HTTPS_PROXY のホスト名の間違い |
| 6 | ホストの名前解決に失敗 | Could not resolve host: no-such-host.invalid |
| 7 | 接続に失敗 | Failed to connect to localhost:1 ... |
| 16 | HTTP/2 のフレームの問題 | 詳しい原因はエラー文に出る |
| 18 | ファイルの一部しか転送されなかった | 転送の途中で接続が切れた |
| 22 | HTTP のエラー(400 以上) | -f か --fail-with-body を付けたとき |
| 23 | 書き込みエラー | 保存先のディレクトリが無い |
| 26 | 読み込みエラー | -d @ファイル のファイルが無い |
| 28 | タイムアウト | --max-time を過ぎた |
| 35 | TLS の接続エラー | HTTP のポートに https で接続、TLS の版が合わない |
| 47 | リダイレクトが多すぎる | --max-redirs を超えた |
| 52 | サーバーが何も返さなかった | Empty reply from server |
| 55 / 56 | 送信 / 受信の失敗 | 通信の途中で切断された |
| 58 | 手元の証明書の問題 | クライアント証明書(--cert)の指定 |
| 60 | サーバー証明書を検証できない | 自己署名・社内 CA・期限切れ・ホスト名の不一致 |
| 77 | CA 証明書の読み込みに失敗 | CA ファイルのパスや権限 |
| 92 | HTTP/2 のストリームのエラー | 詳しい原因はエラー文に出る |
| 95 / 96 | HTTP/3 / QUIC のエラー | --http3 使用時 |
全一覧(0〜100)は curl の man ページの「EXIT CODES」にあります。
よくあるエラーと直し方
エラー文は curl の版で少し変わります。8.22.0 と、Ubuntu 24.04 の 8.5.0 で同じ操作をしたときの文を並べます。
| 番号 | 8.22.0 のエラー文 | 8.5.0 のエラー文 |
|---|---|---|
| (7) | Failed to connect to localhost:1 after 0 ms: Could not connect to server |
Failed to connect to localhost port 1 after 0 ms: Couldn't connect to server |
| (35) | TLS connect error: error:0A00010B:SSL routines::wrong version number |
OpenSSL/3.0.13: error:0A00010B:SSL routines::wrong version number |
| (60) | SSL certificate OpenSSL verify result: unable to get local issuer certificate (20) |
SSL certificate problem: unable to get local issuer certificate |
curl: (6) Could not resolve host
$ curl -sS http://no-such-host.invalid/
curl: (6) Could not resolve host: no-such-host.invalid
ホスト名から IP アドレスを引けていません。URL のつづり、DNS の設定、社内ネットワークならプロキシの要否を確かめます。DNS を通さずに試すには、--resolve ホスト:ポート:IP で IP を指定します。
$ curl -s --resolve api.example.test:47180:127.0.0.1 http://api.example.test:47180/echo -w '\n%{remote_ip}\n'
{"method": "GET", "path": "/echo", ...}
127.0.0.1
curl: (7) Failed to connect
$ curl -sS http://localhost:1/
curl: (7) Failed to connect to localhost:1 after 0 ms: Could not connect to server
名前解決はできたが、そのポートにつながりません。サーバーが起動していない、ポート番号の間違い、ファイアウォールが主な原因です。ポートの待ち受けは ss -ltn で確かめられます。関連記事「Linuxネットワークコマンド一覧|ip/ss/ncで障害切り分け」で扱っています。
curl: (28) Operation timed out
$ curl -sS --max-time 2 http://localhost:47181/
curl: (28) Operation timed out after 2001 milliseconds with 0 bytes received
with 0 bytes received は、接続はできたが応答が1バイトも来なかったことを示します。-w の time_connect と time_starttransfer を見ると、接続で止まったのか、サーバーの処理で止まったのかを分けられます。
curl: (35) TLS connect error
$ curl -sS https://localhost:47180/
curl: (35) TLS connect error: error:0A00010B:SSL routines::wrong version number
$ curl -sS --tls-max 1.1 --cacert ca.pem https://localhost:47443/echo
curl: (35) TLS connect error: error:0A0000BF:SSL routines::no protocols available
1つ目は、HTTP で待ち受けているポートに https:// で接続したときのエラーです。URL の http と https、ポート番号を見直します。2つ目は、TLS の版が合わないときのエラーです。プロキシが通信を中継している環境でも (35) が出ることがあり、-v で接続先を確かめます。
curl: (60) SSL certificate problem
自作の CA で発行した証明書、自己署名の証明書、期限切れの証明書、IP アドレスでの接続で試しました。
| 状況 | 8.22.0 のエラー文の要点 |
|---|---|
| 信頼していない CA が発行 | unable to get local issuer certificate (20) |
| 自己署名の証明書 | self-signed certificate (18) |
| 期限切れ | certificate has expired (10) |
| 証明書の名前と URL が違う | no alternative certificate subject name matches target IPv4 address '127.0.0.1' |
$ curl -sS https://localhost:47443/echo
curl: (60) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the webpage mentioned above.
直し方は、信頼する CA 証明書を --cacert で渡すことです。 渡すと 200 が返り、検証の結果(ssl_verify_result)は 0 になりました。
$ curl -sS --cacert ca.pem -o /dev/null -w '%{http_code} ssl_verify_result=%{ssl_verify_result}\n' https://localhost:47443/echo
200 ssl_verify_result=0
$ curl -sS -k -o /dev/null -w '%{http_code} ssl_verify_result=%{ssl_verify_result}\n' https://localhost:47444/echo
200 ssl_verify_result=18
-k(--insecure)でも 200 は返りますが、ssl_verify_result=18(自己署名)のまま通っています。-k は相手が本物のサーバーかを確かめないので、通信を途中で盗み見る攻撃を防げません。 開発中に一時的に使っても、本番のスクリプトや CI には残さず、社内 CA なら --cacert、OS に登録済みの CA なら --ca-native(8.2.0 以降)を使います。証明書の中身の確かめ方は、関連記事「opensslコマンドの使い方|目的別一覧と実行結果・エラー対処【3系】」で扱っています。
その他のエラー
| エラー文 | 原因 | 直し方 |
|---|---|---|
curl: (3) URL rejected: Malformed input to a URL function |
URL に空白などが入っている | --url-query か --data-urlencode -G を使う |
curl: (52) Empty reply from server |
サーバーが何も返さず接続を切った | サーバーのログ、HTTP と HTTPS の取り違えを確かめる |
curl: (47) Maximum (2) redirects followed |
リダイレクトの回数が上限を超えた | リダイレクトのループを -w '%{redirect_url}' で追う |
curl: (23) client returned ERROR on write of 105 bytes |
保存先のディレクトリが無い | --create-dirs を付ける |
curl: Failed to open nofile.json(終了コード 26) |
-d @ファイル のファイルが無い |
パスを確かめる |
Windowsでcurlコマンドを使う(curl.exe と PowerShell の違い)
curl 公式の説明では、Windows 10・11 には標準で curl が入っています。Microsoft のドキュメントでは、Linux や macOS と同じオプション・同じ動作で使えると書かれています。つまずくのは、Windows PowerShell 5.1 で curl が別のコマンドになることです。
| シェル | curl と打ったときに動くもの |
|---|---|
| コマンドプロンプト(cmd) | curl.exe |
| Windows PowerShell 5.1 | Invoke-WebRequest の別名(エイリアス) |
| PowerShell 7 以降 | curl.exe(別名は iwr だけ) |
Windows PowerShell 5.1 の Invoke-WebRequest には、iwr・curl・wget の3つの別名があります。PowerShell 7 では iwr だけです。5.1 では curl.exe と拡張子まで書くと curl 本体が動きます。Remove-Item Alias:curl で別名を消す方法もあります。
curl.exe -sS --fail-with-body https://api.example.com/users
PowerShell 7.6.4 で Get-Command curl を実行すると、CommandType は Application(外部のプログラム)でした。
PowerShell で JSON の引用符が消える
PowerShell 7.3 で、外部コマンドへの引数の渡し方が変わりました($PSNativeCommandArgumentPassing)。ドキュメントでは、Legacy が以前からの渡し方です。PowerShell 7.6.4 で、この設定を切り替えて同じコマンドを送り、サーバーが受け取った本文を比べました。
curl -s --json '{"name":"yamada"}' "http://localhost:47180/echo"
| 設定 | サーバーが受け取った本文 |
|---|---|
Standard(7.3 以降の既定) |
{"name":"yamada"} |
Legacy(以前からの渡し方) |
{name:yamada}(" が消えた) |
Legacy で '{\"name\":\"yamada\"}' と書いた |
{"name":"yamada"} |
Windows PowerShell 5.1 と同じ渡し方では、JSON の " が消え、壊れた JSON が送られました。 どの環境でも同じ結果になるのは、JSON をファイルに書いて --json "@user.json" で送る方法です。
コマンドプロンプト(cmd)での引用符
cmd では、シングルクォートは引用符として扱われません。Microsoft の引数の解析規則では、" で囲んだ中の \" が " になります。
curl -H "Content-Type: application/json" -d "{\"name\":\"yamada\"}" https://api.example.com/users
- 行を折り返すときは、
\ではなく^を使う(PowerShell では`) - 本文を捨てるときは
-o /dev/nullではなく-o NUL(8.16.0 以降は--out-null) - バッチファイルの中では、
-w "%{http_code}"の%を%%と2つ重ねる(curl のドキュメントの注意)
Invoke-WebRequest・Invoke-RestMethod との対応
PowerShell の機能で同じことをするときの対応です。PowerShell 7.6.4 で動かしました。
| curl | PowerShell |
|---|---|
curl URL |
Invoke-WebRequest -Uri URL |
curl --json '{...}' URL |
Invoke-RestMethod -Method Post -Uri URL -ContentType 'application/json' -Body $json |
curl -H 'X: 1' URL |
Invoke-WebRequest -Uri URL -Headers @{X='1'} |
curl -o file URL |
Invoke-WebRequest -Uri URL -OutFile file |
| 404 でも終了コード 0 | 404 で例外(HttpResponseException)。-SkipHttpErrorCheck で例外にしない |
curl.exe の終了コードは、PowerShell では $LASTEXITCODE で取れます。curl -s -f で 404 を取ったとき、LASTEXITCODE=22 でした。PowerShell の他のコマンドは、関連記事「PowerShellコマンド一覧|用途別50選とbash対応表・実行例付き」で扱っています。
Windows 同梱の curl の注意
curl 公式の説明では、Windows 同梱の curl は TLS に Schannel を使い、HTTP/2・HTTP/3・brotli・zstd などが含まれていません。また、curl 公式の版より遅れて更新されます。新しい機能が要るときは、curl 公式サイトの Windows 版を使う方法があります。
wgetとcurlの違い
wget もファイルを取るコマンドですが、得意なことが違います。同じテスト用サーバーに向けて、GNU Wget 1.21.4 と curl 8.22.0 を動かしました。
| 項目 | curl | wget |
|---|---|---|
| 何もしないときの出力先 | 画面(標準出力) | ファイルに保存 |
| リダイレクト | -L を付けたときだけたどる |
既定でたどる |
| 再試行 | 既定では無し(--retry) |
既定で 20 回(ドキュメント) |
| 404 のときの終了コード | 0(-f で 22) |
8 |
| 接続できないときの終了コード | 7 | 4 |
| 証明書を検証できないとき | 60 | 5 |
| フォルダごと再帰的に取る | できない | -r でできる |
| メソッド・ヘッダーの指定 | 自由に組み立てられる | 一部(--method・--header など) |
| 対応プロトコル | HTTP・FTP・SFTP・SMTP など多数 | HTTP・HTTPS・FTP・FTPS |
$ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:47180/redirect/2
302
$ wget -q -O - http://localhost:47180/redirect/2
{"method": "GET", "path": "/echo", ...}
API を確かめる・送る中身を細かく決めるなら curl、サイトやディレクトリをまとめて取るなら wgetが向いています。wget の使い方は、関連記事「wgetコマンドの使い方|保存先・再帰・リトライとcurlの違い」で扱っています。
ブラウザの通信をcurlで再現する(Copy as cURL)
Chrome や Edge の開発者ツールでは、ブラウザが送った通信を curl のコマンドとしてコピーできます。
- 開発者ツールの「Network」タブを開く
- 対象のリクエストを右クリックする
- 「Copy」→「Copy as cURL」を選ぶ
Windows では「Copy as cURL (cmd)」と「Copy as cURL (bash)」が分かれていることがあり、引用符の書き方が違います。コピーしたコマンドには、Cookie やトークンなどログインの情報が入っています。 チャットや資料に貼るときは、その部分を伏せます。GUI で API を試す方法は、関連記事「Postmanの使い方|環境変数・テストスクリプト・コマンドでの実行」で扱っています。
よくある質問
Q. curlコマンドとは何ですか?
A. URL を指定して、HTTP・HTTPS・FTP などでデータを送受信するコマンドです。curl URL で GET を送り、返ってきた本文を画面に出します。API の動作確認やファイルのダウンロードに使われます。
Q. curl のオプション一覧を表示するには?
A. curl --help all で全オプションを表示します。curl 8.22.0 では 274 行でした。curl --help http のようにカテゴリを指定すると絞り込めます。
Q. curl -i とは何ですか?
A. レスポンスヘッダーを本文の前に出すオプションです。長い名前は --show-headers(8.10.0 より前は --include)です。大文字の -I は HEAD リクエストでヘッダーだけを出します。
Q. curl -LO(curl -lo)の意味は?
A. -L(リダイレクトをたどる)と -O(URL のファイル名で保存する)を並べた形です。小文字の -l は FTP の --list-only なので、ダウンロードには大文字の -LO を使います。
Q. Windows で curl コマンドは使えますか?
A. Windows 10・11 には curl.exe が入っています。Windows PowerShell 5.1 では curl が Invoke-WebRequest の別名なので、curl.exe と書きます。JSON は --json "@ファイル" で送ると引用符で困りません。
Q. wget と curl の違いは? A. wget は既定でファイルに保存し、リダイレクトをたどり、再帰的なダウンロードができます。curl は既定で画面に出し、メソッドやヘッダーを細かく指定でき、API の確認に向いています。
Q. -X POST は必要ですか?
A. -d・--json・-F を付けると POST になるので、-X POST は無くても POST です。-L と一緒に -X POST を書くと、302 の転送先にも本文の無い POST が送られました。
Q. レスポンスの JSON を見やすくしたい
A. curl -s URL | jq のように jq に渡します。-s を付けないと、出力をパイプに渡したときに進捗表示が画面に出ます。
Q. プロキシを経由したい
A. -x http://proxy.example.com:8080 で指定するか、環境変数 HTTPS_PROXY・HTTP_PROXY を設定します。プロキシを使わないホストは --noproxy か NO_PROXY で指定します。
まとめ
- curl は
curl [オプション] URLで使う。まずcurl -Vで版と Features を確かめる(最新は 8.22.0、Ubuntu 24.04 は 8.5.0) - オプションは
curl --help all(8.22.0 で 274 行)。よく使うものは本文の一覧表のとおり - JSON は
--json(7.82.0 以降)。長い JSON は@ファイルで送る - ステータスは
-s -o /dev/null -w '%{http_code}\n'、応答時間はtime_*、全部見るなら%{json} - 404・500 でも終了コードは 0。スクリプトでは
-sS --fail-with-body、--max-time、--retryを付ける - 新しい版では
--variable(環境変数の埋め込み)、--follow(仕様どおりのリダイレクト)、--out-nullが使える - エラーは番号で切り分ける:(6) 名前解決、(7) 接続、(28) タイムアウト、(35) TLS、(60) 証明書
-kに頼らず、--cacertか--ca-nativeで CA を指定する- Windows PowerShell 5.1 では
curl.exeと書き、JSON はファイルから送る - まとめて取る・再帰的に取るなら wget、API を確かめるなら curl
参考・出典
確認日はいずれも 2026年10月14日です。
- curl - Changes(変更履歴):https://curl.se/changes.html
- curl man page(オプションと EXIT CODES):https://curl.se/docs/manpage.html
- curl ソースコード(docs/cmdline-opts、curl-8_22_0 タグ):https://github.com/curl/curl
- curl - SSL CA Certificates:https://curl.se/docs/sslcerts.html
- curl - Microsoft's curl(Windows 同梱の curl):https://curl.se/windows/microsoft.html
- Microsoft Learn - curl on Windows:https://learn.microsoft.com/en-us/windows/curl/
- Microsoft Learn - Invoke-WebRequest(PowerShell 5.1):https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-5.1
- Microsoft Learn - Invoke-WebRequest(PowerShell 7.5):https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.5
- Microsoft Learn - about_Parsing($PSNativeCommandArgumentPassing):https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing
- Microsoft Learn - Parsing C command-line arguments:https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments
- GNU Wget Manual - Exit Status:https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「curlコマンドの使い方とオプション一覧|エラー対処・Windows・wget比較」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。