32blogby Studio Mitsu

curlコマンド完全ガイド:API操作からデバッグまで

curlの基本からAPI呼び出し・ヘッダー操作・認証・ファイル転送・スクリプト活用まで実例付きで解説。wgetとの使い分けも。

by omitsu19 min read
目次

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 が使えるか確認する。

bash
curl --version

WSL(Windows Subsystem for Linux)を使っている場合は Linux 版が利用できる。Git Bash にも curl が同梱されている。PowerShell の curlInvoke-WebRequest のエイリアスなので注意。

bash
# WSL(Ubuntu の場合)
sudo apt install curl

GETリクエスト

bash
curl https://example.com

指定した URL のレスポンスボディが標準出力に表示される。ファイルに保存したい場合:

bash
# ファイル名を指定して保存
curl -o output.html https://example.com

# URLのファイル名で保存
curl -O https://example.com/file.zip

レスポンスヘッダーを確認

bash
# ヘッダーだけ表示(HEADリクエスト)
curl -I https://example.com

# ヘッダー + ボディ両方
curl -i https://example.com

詳細表示(デバッグ用)

bash
curl -v https://example.com

TLSハンドシェイク、リクエストヘッダー、レスポンスヘッダーがすべて表示される。通信トラブルの調査に欠かせない。

サイレントモード

bash
# 進捗バーやエラーメッセージを非表示
curl -s https://example.com

# 進捗バーを # で表示(大きなファイル向け)
curl -# -O https://example.com/file.zip

よく使うオプション一覧

オプション意味
-o FILE出力ファイル名を指定
-OURLのファイル名で保存
-I / --headヘッダーのみ取得(HEADリクエスト)
-iレスポンスヘッダーも一緒に出力
-v / --verbose詳細表示(TLS含む全通信)
-s / --silent出力を抑制
-L / --locationリダイレクト追従
-X METHODHTTPメソッドを指定(POST, PUT, DELETE 等)
-H "Header: Value"カスタムヘッダーを追加
-d "data"POSTデータを送信
-u user:passBasic認証
-k / --insecureSSL証明書の検証をスキップ
-c FILECookieをファイルに保存
-b FILECookieをファイルから送信
--limit-rate RATE速度制限(例: --limit-rate 1M
-w "format"レスポンス情報をカスタム表示
--connect-timeout SEC接続タイムアウト(秒)
-C -ダウンロードを途中から再開
-F "key=@file"フォームデータ送信(ファイルアップロード)

実践ユースケース

REST API の呼び出し(GET / POST / PUT / DELETE)

APIテストで最も使うパターンをまとめる。

JSON を POST する:

bash
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice", "email": "alice@example.com"}' \
  https://api.example.com/users

Bearer トークンで認証する:

bash
curl -s \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  https://api.example.com/me

PUT でリソースを更新する:

bash
curl -s -X PUT \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice Updated"}' \
  https://api.example.com/users/123

DELETE でリソースを削除する:

bash
curl -s -X DELETE \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  https://api.example.com/users/123

レスポンスを jq で整形する:

bash
curl -s https://api.example.com/users | jq '.data[] | {id, name}'

JSON API のレスポンスを見やすくするなら jqコマンド完全ガイド も参考にしてほしい。

ヘッダー・リダイレクトのデバッグ

TLSハンドシェイクを含む全通信を確認する:

bash
curl -v https://example.com 2>&1 | head -30

-v の出力は stderr に出るため、2>&1 でまとめてから head で必要な分だけ確認できる。

レスポンスタイムを計測する:

bash
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 ハンドシェイク、合計時間をそれぞれ表示する。パフォーマンスのボトルネック特定に便利だ。

リダイレクトチェーンを追跡する:

bash
curl -s -L -o /dev/null -w "Final URL: %{url_effective}\nRedirects: %{num_redirects}\n" https://example.com

ファイルアップロード

フォームデータとしてファイルを送信する:

bash
curl -F "file=@photo.jpg" https://api.example.com/upload

複数ファイルを同時にアップロードする:

bash
curl -F "file1=@document.pdf" \
     -F "file2=@image.png" \
     -F "description=Monthly report" \
     https://api.example.com/upload

MIME タイプを明示する:

bash
curl -F "file=@data.csv;type=text/csv" https://api.example.com/import

ログインが必要なサイトでセッションを維持する方法。

bash
# 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

ダウンロード再開

大きなファイルのダウンロードが途中で切れた場合:

bash
# 最初のダウンロード(途中で 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つのオプションにまとめる。

bash
# 従来の書き方(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/jsonAccept: application/json を同時に設定する。ファイルや stdin からも読める。

bash
# ファイルから JSON を送信
curl --json @payload.json https://api.example.com/users

# パイプで渡す
echo '{"status": "active"}' | curl --json @- https://api.example.com/users/123

--retry でビルトインリトライ

スクリプトでリトライループを書かなくても、curl の --retry が使える。

bash
# 一時的なエラーで最大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 を同時にリクエストできる。

bash
# 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"
bash
# 最大同時接続数を制限
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)

毎回長いオプションを打つ代わりに、設定ファイルにまとめておける。

text
# ~/.curl/api-config
header = "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
header = "Content-Type: application/json"
header = "Accept: application/json"
silent
location
connect-timeout = 10
max-time = 30
bash
# 設定ファイルを使ってリクエスト
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)にはレスポンスタイム以外にも便利な変数がある。

bash
# レスポンスの詳細情報を一括表示
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
text
HTTP/2 200
Size: 12345 bytes
Content-Type: text/html; charset=utf-8
Connections: 1
IP: 93.184.215.14:443
bash
# 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 ヘルスチェック

複数のエンドポイントのステータスコードを一括確認するスクリプト。

bash
#!/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

ファイル一括ダウンロード(リトライ付き)

bash
#!/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 は本番で使わない

bash
# テスト環境でのみ使用すること
curl -k https://self-signed.example.com/api

-k--insecure)は SSL 証明書の検証をスキップする。自己署名証明書のテスト環境で一時的に使う分にはいいが、本番環境やスクリプトへの常用は中間者攻撃のリスクを生む。

パスワードをコマンドに書かない

bash
# 悪い例:シェル履歴に残る
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 にすること。他のユーザーから読めない状態にしておく。

環境変数を使う方法もある:

bash
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-TypeAccept-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

関連記事

まとめ

curl は HTTP 通信をコマンドラインから自在に操れる万能ツールだ。APIテストからデバッグ、ファイル転送、スクリプト自動化まで幅広くカバーする。

今日から使えるポイントをおさらい:

  • 基本は curl URL。ファイル保存は -o-O
  • API テストは --json '{...}'(7.82+)が最もシンプル
  • デバッグは -v で全通信を確認、-w でレスポンスタイム計測
  • スクリプトでは -s -f を付けてサイレント + エラー検出
  • 認証情報はコマンドに書かず .netrc か環境変数を使う
  • 最新バージョンは curl.se で定期的に確認

ファイルダウンロードが中心なら wget の方がシンプルだ。API 呼び出しや HTTP デバッグが目的なら curl 一択。両方を場面で使い分けるのがベストだ。