curl/wget入門 - コマンドラインでのHTTP通信

curl/wget入門 - コマンドラインでのHTTP通信

この記事でできるようになること

  • `curl` と `wget` を目的に合わせて選べる
  • ダウンロードしたファイルの保存先と上書きの危険を先に確認できる
  • リダイレクト追従・ヘッダー確認・JSON の POST をコピペで実行できる

前提知識(先に読むと理解しやすい記事)

この記事で学べること

  • curlwget役割の違い がわかります
  • ダウンロードしたファイルが どこに作られるか を先に確認できます
  • 上書きの危険 を避けながらファイルを取ってこられます
  • ヘッダー確認や API アクセスを コピペで動かせる ようになります

言葉の整理(先に取りちがえを防ぎます)

  • ダウンロード:ネットワークの向こうにあるデータを、自分のパソコンに写し取ることです。
  • リダイレクト:「このページは別の場所へ引っこしました」というサーバからの案内です。シェル入力したコマンドを解釈してコンピュータに実行させる対話プログラム。>(リダイレクト)とは 別のもの です。同じ言葉が 2 つの意味で使われます。
  • ヘッダー:本文とは別に送られてくる情報の札です。中身の種類や大きさが書かれています。
  • ステータスコード:結果を表す 3 桁の数字です。200 は成功、404 は見つからない、を表します。
  • API:プログラム同士がやり取りするための窓口です。返事は HTML ではなく JSON という形式が多いです。

結論(先に覚える型)

  • 単発のファイルダウンロード → wget URL
  • API を叩く・ヘッダー確認・POST → curl URL
  • リダイレクトを追従したい → curl -L URL
  • ダウンロードが途中で切れた → wget -c URL

前提(対象環境)

  • OS:Ubuntu / 一般的な Linux
  • curl は標準搭載が多いです。wgetsudo apt install wget で入ります
  • 対象は HTTP / HTTPS です(curl は ftp / sftp / smtp 等にも対応します)

1. curl と wget の違い:まず役割を分ける

結論: wget はダウンローダーで保存がデフォルト、curl は多機能 HTTP クライアントで標準出力がデフォルト。

リナ: 先輩、curl と wget ってどっちも「URL からデータを取ってくる」コマンドですよね。どちらを使えばいいのか毎回迷います。
ライニー先輩: いい質問。実は 設計の目的が違う んだ。一言で言うと、wget は ダウンローダー、curl は 多機能 HTTP クライアント だよ。
リナ: ダウンローダーと、クライアント、ですか。
ライニー先輩: ダウンローダーは「ファイルを落とす専門の道具」。クライアントは「サーバに話しかける側」のことだよ。
リナ: なるほど。curl の方が守備範囲が広いのですね。
ライニー先輩: そう。wget は「URL を渡したらファイルを保存する」のがデフォルト動作。curl は「URL を叩いてレスポンスを画面に出す」のがデフォルト。この差が、ほかの全部の違いにつながっているよ。

ざっくり比較

