curlコマンド:オプションの使い方とPOSTリクエスト、ファイルのダウンロード

テスト環境RHEL系AlmaLinux 9.8rootアカウント2026-10-28 確認

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.txt
User-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=86400

1行目の[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

オプションによってリクエストが何回送られ、画面に何が表示されるかは、下の図で順に比較できます。

🧭 curlオプション別のリクエストと出力:httpアドレスの301
解説ダイアグラム
⚙️ オプション
$ curl -I -L -IL http://example.com/
① GETHEAD リクエストhttp://example.com/
➜
301 Moved PermanentlyLocation: https://example.com/
② GETHEAD リクエストhttps://example.com/リクエストしない
➜
200レスポンスなし
🖥️ 画面に出力されるもの
301レスポンス本文(HTML 7行)
301レスポンスヘッダー7行
200レスポンス本文(トップページのHTML 96,679バイト)
301レスポンスヘッダー7行 → 200レスポンスヘッダー10行
オプションなしでリクエストすると、curlは[Location]のhttpsアドレスへ再びリクエストせず、301レスポンスの本文だけを出力します。
-IはHEADリクエストでヘッダーだけを受け取り、移動先のアドレスへ再びリクエストせずに、301のステータスと[Location]ヘッダーを出力します。
-Lは[Location]のhttpsアドレスへもう一度リクエストし、最後の200レスポンスの本文を出力します。
-ILは2回リクエストしたレスポンスのヘッダーを順にすべて出力します。301の次に200が続きます。

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 --:--:-- --:--:-- --:--:--  190k
ls -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 --:--:-- --:--:-- --:--:-- 4291k
ls -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/application

4️⃣ 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/posts
401

5️⃣ 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.022825

connectはTCP接続、tlsはTLSネゴシエーション、 ttfbは最初のバイトが送られる直前まで、totalは転送が終わるまでの時間です。4つの値はいずれも、リクエストを開始した時点から積み上げた秒単位です。

curlを実行したサーバーとリクエストを受けたサイトが同じサーバーだったため、接続は0.0015秒と短く、TLSネゴシエーションまで0.0177秒、最初のバイトまで0.0219秒かかりました。TLSネゴシエーションが終わってから最初のバイトが届くまでは約0.004秒でした。公式ドキュメントは、この区間にサーバーが結果を作る時間が含まれると説明しています。

同じコマンドをさらに3回実行したとき、totalは0.0219秒から0.0226秒の間でした。

🔲 curlコマンドシミュレーター

下のシミュレーターで、ここまでのコマンドを実際に入力し、オプションごとに出力がどう変わるかを確認できます。

curlコマンドシミュレーターcurl 7.76.1
[root@server work]#
キーボードの↑↓で、前に入力したコマンドを呼び出せます。

🔢 FAQ & おすすめコンテンツ

-sは進捗表示とエラーメッセージの両方を隠します。存在しないアドレスへリクエストすると、何も出力されず終了コード6だけが残りました。-sSと一緒に指定すると、進捗表示は隠したまま、[curl: (6) Could not resolve host]のようなエラーはそのまま表示されます。

-kを使うと接続が安全かどうかを確かめる手順を飛ばすため、接続したサーバーがそのドメインのサーバーかどうかを確認せずに送信します。curlは、サーバー証明書に接続先のドメイン名が含まれているかと、証明書ストアで検証できるかを確認します。このエラーが出たら、まず証明書のドメイン名と発行機関を確認します。

公式ドキュメントによると、301、302、303のレスポンスを受け取ると、curlは次のリクエストをGETに変えて送信します。POSTを維持するには、[--post301]のような専用オプションを使います。-Xで指定したメソッドはこの変換より優先されます。

🧭 ネットワークコマンドのおすすめコンテンツ 記事9・参照2
🗂️ ネットワークコマンド
📄 SSHコマンド 📄 rsyncコマンド 📄 wgetコマンド 📄 rz・szコマンド 📄 curlコマンド
📄 hostコマンド 📄 nslookupコマンド
📄 ipコマンド 📄 netstat・ifconfigコマンド
Linux SSH(Secure Shell)
Linux · 接続
SSHコマンド:オプションと使い方
LinuxのSSH(Secure Shell)は、ネットワークを通じて別のシステムへ安全に接続できるようにするプロトコルです。
記事を見る →現在の記事
rsyncコマンド_ローカルからリモートへ送る
Linux · 転送
Linux rsyncコマンド: オプションと使用例
サーバー2台のフォルダーを揃えるために毎回全体をコピーし直すと、変わったファイルが1つでも転送量はフォルダー全体のままです。
記事を見る →現在の記事
Linux TOPコマンド:コマンドラインインターフェース(CLI-Command-Line Interface)
Linux · 転送
Linux wgetコマンド
wgetコマンドは、WebのダウンロードリンクをLinuxのコマンドラインから実行してダウンロードするコマンドです。
記事を見る →現在の記事
lrzszツールのインストール - Rocky Linux
Linux · 転送
Linux:lrzszツールのインストールとファイルのアップロード(rz)・ダウンロード(sz)
Linux OSでrzとszによるファイルのアップロードとダウンロードのコマンドを実行するには、サーバーにlrzszがインストールされている必要があります。
記事を見る →現在の記事
curlコマンドのオプション別リクエストと出力の説明図:-ILで301ヘッダーの次に200ヘッダーを出力
Linux · 転送
curlコマンド:オプションの使い方とPOSTリクエスト、ファイルのダウンロード
ターミナルからWebアドレスへリクエストを送り、レスポンスをそのまま出力するツールがcurlで、curlコマンド1つでページの本文とヘッダー、ステータスコードを確認できます。
記事を見る →現在の記事

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

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

人間であることを証明してください: 0   +   4   =