curlは、コマンドラインからHTTP通信を操るための万能ツールだ。 curl URL でGETリクエスト、-X POST -d '{...}' でAPIへのデータ送信、-v で通信内容のデバッグ — ほぼすべてのHTTP操作をワンライナーでこなせる。
「APIのレスポンスをターミナルで確認したい」「サーバーがリダイレクトしてるか調べたい」「CIスクリプトからWebhookを叩きたい」
こういう場面で真っ先に使うのが curl だ。Linux・macOS にはほぼ確実にプリインストールされているし、Windows でも WSL や Git Bash で使える。
今回は curl の基本から、API操作・デバッグ・スクリプト活用まで、実行可能なコマンド例を交えて解説する。
curl とは
curl は URL を指定してデータを送受信するコマンドラインツールだ。正式名称は「Client URL」。HTTP / HTTPS / FTP / SFTP / SCP など、20以上のプロトコルに対応している。1998年に Daniel Stenberg が開発を開始し、現在も活発にメンテナンスされている。
主な特徴:
- HTTP通信の万能ツール:GET / POST / PUT / DELETE などあらゆるメソッドを使える
- レスポンス制御が柔軟:ヘッダーだけ取得、ボディだけ取得、レスポンスタイム計測など自在
- libcurl:C言語のライブラリとしても提供されており、Python・PHP・Ruby など多くの言語から利用できる
- クロスプラットフォーム:Linux / macOS / Windows のどれでも動く
wget との違い を一言で言うと、wget は「ファイルダウンロード特化」、curl は「HTTP通信全般の万能ツール」だ。再帰ダウンロードやサイトミラーリングは wget の方が得意だが、API呼び出し・レスポンス操作・複雑なHTTPリクエストは curl の独壇場になる。
詳しい使い分けは wgetコマンド完全ガイド を参照してほしい。
基本的な使い方
インストール確認
まず curl が使えるか確認する。
curl --version
WSL(Windows Subsystem for Linux)を使っている場合は Linux 版が利用できる。Git Bash にも curl が同梱されている。PowerShell の curl は Invoke-WebRequest のエイリアスなので注意。
# WSL(Ubuntu の場合)
sudo apt install curl
GETリクエスト
curl https://example.com
指定した URL のレスポンスボディが標準出力に表示される。ファイルに保存したい場合:
# ファイル名を指定して保存
curl -o output.html https://example.com
# URLのファイル名で保存
curl -O https://example.com/file.zip
レスポンスヘッダーを確認
# ヘッダーだけ表示(HEADリクエスト)
curl -I https://example.com
# ヘッダー + ボディ両方
curl -i https://example.com
詳細表示(デバッグ用)
curl -v https://example.com
TLSハンドシェイク、リクエストヘッダー、レスポンスヘッダーがすべて表示される。通信トラブルの調査に欠かせない。
サイレントモード
# 進捗バーやエラーメッセージを非表示
curl -s https://example.com
# 進捗バーを # で表示(大きなファイル向け)
curl -# -O https://example.com/file.zip
よく使うオプション一覧
| オプション | 意味 |
|---|---|
-o FILE | 出力ファイル名を指定 |
-O | URLのファイル名で保存 |
-I / --head | ヘッダーのみ取得(HEADリクエスト) |
-i | レスポンスヘッダーも一緒に出力 |
-v / --verbose | 詳細表示(TLS含む全通信) |
-s / --silent | 出力を抑制 |
-L / --location | リダイレクト追従 |
-X METHOD | HTTPメソッドを指定(POST, PUT, DELETE 等) |
-H "Header: Value" | カスタムヘッダーを追加 |
-d "data" | POSTデータを送信 |
-u user:pass | Basic認証 |
-k / --insecure | SSL証明書の検証をスキップ |
-c FILE | Cookieをファイルに保存 |
-b FILE | Cookieをファイルから送信 |
--limit-rate RATE | 速度制限(例: --limit-rate 1M) |
-w "format" | レスポンス情報をカスタム表示 |
--connect-timeout SEC | 接続タイムアウト(秒) |
-C - | ダウンロードを途中から再開 |
-F "key=@file" | フォームデータ送信(ファイルアップロード) |
実践ユースケース
REST API の呼び出し(GET / POST / PUT / DELETE)
APIテストで最も使うパターンをまとめる。
JSON を POST する:
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@example.com"}' \
https://api.example.com/users
Bearer トークンで認証する:
curl -s \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
https://api.example.com/me
PUT でリソースを更新する:
curl -s -X PUT \
-H "Content-Type: application/json" \
-d '{"name": "Alice Updated"}' \
https://api.example.com/users/123
DELETE でリソースを削除する:
curl -s -X DELETE \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
https://api.example.com/users/123
レスポンスを jq で整形する:
curl -s https://api.example.com/users | jq '.data[] | {id, name}'
JSON API のレスポンスを見やすくするなら jqコマンド完全ガイド も参考にしてほしい。
ヘッダー・リダイレクトのデバッグ
TLSハンドシェイクを含む全通信を確認する:
curl -v https://example.com 2>&1 | head -30
-v の出力は stderr に出るため、2>&1 でまとめてから head で必要な分だけ確認できる。
レスポンスタイムを計測する:
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" https://example.com
このコマンドは DNS 解決、TCP 接続、TLS ハンドシェイク、合計時間をそれぞれ表示する。パフォーマンスのボトルネック特定に便利だ。
リダイレクトチェーンを追跡する:
curl -s -L -o /dev/null -w "Final URL: %{url_effective}\nRedirects: %{num_redirects}\n" https://example.com
ファイルアップロード
フォームデータとしてファイルを送信する:
curl -F "file=@photo.jpg" https://api.example.com/upload
複数ファイルを同時にアップロードする:
curl -F "file1=@document.pdf" \
-F "file2=@image.png" \
-F "description=Monthly report" \
https://api.example.com/upload
MIME タイプを明示する:
curl -F "file=@data.csv;type=text/csv" https://api.example.com/import
Cookie 操作
ログインが必要なサイトでセッションを維持する方法。
# Step 1: ログインして Cookie を保存
curl -c cookies.txt \
-d "username=admin&password=secret" \
https://example.com/login
# Step 2: 保存した Cookie を使ってアクセス
curl -b cookies.txt https://example.com/dashboard
# Step 3: Cookie を送りつつ新しい Cookie も保存
curl -b cookies.txt -c cookies.txt https://example.com/profile
ダウンロード再開
大きなファイルのダウンロードが途中で切れた場合:
# 最初のダウンロード(途中で Ctrl+C 等)
curl -O https://example.com/largefile.iso
# 途中から再開
curl -C - -O https://example.com/largefile.iso
-C - の - は「現在のファイルサイズを自動検出して続きから」という意味だ。
応用テクニック
--json で JSON API をシンプルに呼ぶ
curl 7.82+ で追加された --json フラグは、JSON API 呼び出しの定型パターンを1つのオプションにまとめる。
# 従来の書き方(3つのオプションが必要)
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name": "Alice"}' \
https://api.example.com/users
# --json なら1つで済む
curl -s --json '{"name": "Alice"}' https://api.example.com/users
--json は内部的に -d(POST)、Content-Type: application/json、Accept: application/json を同時に設定する。ファイルや stdin からも読める。
# ファイルから JSON を送信
curl --json @payload.json https://api.example.com/users
# パイプで渡す
echo '{"status": "active"}' | curl --json @- https://api.example.com/users/123
--retry でビルトインリトライ
スクリプトでリトライループを書かなくても、curl の --retry が使える。
# 一時的なエラーで最大3回リトライ(間隔は自動バックオフ)
curl --retry 3 --retry-delay 2 https://api.example.com/data
# 全エラー(4xx/5xx含む)でリトライする場合
curl --retry 3 --retry-all-errors https://api.example.com/data
# リトライの最大時間を制限
curl --retry 5 --retry-max-time 60 https://api.example.com/data
デフォルトでは接続タイムアウト、HTTP 408、HTTP 429、HTTP 5xx がリトライ対象だ。--retry-all-errors を付けるとネットワークエラーも含め全てリトライする。
並列リクエスト(--parallel)
curl 7.66+ の --parallel(-Z)で、複数 URL を同時にリクエストできる。
# 4つの API を並列にリクエスト
curl -Z -s \
-o users.json "https://api.example.com/users" \
-o posts.json "https://api.example.com/posts" \
-o comments.json "https://api.example.com/comments" \
-o tags.json "https://api.example.com/tags"
# 最大同時接続数を制限
curl -Z --parallel-max 3 -s \
-o file1.zip "https://example.com/file1.zip" \
-o file2.zip "https://example.com/file2.zip" \
-o file3.zip "https://example.com/file3.zip" \
-o file4.zip "https://example.com/file4.zip" \
-o file5.zip "https://example.com/file5.zip"
--parallel-max のデフォルトは 50。API のレートリミットに合わせて調整しよう。
設定ファイルで定型リクエストを再利用(-K)
毎回長いオプションを打つ代わりに、設定ファイルにまとめておける。
# ~/.curl/api-config
header = "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
header = "Content-Type: application/json"
header = "Accept: application/json"
silent
location
connect-timeout = 10
max-time = 30
# 設定ファイルを使ってリクエスト
curl -K ~/.curl/api-config https://api.example.com/users
# 設定ファイル + 追加オプション
curl -K ~/.curl/api-config --json '{"name": "Alice"}' https://api.example.com/users
チームで共有すれば、API テストの手順を統一できる。ヘルスチェックを定期実行したい場合は、cron / systemd timer と組み合わせるのがおすすめだ。
-w の実用的な変数
-w(--write-out)にはレスポンスタイム以外にも便利な変数がある。
# レスポンスの詳細情報を一括表示
curl -s -o /dev/null -w "\
HTTP/%{http_version} %{http_code}\n\
Size: %{size_download} bytes\n\
Content-Type: %{content_type}\n\
Connections: %{num_connects}\n\
IP: %{remote_ip}:%{remote_port}\n\
" https://example.com
HTTP/2 200
Size: 12345 bytes
Content-Type: text/html; charset=utf-8
Connections: 1
IP: 93.184.215.14:443
# JSON形式で出力(jq と組み合わせ)
curl -s -o /dev/null -w '{
"status": %{http_code},
"time_total": %{time_total},
"size": %{size_download},
"ip": "%{remote_ip}"
}' https://example.com | jq '.'
スクリプト活用例
curl はシェルスクリプトとの相性が抜群だ。基本的なシェルスクリプトの書き方は シェルスクリプト実践ガイド を参照してほしい。
API ヘルスチェック
複数のエンドポイントのステータスコードを一括確認するスクリプト。
#!/bin/bash
ENDPOINTS=(
"https://api.example.com/health"
"https://api.example.com/v2/status"
"https://cdn.example.com/ping"
"https://auth.example.com/health"
)
echo "=== API Health Check ==="
echo ""
FAILED=0
for URL in "${ENDPOINTS[@]}"; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 10 "$URL")
if [ "$STATUS" -ge 200 ] && [ "$STATUS" -lt 300 ]; then
echo "[OK] $STATUS $URL"
else
echo "[FAIL] $STATUS $URL"
FAILED=$((FAILED + 1))
fi
done
echo ""
echo "Results: $((${#ENDPOINTS[@]} - FAILED))/${#ENDPOINTS[@]} passed"
if [ "$FAILED" -gt 0 ]; then
exit 1
fi
ファイル一括ダウンロード(リトライ付き)
#!/bin/bash
URLS=(
"https://example.com/data/january.csv"
"https://example.com/data/february.csv"
"https://example.com/data/march.csv"
)
DEST_DIR="./downloads"
MAX_RETRIES=3
mkdir -p "$DEST_DIR"
for URL in "${URLS[@]}"; do
FILENAME=$(basename "$URL")
ATTEMPT=1
while [ "$ATTEMPT" -le "$MAX_RETRIES" ]; do
echo "Downloading $FILENAME (attempt $ATTEMPT/$MAX_RETRIES)..."
if curl -s -f -L -o "${DEST_DIR}/${FILENAME}" --connect-timeout 10 --max-time 120 "$URL"; then
echo " OK: $FILENAME"
break
else
echo " FAILED: $FILENAME"
ATTEMPT=$((ATTEMPT + 1))
if [ "$ATTEMPT" -le "$MAX_RETRIES" ]; then
echo " Retrying in 5 seconds..."
sleep 5
fi
fi
done
if [ "$ATTEMPT" -gt "$MAX_RETRIES" ]; then
echo " GAVE UP: $FILENAME after $MAX_RETRIES attempts"
fi
done
echo "Done."
セキュリティの注意点
curl のセキュリティ動向
curl 8.19.0(2026年3月11日リリース)が現時点の最新版だ。直前の 8.18.0(2026年1月7日)では 6件のセキュリティ修正が含まれていた。
curl のバグバウンティプログラムは2026年1月末に終了した。AI生成レポートの大量投稿により、有効な報告の確認率が5%未満に急落し、トリアージのリソースを圧迫したことが原因だ。2019年4月の開始から約6年間で87件の脆弱性が確認され、総額10万ドル以上の報奨金が支払われた。
-k は本番で使わない
# テスト環境でのみ使用すること
curl -k https://self-signed.example.com/api
-k(--insecure)は SSL 証明書の検証をスキップする。自己署名証明書のテスト環境で一時的に使う分にはいいが、本番環境やスクリプトへの常用は中間者攻撃のリスクを生む。
パスワードをコマンドに書かない
# 悪い例:シェル履歴に残る
curl -u admin:P@ssw0rd https://api.example.com/admin
# 良い例:.netrc を使う
echo "machine api.example.com login admin password P@ssw0rd" > ~/.netrc
chmod 600 ~/.netrc
curl -n https://api.example.com/admin
.netrc ファイルのパーミッションは必ず 600 にすること。他のユーザーから読めない状態にしておく。
環境変数を使う方法もある:
curl -u "admin:${API_PASSWORD}" https://api.example.com/admin
よくある質問(FAQ)
curl と wget はどう使い分ける?
curlはAPI呼び出し・HTTPデバッグ・複雑なリクエスト構築が得意。wgetは再帰ダウンロード・サイトミラーリングが得意。APIテストならcurl、ファイル一括ダウンロードならwget、と覚えておけばいい。詳しくは wgetコマンド実践ガイド を参照。
curl でJSONを送信する一番シンプルな方法は?
curl 7.82以降なら curl --json '{"key": "value"}' URL が最もシンプル。--json フラグが Content-Type・Accept・-d をまとめて設定してくれる。古いバージョンでは -X POST -H "Content-Type: application/json" -d '{...}' を使う。
curl のレスポンスが遅い原因を調べるには?
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" URL でDNS解決・TCP接続・TLSハンドシェイク・合計時間を個別に計測できる。ボトルネックがどのフェーズにあるか一目でわかる。
curl -k(--insecure)を本番で使っていいか?
使ってはいけない。-k はSSL証明書の検証をスキップするため、中間者攻撃のリスクがある。自己署名証明書のテスト環境でのみ一時的に使うべきだ。本番では正規の証明書を用意するか、--cacert でCA証明書を指定する。
curl でファイルアップロードする方法は?
curl -F "file=@ファイル名" URL でフォームデータとしてアップロードできる。MIMEタイプを指定する場合は curl -F "file=@data.csv;type=text/csv" URL。複数ファイルは -F を繰り返す。
curl のパスワードをシェル履歴に残さない方法は?
.netrc ファイルに認証情報を書き、curl -n URL で参照するのが定番。.netrc のパーミッションは chmod 600 で他ユーザーから読めなくする。環境変数(curl -u "user:${PASSWORD}" URL)も使える。
curl でリトライを自動化するには?
curl --retry 3 --retry-delay 2 URL で一時的なエラー時に最大3回リトライする。--retry-all-errors を付ければ4xx/5xxも含めてリトライ対象になる。スクリプトでリトライループを書く必要はない。
curl の最新バージョンを確認するには?
curl --version でローカルのバージョンを確認。最新リリースは curl公式ダウンロードページ で確認できる。2026年3月時点の最新は 8.19.0。
関連記事
- jqコマンド完全ガイド —
curl | jqでAPIレスポンスのJSON加工。curl の最強の相棒 - wgetコマンド実践ガイド — ファイルダウンロード特化。curlとの使い分け
- シェルスクリプト実践ガイド — curl を活かしたスクリプト自動化の基礎
- SSH・rsync実践ガイド — リモートサーバー操作。curl + SSH でAPI自動化
- xargsコマンド実践ガイド — curl と組み合わせて複数URLを一括処理
- grep・ripgrep実践ガイド — curl の出力からテキスト検索
- CLIツール完全マップ — CLI ツールの全体像と使い分け
まとめ
curl は HTTP 通信をコマンドラインから自在に操れる万能ツールだ。APIテストからデバッグ、ファイル転送、スクリプト自動化まで幅広くカバーする。
今日から使えるポイントをおさらい:
- 基本は
curl URL。ファイル保存は-oか-O - API テストは
--json '{...}'(7.82+)が最もシンプル - デバッグは
-vで全通信を確認、-wでレスポンスタイム計測 - スクリプトでは
-s -fを付けてサイレント + エラー検出 - 認証情報はコマンドに書かず
.netrcか環境変数を使う - 最新バージョンは curl.se で定期的に確認
ファイルダウンロードが中心なら wget の方がシンプルだ。API 呼び出しや HTTP デバッグが目的なら curl 一択。両方を場面で使い分けるのがベストだ。