curlコマンド:オプションの使い方とPOSTリクエスト、ファイルのダウンロード
curlコマンドは、ターミナルからWebアドレスへリクエストを送り、レスポンスをそのまま出力するツールです。コマンド1行でページの本文とヘッダー、ステータスコードを確認できます。AlmaLinux 9サーバーからWordPressサイトへcurlでリクエストを送った結果、httpのアドレスは301レスポンスでhttpsのアドレスを案内し、認証のないREST APIリクエストは401で拒否されました。
1️⃣ curlコマンドの基本的な使い方とレスポンス本文
curlの後ろにアドレスを1つ付けると、そのアドレスへGETリクエストを送り、レスポンス本文を画面に出力します。WordPressが生成するrobots.txtをリクエストすると、3行のファイル内容がそのまま表示されました。
curl https://example.com/robots.txtUser-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.phpブラウザーのアドレスバーに入れたときと同じ画面を期待しがちですが、curlが出力するのはサーバーが送ったHTMLそのものです。curlはスクリプトを実行したり、画像やCSSを別にリクエストしたりしません。ページのHTMLは長いため、Webページのアドレスは出力をパイプでheadに渡し、先頭の数行だけを確認します。
curl -s https://example.com/ | head -n 2<!DOCTYPE html>
<html lang="ko-KR">-sを付けると、パイプで渡すときに画面に混ざる進捗表示を隠します。トップページのアドレス1つで受け取ったHTMLは96,679バイトでした。画像やスクリプトのファイルはこのサイズに含まれていません。
2️⃣ curl -Iでのヘッダー確認と-Lでのリダイレクト
本文だけではリクエストが成功したかどうか分からないため、ステータスコードとヘッダーは-Iで別に確認します。-IはHEADリクエストを送り、本文なしでレスポンスヘッダーだけを出力します。宅配便の箱を開けずに送り状だけを確認するのと同じです。
curl -I https://example.com/HTTP/2 200
server: nginx/1.28.0
date: Wed, 28 Oct 2026 05:29:23 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
last-modified: Tue, 27 Oct 2026 21:12:18 GMT
cache-control: max-age=0
expires: Wed, 28 Oct 2026 05:29:23 GMT
accept-ranges: none
alt-svc: h3=":443"; ma=864001行目の[HTTP/2 200]がステータスコードです。その下にサーバーの種類、コンテンツの形式、キャッシュ関連のヘッダーが続きます。同じリクエストをhttpのアドレスへ送ると、301とともに[Location]ヘッダーに移動先のhttpsアドレスが表示されます。
curl -I http://example.com/HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.0
Date: Wed, 28 Oct 2026 05:27:51 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/オプションなしでhttpのアドレスをリクエストすると、curlは[Location]のアドレスへ再びリクエストせず、301レスポンスの本文7行だけを出力して終了しました。
curl http://example.com/<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>-Lを付けると、[Location]のアドレスへ再びリクエストします。-Iと組み合わせて-ILで実行すると、301レスポンスヘッダーの次に200レスポンスヘッダーが順に表示されます。
curl -IL http://example.com/HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.0
Date: Wed, 28 Oct 2026 05:29:23 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/
HTTP/2 200
server: nginx/1.28.0
date: Wed, 28 Oct 2026 05:29:23 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
last-modified: Tue, 27 Oct 2026 21:12:18 GMT
cache-control: max-age=0
expires: Wed, 28 Oct 2026 05:29:23 GMT
accept-ranges: none
alt-svc: h3=":443"; ma=86400オプションによってリクエストが何回送られ、画面に何が表示されるかは、下の図で順に比較できます。
3️⃣ curlコマンドでファイルをダウンロード(-o、-O)
-Oはアドレスの最後のファイル名のまま、現在のフォルダーに保存します。保存中の画面には本文の代わりに進捗表示が出ます。
curl -O https://example.com/wp-includes/images/w-logo-blue.png % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 3113 100 3113 0 0 178k 0 --:--:-- --:--:-- --:--:-- 190kls -l w-logo-blue.png-rw-r--r-- 1 root root 3113 Oct 28 14:29 w-logo-blue.pngダウンロードの結果、進捗表示の[Total]と[Received]はどちらも3113で、ls -lで確認したファイルサイズも3,113バイトで一致しました。
保存する名前を自分で決めるには、-oの後ろにファイル名を書きます。下は、トップページのアドレスをhome.htmlとして保存した結果です。
curl -o home.html https://example.com/ % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 96679 0 96679 0 0 4291k 0 --:--:-- --:--:-- --:--:-- 4291kls -l home.html-rw-r--r-- 1 root root 96679 Oct 28 14:29 home.html-Oはアドレス末尾のファイル名をそのまま使うため、スラッシュで終わるページのアドレスには向きません。トップページのアドレスに-Oを付けると、ファイル名が見つからず、下のエラーとともに終了します。
curl -O https://example.com/curl: Remote file name has no length!
curl: (23) Failed writing received data to disk/application4️⃣ curlのPOSTリクエストとJSONデータの送信
読むだけだったリクエストにデータを載せて送るには-dを使い、データの形式を示すときは-Hを加えます。-dは後ろに書いたデータをPOSTの本文として送ります。特に指定しない場合の[Content-Type]は[application/x-www-form-urlencoded]です。
-dを使うとリクエストの方式がPOSTに変わるため、[-X POST]は省略できます。公式ドキュメントでも、通常-Xは必要ないと説明しています。
JSONを送るときは、-Hで[Content-Type]を[application/json]に変えます。下は、WordPressのREST APIへ認証なしで投稿作成リクエストを送った結果です。
curl -s -X POST -H 'Content-Type: application/json' -d '{"title":"curl test"}' https://example.com/wp-json/wp/v2/posts{"code":"rest_authentication_error","message":"\uc8c4\uc1a1\ud569\ub2c8\ub2e4. REST API \uc694\uccad\uc744 \ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.","data":{"status":401}}リクエスト先のサイトが ログインしていないREST APIリクエストをブロックしている ため、codeに[rest_authentication_error]が返り、ステータスは401でした。同じ設定のため、同じアドレスへGETで投稿一覧をリクエストしても401が返りました。messageの値は、サイトの言語で書かれたエラー文がJSONのUnicode表記に変わって出てきたものです。
ステータスコードだけを確認するには、本文を[-o /dev/null]で捨て、-wでhttp_codeだけを出力します。
curl -s -o /dev/null -w '%{http_code}\n' -X POST -H 'Content-Type: application/json' -d '{"title":"curl test"}' https://example.com/wp-json/wp/v2/posts4015️⃣ curlコマンドで応答時間を測定(-w)
応答が遅いときはtotalだけを見がちですが、接続とサーバー処理のどこで時間がかかったのかは、区間ごとの時間を分けて出力しないと確認できません。-wはリクエストが終わった後、指定した形式で測定値を出力します。形式の中の[%{変数名}]の部分に値が入ります。
本文は[-o /dev/null]で捨て、-sで進捗表示を隠します。
curl -o /dev/null -s -w 'code: %{http_code}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\n' https://example.com/code: 200
connect: 0.001507
tls: 0.017728
ttfb: 0.021912
total: 0.022825connectはTCP接続、tlsはTLSネゴシエーション、 ttfbは最初のバイトが送られる直前まで、totalは転送が終わるまでの時間です。4つの値はいずれも、リクエストを開始した時点から積み上げた秒単位です。
curlを実行したサーバーとリクエストを受けたサイトが同じサーバーだったため、接続は0.0015秒と短く、TLSネゴシエーションまで0.0177秒、最初のバイトまで0.0219秒かかりました。TLSネゴシエーションが終わってから最初のバイトが届くまでは約0.004秒でした。公式ドキュメントは、この区間にサーバーが結果を作る時間が含まれると説明しています。
同じコマンドをさらに3回実行したとき、totalは0.0219秒から0.0226秒の間でした。
🔲 curlコマンドシミュレーター
下のシミュレーターで、ここまでのコマンドを実際に入力し、オプションごとに出力がどう変わるかを確認できます。
🔢 FAQ & おすすめコンテンツ




ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。