項目 curl wget
デフォルト動作 標準出力に表示 ファイルとして保存
HTTP メソッド GET/POST/PUT/DELETE 等 基本 GET のみ
リダイレクト追従 -L を付ける必要あり 自動で追従
再帰ダウンロード 苦手 得意(-r
レジューム -C - で対応 -c で対応
用途 API 叩く・デバッグ・POST サイト丸ごとミラー・DL

迷ったら:API・ヘッダー・POST が絡むなら curl です。ファイルを落とすだけなら wget です。

2. curl の基本:まず画面に出す

結論: curl は既定で内容を画面に出す。保存するには -o 名前(名前指定)か -O(URL のファイル名)を付ける。

2-1. URL を叩いて結果を画面に出す

$ curl https://example.com
<!doctype html>
<html>
<head>
    <title>Example Domain</title>
...
リナ: えっ、HTML が全部画面に流れてきました。
ライニー先輩: それが curl のデフォルト動作。標準出力(画面)に丸ごと吐く んだ。ファイルにしたいときは -o(名前指定)か -O(URL のファイル名を使う)を付けるよ。

2-2. 名前を指定して保存 -o

$ curl -o page.html https://example.com

-ooutput(出力)の頭文字です。小文字の o は、保存する名前を引数で指定します。

2-3. URL のファイル名で保存 -O

$ curl -O https://example.com/sample.tar.gz

大文字の O は、URL の末尾のファイル名をそのまま使います。この例なら sample.tar.gz という名前で保存されます。

-o-O を間違えると悲しい結末

  • -O を付ける URL は 末尾がファイル名であること が前提です
  • curl -O https://example.com/(末尾スラッシュ)は、ファイル名が決まらず失敗します
  • 迷ったら -o 名前 で明示する方が安全です

2-4. どこに保存される? 上書きは?

ダウンロードの前に、2 つだけ確認しておきます。「どこに作られるか」と「同じ名前があったらどうなるか」です。

保存先と上書きの先回り

  • 保存先は いま自分がいるディレクトリファイルをまとめて整理する入れ物。Windows や macOS の「フォルダ」と同じもの。(カレントディレクトリ)です。pwd で確認できます
  • curl -Ocurl -o は、同じ名前のファイルがあっても確認なしで上書きします
  • GUI のファイル操作と違い、上書き前の確認ダイアログは出ません。元の中身は戻せません
  • 上書きを止めたいときは curl --no-clobber -O URL を使います。同じ名前があれば curl は何もしません
  • wget は既定では上書きしません。代わりに sample.tar.gz.1 のように連番を足して保存します
  • curlwget は本サイトの仮想ターミナルでは動きません。実行は自分のパソコンのターミナルで行います
  • 練習は「10. ミニ課題」で作る、からっぽのディレクトリの中だけで行ってください。そこなら、もとからあるファイルを壊しません
リナ: 先輩、curl -O で落とした設定ファイルを少し書きかえたんです。そのあと、もう一度同じコマンドを実行しました。そうしたら、書きかえた内容が消えていました。
ライニー先輩: それは上書きだね。curl は「同じ名前があるよ、いい?」とは聞かない。だまってファイルを置きかえるんだ。
リナ: えっ、確認なしなんですか。ゴミ箱にも残らない…。
ライニー先輩: 残らないよ。だから 落とす前に ls で同じ名前がないか見る のが安全。名前を変えたいときは -o で自分で決める。この 2 つで事故はほぼ防げるよ。
リナ: なるほど。「落とす前に ls」を先にやればよかったんですね。
# 落とす前に、いる場所と既存ファイルを確認する
$ pwd
$ ls sample.tar.gz

# 上書きが怖いときは自分で名前を決める
$ curl -o sample-20260605.tar.gz https://example.com/sample.tar.gz

2-5. ダウンロード進捗を見たい

$ curl -O --progress-bar https://example.com/big.iso

--progress-bar を付けると、シンプルな進捗バーが出ます。長いダウンロードでも状況がわかります。

3. 初心者の最大の罠:リダイレクト -L

結論: curl は既定でリダイレクトを追わない。GitHub 等を叩くときは -L を付けて最終ページを取得する。

リナ: 先輩、https://github.com/torvalds/linux を curl で取ってみたんです。でも中身が変なんです。
ライニー先輩: ああ、それは典型的なハマりどころ。GitHub やショート URL は、途中で リダイレクト が挟まることが多いんだ。
リナ: リダイレクト、でしたね。「引っこしました」の案内ですか。
ライニー先輩: そう。curl はデフォルトで その案内を追いかけない。だから引っこし先ではなく、案内のページだけが返ってくる。-L を付けると追いかけるようになるよ。

3-1. リダイレクトを追従する -L

# NG: リダイレクトされた案内が返るだけ
$ curl https://github.com/torvalds/linux

# OK: 最終ページの内容を取得
$ curl -L https://github.com/torvalds/linux

-LLocation の頭文字です。Location は、引っこし先を伝える HTTP ヘッダーの名前です。

型として覚える

  • 外部サイトを curl で叩くときは 常に -L を付ける と事故が減ります
  • ファイルダウンロードでも -L が必要な場面は多いです(GitHub Releases 等)
# 安全な定番形
$ curl -LO https://github.com/some/repo/releases/download/v1.0/binary.tar.gz

-LO-L-O をつなげた書き方です。1 文字のオプションは、このようにまとめて書けます。-L -O と離して書いても同じ意味です。

結論: -I は本文を落とさずヘッダーだけ取得する。先頭の HTTP ステータスコードで生死やリダイレクトが分かる。

「リンク先は生きているか」「リダイレクト先はどこか」を、本文をダウンロードせずに 確認できます。

$ curl -I https://example.com
HTTP/2 200
content-type: text/html; charset=UTF-8
content-length: 1256
date: Sun, 26 May 2026 09:00:00 GMT
server: ECS
リナ: なるほど、HTTP/2 200 は「成功」ですね。
ライニー先輩: その通り。最初の数字が HTTP ステータスコード。これだけ覚えれば実務の 9 割は読めるよ。

HTTP ステータス 早見表

コード 意味 状況
2xx 成功 200 OK204 No Content
3xx リダイレクト 301(恒久)、302(一時)
4xx クライアント側 404(無い)、401/403(権限)
5xx サーバー側 500(バグ)、503(過負荷)

4-1. リダイレクト先を辿る

$ curl -ILs https://bit.ly/3xxxxx | grep -i location

-ILs-I -L -s を 1 つにまとめた書き方です。-L でリダイレクト追従、-s で進捗とエラーの非表示、-I でヘッダーのみになります。location: の行に遷移先の URL が出ます。リダイレクトが複数回起きると、その回数だけ location: が並びます。一番下が最終的な行き先です。

5. POST と JSON:API を叩く

結論: API 送信は -X(メソッド)・-H(ヘッダー)・-d(ボディ)の 3 点セット。JSON はシングルクォートで囲む。

リナ: REST API を curl で叩きたいです。JSON はどう送ればいいですか。
ライニー先輩: API テストは curl の得意分野。-X で HTTP メソッド、-H でヘッダー、-d でボディを指定する。この 3 点セット を覚えるだけだよ。

5-1. GET(クエリパラメータ付き)

$ curl "https://api.example.com/users?id=42"

URL に ? 以降を含めるときは、必ずクォート文字列を引用符(' や ")で囲むこと。スペースなどを含む値をひとまとまりとして扱える。 します。囲まないと、シェルが & を別の意味に解釈します。

5-2. POST で JSON を送る

$ curl -X POST https://api.example.com/users \
    -H "Content-Type: application/json" \
    -d '{"name":"lina","role":"beginner"}'

3 点セットの意味

  • -X POST:HTTP メソッドの指定です。-d を付けると curl は自動で POST になります。そのため普段は書かなくても動きます
  • -H "Content-Type: application/json":「JSON を送ります」という宣言です
  • -d '...':送る本体(JSON)です。シングルクォート推奨 です。中の " をエスケープせずに済みます

5-3. Bearer トークン認証

$ curl https://api.example.com/me \
    -H "Authorization: Bearer YOUR_TOKEN_HERE"

トークンを履歴に残さない

# NG: シェル履歴・ps に丸見え
$ curl -H "Authorization: Bearer abc123..." ...

# OK: 環境変数経由
$ export API_TOKEN=abc123...
$ curl -H "Authorization: Bearer $API_TOKEN" ...

historyps でトークンが見えると事故になります。環境変数シェルやプログラムが参照する、名前と値の組み合わせで管理される設定値。~/.netrc を使ってください。

5-4. 基本認証(Basic 認証)

$ curl -u username:password https://example.com/private

-uuser:pass を渡します。HTTPS で使ってください。

6. wget の本領:堅実なダウンロード

結論: wget は保存がデフォルトでリダイレクトも自動追従。-O で名前指定、-c で中断ダウンロードを再開できる。

6-1. 基本:ファイルとして保存

$ wget https://example.com/sample.tar.gz
リナ: wget はオプションを付けなくてもファイルになるんですね。楽です。
ライニー先輩: そう、wget は 保存がデフォルト。リダイレクトも自動で追う。シンプルなダウンロードなら wget の方が事故が少ないよ。

wget は勝手に上書きしません

同じ名前のファイルがあると、wget は sample.tar.gz.1 のように 連番を足した別名 で保存します。ただし -O 名前 を付けたときは指定した名前を上書きします。ここだけ挙動が変わるので注意してください。

6-2. 名前を変えて保存 -O

$ wget -O custom.tar.gz https://example.com/sample.tar.gz

curl と wget で -O の意味が逆

  • curl の -O:URL のファイル名で保存します
  • wget の -Oファイル名を指定 して保存します(curl の -o に相当)

両方使う人は、ここで必ず一度ハマります。

6-3. 中断したダウンロードを再開 -c

$ wget -c https://example.com/big.iso

-ccontinue です。回線が切れて途中までしか落ちていないファイルを、続きから ダウンロードします。

6-4. リトライ・タイムアウト

$ wget --tries=5 --timeout=30 https://example.com/file.zip

不安定な回線でも、あきらめずに再試行する設定です。

7. 再帰ダウンロード wget -r(注意して使う)

結論: wget -r はリンクを再帰追跡する。-l で深さ、-np で範囲を必ず制限し、相手サーバへの配慮を忘れない。

$ wget -r -l 2 -np https://example.com/docs/
  • -r:再帰的にリンクをたどります
  • -l 2:階層を 2 階層までに制限します
  • -np:親ディレクトリに登りません

8. 文字化け・改行コードの罠

結論: curl/wget は生のバイト列を渡す。非 UTF-8 は iconv、Windows 由来の CRLF は tr -d '\r' で整える。

リナ: 取ってきた HTML が 譁�ュ怜喧 みたいな読めない文字だらけです。
ライニー先輩: 文字化けだね。ブラウザは文字の種類を自動で見分けて直してくれる。でも curl と wget は そのまま 渡すんだ。文字コードが UTF-8 でないページは iconv で変換すると読めるようになるよ。
リナ: 改行コードも気になります。
ライニー先輩: Windows のサーバから取ったファイルは、改行が \r\n(CRLF)のことがある。Linux で扱うなら dos2unixtr -d '\r' で除くのが定番だよ。
# Shift_JIS のページを UTF-8 に変換しながら保存
$ curl -s https://example.com/sjis.html | iconv -f SHIFT_JIS -t UTF-8 > page.html

# CRLF を LF に変換
$ curl -s https://windows-server.example/data.csv | tr -d '\r' > data.csv

>シェルのリダイレクト です。ここでも同じで、指定した名前のファイルがあれば中身を消して上書きします。大事なファイル名を書かないよう気をつけてください。

9. よくある初心者のつまずき

結論: 保存されない(-O/-o 忘れ)、リダイレクト未追従(-L 忘れ)、& の未クォートが典型的なつまずき。

9-1. curl URL で何も保存されない

原因:curl のデフォルトは「画面に出す」です。保存したいなら -O-o を付けます。

$ curl -O https://example.com/file.zip
$ curl -o my.zip https://example.com/file.zip

9-2. リダイレクト先の中身が取れない

原因-L を忘れています。

$ curl -L https://github.com/...

9-3. クエリの一部が無視される・変なエラーが出る

原因& が、シェルのバックグラウンド実行の記号として解釈されました。& の前までが curl に渡され、後ろは別の処理になります。

  • &page=2 のように = があるとき:エラーは出ません&page=2 が静かに捨てられ、結果だけが期待と違います。これが一番気づきにくいパターンです
  • &page のように = がないとき:page: command not found が出ます
# NG
$ curl https://api.example.com/search?q=linux&page=2

# OK
$ curl "https://api.example.com/search?q=linux&page=2"

9-4. SSL 証明書エラーで止まる

原因:自己署名証明書、期限切れ、社内 CA などです。

# 検証あり(推奨)
$ curl https://internal.example.com

# 検証スキップ(緊急回避のみ。本番禁止)
$ curl -k https://internal.example.com

-k検証スキップ です。通信に割り込まれる危険が上がります。本番運用では証明書を正しく整えてください。

9-5. プロキシ環境で繋がらない

$ export http_proxy=http://proxy.example.com:8080
$ export https_proxy=http://proxy.example.com:8080
$ curl https://example.com

社内環境では http_proxyhttps_proxy を設定します。

10. ミニ課題:手を動かして確かめよう

結論: httpbin.org を使い、ステータス確認・JSON POST・リダイレクト追従の 3 課題を実際に叩いて定着させる。

リナ: 知識は入りました。ターミナルで試したいです。
ライニー先輩: 3 問用意したよ。https://httpbin.org は HTTP の練習用サイト。安心して叩いていい。

練習用のからっぽのディレクトリを作り、その中で試します。こうすれば、もとからあるファイルを上書きしません。

# 練習用ディレクトリを準備して移動する
$ mkdir -p ~/curl-practice && cd ~/curl-practice
  • ~ は「自分のホームディレクトリ(自分専用の置き場)」を表す記号です
  • && は「左が成功したら、続けて右を実行する」という意味です。2 行に分けて打っても同じです

課題 1https://httpbin.org/get の HTTP ステータスコードと content-type を確認しよう。

ヒント 1(方向づけ)を見る

本文はいりません。「札」の部分だけを取るオプションがあります。

ヒント 2(コマンド名)を見る

使うコマンドは curl です。オプションは「4. ヘッダーだけ確認したい」で出てきた 1 文字です。

答えを見る
$ curl -I https://httpbin.org/get
HTTP/2 200
date: ...
content-type: application/json
...

先頭の 200 が成功を表します。content-type: application/json は、返事が JSON であることを示します。

課題 2https://httpbin.org/post に JSON {"hello":"world"} を POST しよう。

ヒント 1(方向づけ)を見る

指定するものは 3 つです。「方法」「これは JSON という宣言」「送る中身」です。

ヒント 2(コマンド名)を見る

使うコマンドは curl です。オプションは「5-2. POST で JSON を送る」で使った 3 つです。

答えを見る
$ curl -X POST https://httpbin.org/post \
    -H "Content-Type: application/json" \
    -d '{"hello":"world"}'

レスポンスの中に "json": {"hello": "world"} が見えれば成功です。

課題 3https://httpbin.org/redirect/3 のリダイレクト先を辿って、最終ページを取得しよう。

ヒント 1(方向づけ)を見る

curl は引っこしの案内を、そのままでは追いかけません。追いかけさせる指示が必要です。

ヒント 2(コマンド名)を見る

使うコマンドは curl です。オプションは「3. 初心者の最大の罠」で出てきた 1 文字、Location の頭文字です。

答えを見る
$ curl -L https://httpbin.org/redirect/3

3 回リダイレクトされたあと、/get のレスポンスが返ります。

11. コピペ用テンプレート

結論: curl は表示/保存/リダイレクト/ヘッダー/POST/認証、wget は基本DL/名前変更/再開/再帰の定番形をコピペで使える。

curl テンプレ

# 画面に表示(デバッグ)
curl URL

# 保存(URL のファイル名で。同名は上書き)
curl -O URL

# 保存(名前指定。同名は上書き)
curl -o name URL

# リダイレクト追従しつつ保存(GitHub Releases 等)
curl -LO URL

# ヘッダーだけ確認
curl -I URL

# ステータスコードだけ取得
curl -s -o /dev/null -w "%{http_code}\n" URL

# JSON を POST
curl -X POST URL \
    -H "Content-Type: application/json" \
    -d '{"key":"value"}'

# Bearer トークン
curl URL -H "Authorization: Bearer $API_TOKEN"

# 基本認証
curl -u user:pass URL

# 進捗バー付き
curl -O --progress-bar URL

wget テンプレ

# 基本ダウンロード(同名があれば連番を足す)
wget URL

# 名前を変えて保存(同名は上書き)
wget -O custom.name URL

# 中断したファイルの続き
wget -c URL

# リトライ・タイムアウト指定
wget --tries=5 --timeout=30 URL

# 静かにダウンロード(ログ最小)
wget -q URL

# 再帰ダウンロード(マナー注意)
wget -r -l 2 -np --wait=2 https://example.com/docs/

振り返り

結論: 目的で curl と wget を選び、落とす前に保存先を見て、外部サイトには -L を付ける。

リナ: 整理します。ファイルを落とすだけなら wget、API やヘッダーを見るなら curl ですね。
ライニー先輩: そのとおり。迷ったら「保存が目的か、中身を見るのが目的か」で分けるといいよ。
リナ: あと、落とす前に pwdlscurl -O は確認なしで上書きするからですね。
ライニー先輩: 完璧だね。外部サイトを curl で叩くときは -L。この 3 つを持ち帰ってくれれば十分だよ。

今日の 3 行まとめ

結論: 用途で curl と wget を選び、保存先と上書きを先に確かめ、外部サイトには -L を付ける。

  1. API やヘッダーを見るなら curl、ファイルを落とすだけなら wget を選びます
  2. 落とす前に pwdls を見ます。curl -Ocurl -o は同名ファイルを確認なしで上書きします
  3. 外部サイトを curl で叩くときは -L を付けます。リダイレクトを追いかけてくれます

まとめ:次に読む

この記事を共有

次の一手