curl/wget入門 - コマンドラインでのHTTP通信
この記事で学べること
curlとwgetの 役割の違い が腑に落ちる- ファイルダウンロード・ヘッダー確認・API アクセスの 基本コマンド が書ける
- 初心者がハマりやすい 「保存されない」「リダイレクトされない」「文字化け」 の原因が分かる
- API レスポンスの確認や HTTP ステータスの読み方が コピペで動かせる ようになる
結論(先に覚える型)
- 単発のファイルダウンロード →
wget URL - API 叩く・ヘッダー確認・POST →
curl URL - リダイレクトを追従したい →
curl -L URL - ダウンロードが途中で切れた →
wget -c URL
前提(対象環境)
- OS:Ubuntu / 一般的な Linux
curlは標準搭載が多い。wgetはsudo apt install wgetで導入- 対象は HTTP / HTTPS(curl は ftp / sftp / smtp 等も対応)
1. curl と wget の違い:まず役割を分ける
ざっくり比較
| 項目 | curl | wget |
|---|---|---|
| デフォルト動作 | 標準出力に表示 | ファイルとして保存 |
| HTTP メソッド | GET/POST/PUT/DELETE 等 | 基本 GET のみ |
| リダイレクト追従 | -L を付ける必要あり |
自動で追従 |
| 再帰ダウンロード | 苦手 | 得意(-r) |
| レジューム | -C - で対応 |
-c で対応 |
| 用途 | API 叩く・デバッグ・POST | サイト丸ごとミラー・DL |
迷ったら:API・ヘッダー・POST が絡むなら curl、ファイル落とすだけなら wget。
2. curl の基本:まず画面に出す
2-1. URL を叩いて結果を画面に出す
$ curl https://example.com
<!doctype html>
<html>
<head>
<title>Example Domain</title>
...
-o(名前指定)か -O(URL のファイル名を使う)を付ける。2-2. 名前を指定して保存 -o
$ curl -o page.html https://example.com
-o は output(出力)の頭文字。小文字の 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. ダウンロード進捗を見たい
$ curl -O --progress-bar https://example.com/big.iso
--progress-bar でシンプルな進捗バーが出る。長時間ダウンロードで安心。
3. 初心者の最大の罠:リダイレクト -L
https://github.com/torvalds/linux を curl で取ってみたんですけど、中身が変なんです...-L を付ける とリダイレクトを追従するようになる。3-1. リダイレクトを追従する -L
# NG: リダイレクトされた案内が返るだけ $ curl https://github.com/torvalds/linux # OK: 最終ページの内容を取得 $ curl -L https://github.com/torvalds/linux
-L は Location(HTTP の Location ヘッダー)の頭文字。
型として覚える
- 外部サイトを curl で叩くときは 常に
-Lを付ける と事故が減る - ファイルダウンロードでも
-L必須のケースが多い(GitHub Releases 等)
# 安全な定番形 $ curl -LO https://github.com/some/repo/releases/download/v1.0/binary.tar.gz
4. ヘッダーだけ確認したい -I
「リンク先は生きてる?」「リダイレクト先はどこ?」を 本文をダウンロードせずに 確認できる。
$ 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 ステータス 早見表
| コード | 意味 | 状況 |
|---|---|---|
2xx |
成功 | 200 OK、204 No Content |
3xx |
リダイレクト | 301(恒久)、302(一時) |
4xx |
クライアント側 | 404(無い)、401/403(権限) |
5xx |
サーバー側 | 500(バグ)、503(過負荷) |
4-1. リダイレクト先を辿る
$ curl -ILs https://bit.ly/3xxxxx | grep -i location
-L でリダイレクト追従、-s で進捗非表示、-I でヘッダーのみ。location: 行で遷移先 URL が分かる。
5. POST と JSON:API を叩く
-X で HTTP メソッド、-H でヘッダー、-d でボディを指定する。JSON を送るなら 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を使うと省略可だが明示が安全)-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" ...
history や ps でトークンが見えると事故。環境変数か ~/.netrc を使う。
5-4. 基本認証(Basic 認証)
$ curl -u username:password https://example.com/private
-u で user:pass を渡す。HTTPS 必須。
6. wget の本領:堅実なダウンロード
6-1. 基本:ファイルとして保存
$ wget https://example.com/sample.tar.gz
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
-c は continue。回線が切れて途中までしか落ちてないファイルの 続きから ダウンロードする。
6-4. リトライ・タイムアウト
$ wget --tries=5 --timeout=30 https://example.com/file.zip
不安定な回線でも諦めず再試行する設定。
7. 再帰ダウンロード wget -r(注意して使う)
$ wget -r -l 2 -np https://example.com/docs/
-r:再帰的にリンクをたどる-l 2:階層を 2 階層までに制限-np:親ディレクトリに登らない
やってはいけないこと
- 上限を付けずに
-rだけで実行 → サイト全体を吸い出してしまう - 短い間隔で大量アクセス → 相手サーバへの DoS と見なされる
robots.txtを無視 → 規約違反
--wait=2 で間隔を空ける、対象範囲を URL レベルで限定する、相手の利用規約を確認するなど、マナーを守る。
8. 文字化け・改行コードの罠
< とか変な記号だらけで読めません。iconv で変換するか、jq などの専用ツールを通すと解決する。\r\n(CRLF)になることがある。Linux で扱うなら dos2unix か tr -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. よくある初心者のつまずき
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. クエリ文字列が bash: 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_proxy / https_proxy を設定する。
10. ミニ課題:手を動かして確かめよう
https://httpbin.org は HTTP リクエスト確認用の練習サイト。安心して叩いていい。課題 1:https://httpbin.org/get の HTTP ステータスコードと content-type を確認しよう。
ヒントを見る
ヘッダーだけ取るオプションがあった。
解答例
$ curl -I https://httpbin.org/get
HTTP/2 200 date: ... content-type: application/json ...
課題 2:https://httpbin.org/post に JSON {"hello":"world"} を POST しよう。
ヒントを見る
-X POST / -H / -d の 3 点セット。
解答例
$ curl -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-d '{"hello":"world"}'レスポンス内の "json": {"hello": "world"} が確認できれば成功。
課題 3:https://httpbin.org/redirect/3 のリダイレクト先を辿って、最終ページを取得しよう。
ヒントを見る
リダイレクトを追従するオプションが必要。
解答例
$ curl -L https://httpbin.org/redirect/3
3 回リダイレクトされた末の /get のレスポンスが返る。
11. コピペ用テンプレート
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 URLwget テンプレ
# 基本ダウンロード 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/