curlコマンドでファイルをダウンロード・アップロードする方法


curlコマンド完全ガイド: ファイルのダウンロードとアップロードをマスターする

curlは、多くの開発者やシステム管理者にとって、日々の業務に欠かせない強力なツールです。コマンドラインからウェブサイトのコンテンツを取得したり、APIと対話したり、ファイルを転送したりと、その用途は多岐にわたります。しかし、その多機能さゆえに、すべてのオプションを使いこなすのは難しいと感じるかもしれません。

この記事では、「スイスアーミーナイフ」とも称されるcurlコマンドの核心的な機能である、ファイルのダウンロードとアップロードに焦点を当て、基本的な使い方から高度なテクニック、さらには実践的なスクリプト例まで、約5000語にわたって徹底的に解説します。

1. curlとは何か? なぜ重要なのか?

curl(「カール」と読みます)は、URLシンタックスを用いてデータを転送するためのコマンドラインツールおよびライブラリ(libcurl)です。その最大の特徴は、驚くほど多くのプロトコルをサポートしている点にあります。

  • サポートプロトコルの例:
    • HTTP, HTTPS
    • FTP, FTPS
    • SFTP, SCP
    • SMTP, SMTPS
    • IMAP, POP3
    • LDAP
    • SMB, SMT
    • …その他多数

この多様性により、curlは単なる「ウェブサイトダウンローダー」にはとどまりません。ウェブサーバーのデバッグ、REST APIのテスト、ファイルの自動アップロード、メールの送信など、ネットワークに関わるあらゆるデータ転送タスクの自動化とスクリプティングにおいて中心的な役割を果たします。

この記事を読み終える頃には、あなたはcurlを使って以下のことができるようになっているでしょう。

  • Web上のファイルを様々な方法でダウンロードする。
  • ダウンロードを中断・再開する。
  • 認証が必要なサーバーからデータを取得する。
  • フォームデータやファイルをサーバーにアップロードする。
  • APIと対話し、JSONデータを送受信する。
  • エラーハンドリングやリトライを含む堅牢なスクリプトを作成する。

それでは、curlの広大な世界の探求を始めましょう。

2. curlの基本: ファイルのダウンロード

curlの最も基本的な用途は、指定したURLからリソースをダウンロードすることです。

2.1. 最もシンプルなダウンロード: 標準出力へ

curlコマンドにURLを渡すだけで、そのURLのコンテンツを取得できます。

bash
curl https://example.com

このコマンドを実行すると、https://example.comのHTMLソースコードがターミナルの画面(標準出力)に直接表示されます。これはcurlのデフォルトの動作です。ファイルには何も保存されません。

この挙動は、他のコマンドとパイプライン(|)で繋ぐ際に非常に便利です。例えば、取得したHTMLから特定の文字列(例: titleタグ)を検索したい場合、grepと組み合わせることができます。

bash
curl -s https://example.com | grep -i "<title>"

(補足: -s (–silent) オプションは、プログレスメーターやエラーメッセージを非表示にし、純粋なデータのみを出力させたい場合に便利です)

2.2. ファイルに保存する: -o-O

コンテンツを画面に表示するだけでなく、ファイルとして保存したい場合がほとんどでしょう。そのためにcurlは2つの主要なオプションを提供しています。

a) -o (–output): ファイル名を指定して保存

-oオプションを使うと、保存するファイル名を明示的に指定できます。

“`bash

example.com の内容を page.html という名前で保存

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

リモートにある画像を my_image.jpg という名前で保存

curl -o my_image.jpg https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png
“`

このオプションは非常に柔軟で、パスを含めて保存場所を指定することも可能です。

“`bash

downloads ディレクトリに logo.png として保存(ディレクトリは事前に存在している必要があります)

curl -o downloads/logo.png https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png
“`

もし指定したファイルが既に存在する場合、-oは警告なしにそのファイルを上書きします。注意してください。

b) -O (–remote-name): URLのファイル名で保存

-Oオプションは、URLのパス部分からファイル名を自動的に抽出し、その名前でカレントディレクトリに保存します。

“`bash

URLの末尾にある googlelogo_color_272x92dp.png という名前で保存される

curl -O https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png
“`

このコマンドを実行すると、カレントディレクトリにgooglelogo_color_272x92dp.pngというファイルが作成されます。

-Oは、ダウンロードしたいファイルのURLが明確な場合に非常に便利で、タイピングの手間を省いてくれます。しかし、URLがファイル名で終わっていない場合(例: https://example.com/https://api.service.com/users/123)は、ファイル名を抽出できないためエラーになります。

c) -o-O の使い分け

  • -o を使う場面:

    • 保存するファイル名を自分で決めたいとき。
    • 特定のディレクトリに保存したいとき。
    • URLに明確なファイル名が含まれていないとき。
    • 元のファイル名が長すぎたり、分かりにくかったりするとき。
  • -O を使う場面:

    • 元のファイル名のまま保存したいとき。
    • スクリプトで複数のファイルを一括ダウンロードするとき。

2.3. 複数のファイルを一度にダウンロード

curlでは、複数の-Oオプションを並べることで、一度に複数のファイルをダウンロードできます。

bash
curl -O https://example.com/file1.zip -O https://example.com/file2.zip

また、ブレース展開({})を使えば、似たようなURLのリストを簡単に生成できます。

“`bash

file1.txt, file2.txt, file3.txt をダウンロード

curl -O https://example.com/files/file{1,2,3}.txt

01から10までの連番画像をダウンロード

curl -O https://example.com/images/img_[01-10].jpg
“`

もしダウンロードしたいURLがファイルにリストアップされている場合は、xargsと組み合わせるのが一般的です。

“`bash

urls.txt の内容:

https://example.com/file1.zip

https://example.com/file2.zip

https://example.com/file3.zip

cat urls.txt | xargs -n 1 curl -O
“`

3. ダウンロードをマスターする: 高度なテクニック

基本的なダウンロード方法を学んだところで、より現実的なシナリオに対応するための高度なテクニックを見ていきましょう。

3.1. リダイレクトへの対応: -L

現代のWebサイトでは、HTTPリダイレクトが頻繁に使用されます。例えば、http://からhttps://へのリダイレクト、ドメイン名の変更(old-domain.com -> new-domain.com)、短縮URLサービスなどです。

curlのデフォルトの動作では、リダイレクトを追いかけません。リダイレクト元のサーバーから「別の場所に行ってください」という指示(HTTPステータスコード 3xx)を受け取ると、そのヘッダー情報を表示して処理を終了してしまいます。

“`bash

短縮URLをそのまま叩くと、リダイレクト先の内容は表示されない

curl http://t.co/U14i2aJdBH

出力例:

“`

ここで-L (--location) オプションの出番です。このオプションを付けると、curlはリダイレクト先のURLを自動的に追跡し、最終的なコンテンツを取得してくれます。

“`bash

-L を付けると、リダイレクトを追いかけ、最終的な curl.se のコンテンツを取得する

curl -L http://t.co/U14i2aJdBH
“`

ほとんどの場合、Webサイトからファイルをダウンロードする際には-Lを付けておくのが安全策と言えるでしょう。

セキュリティ上の観点から、無限リダイレクトループを防ぐため、curlが追跡するリダイレクトの最大数はデフォルトで50回に設定されています。この回数は--max-redirs <num>オプションで変更できます。

3.2. ダウンロードの中断と再開: -C -

巨大なファイルをダウンロードしている最中に、ネットワーク接続が切れてしまったり、誤ってコマンドを中断してしまったりした経験はありませんか? -C (--continue-at) オプションは、そんな絶望的な状況を救ってくれます。

このオプションは、ダウンロードを途中から再開(レジューム)する機能を提供します。

最も一般的な使い方は -C - です。ハイフン(-)を付けることで、curlは出力ファイル(-oまたは-Oで指定したファイル)のサイズを自動的に検出し、その続きからダウンロードを再開しようと試みます。

“`bash

1. 巨大なファイルのダウンロードを開始

curl -O https://releases.ubuntu.com/22.04.1/ubuntu-22.04.1-desktop-amd64.iso

…ダウンロード途中で Ctrl+C を押して中断…

2. 同じコマンドに -C – を付けて再実行すると、続きから再開される

curl -C – -O https://releases.ubuntu.com/22.04.1/ubuntu-22.04.1-desktop-amd64.iso
“`

重要: この機能が動作するためには、サーバー側がHTTP Rangeリクエストをサポートしている必要があります。ほとんどのモダンなWebサーバーはこれをサポートしていますが、サポートしていないサーバーに対して-C -を使用しても、ダウンロードは最初からやり直されます。

3.3. 進行状況の表示: プログレスバー

curlをインタラクティブに実行すると(つまり、出力をファイルやパイプにリダイレクトしていない場合)、デフォルトで以下のようなプログレスメーターが表示されます。

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1256 100 1256 0 0 4346 0 --:--:-- --:--:-- --:--:-- 4346

各項目の意味は以下の通りです。
* % Total: 総ダウンロード(またはアップロード)サイズに対する現在の進捗率。
* % Received: 受信データの進捗率。
* % Xferd: 転送(送信)データの進捗率。
* Average Speed Dload/Upload: 平均ダウンロード/アップロード速度。
* Time Total: 転送完了までの推定時間。
* Time Spent: 経過時間。
* Time Left: 残り時間。
* Current Speed: 現在の転送速度。

この詳細なメーターは情報量が多いですが、スクリプトのログなどには冗長すぎることがあります。表示をコントロールするためのオプションがいくつかあります。

  • -s (--silent): サイレントモード
    プログレスメーターとエラーメッセージをすべて非表示にします。純粋なデータだけが必要なスクリプトで非常に役立ちます。

  • -# (--progress-bar): シンプルなプログレスバー
    詳細なメーターの代わりに、シンプルなハッシュ(#)のプログレスバーを表示します。ダウンロードの進捗を視覚的に把握したいが、画面をスッキリさせたい場合に最適です。

“`bash

シンプルなプログレスバーを表示してダウンロード

curl -# -O https://example.com/large-file.zip

################################################################## 100.0%

“`

TIPS: -s-#は組み合わせて使えません。しかし、エラーメッセージは表示しつつ、プログレスバーだけを消したい場合は -sS という組み合わせが使えます。-S-s で抑制されたエラーメッセージを再度有効にするオプションです。

3.4. ヘッダー情報の表示と操作

HTTP通信は、ボディ(HTMLや画像などの本体データ)だけでなく、ヘッダー(メタデータ)も送受信しています。curlはこれらのヘッダーを柔軟に扱うことができます。

  • -I (--head): レスポンスヘッダーのみ表示
    HEADリクエストをサーバーに送信し、ボディは受信せず、レスポンスヘッダーだけを取得します。ファイルの存在確認や、最終更新日時、コンテントタイプなどを素早く確認したい場合に便利です。

bash
curl -I https://example.com

  • -v (--verbose): 詳細な通信情報を表示
    リクエストヘッダー、レスポンスヘッダー、SSLハンドシェイクの過程など、curlが行うすべての通信の詳細を表示します。APIのデバッグや接続問題のトラブルシューティングに不可欠なオプションです。

bash
curl -v https://example.com

  • -H (--header): カスタムリクエストヘッダーの送信
    APIを利用する際など、特定のリクエストヘッダーを送信する必要がある場合があります。-Hオプションを使えば、任意のヘッダーを追加できます。

    例1: User-Agentを偽装する
    サーバーによっては、User-Agent(どのクライアントがアクセスしているかを示す文字列)によって応答を変えることがあります。

    bash
    curl -H "User-Agent: MyAwesomeBrowser/1.0" https://httpbin.org/user-agent

    例2: APIキーをヘッダーで送信する
    多くのREST APIでは、認証情報をヘッダーに含めて送信します。

    bash
    curl -H "Authorization: Bearer YOUR_API_TOKEN" https://api.example.com/data

4. 認証が必要なサイトからのダウンロード

パスワードで保護されたリソースにアクセスする必要がある場合も、curlは対応できます。

4.1. ベーシック認証: -u

ベーシック認証は、ユーザー名とパスワードを使う最もシンプルなHTTP認証方式です。-u (--user) オプションで認証情報を指定します。

bash
curl -u username:password -L -O https://protected.example.com/secret-file.zip

セキュリティ上、コマンドラインに直接パスワードを記述するのは好ましくありません。コマンド履歴に残ってしまうからです。パスワード部分を省略すると、curlが安全なプロンプトでパスワードの入力を求めてきます。

bash
curl -u username -L -O https://protected.example.com/secret-file.zip
Enter host password for user 'username':

4.2. .netrc ファイルを使った認証情報の管理

複数の認証が必要なサイトを頻繁に利用する場合、毎回ユーザー名とパスワードを入力するのは面倒です。そこで .netrc ファイルが役立ちます。

ホームディレクトリに .netrc という名前のファイルを作成し、以下のような形式で認証情報を記述します。

machine protected.example.com
login username
password mysecretpassword

このファイルを保存した後、非常に重要なこととして、パーミッションを所有者のみが読み書きできるように設定します。

bash
chmod 600 ~/.netrc

パーミッションが適切に設定されていれば、curl-n (--netrc) オプションを付けることで、このファイルから自動的に認証情報を読み込んで使用します。

“`bash

-u を指定しなくても、.netrc から情報を読み込んで認証してくれる

curl -n -L -O https://protected.example.com/secret-file.zip
“`

4.3. フォームベース認証とCookie

Webサイトのログインの多くは、ベーシック認証ではなく、ログインフォームとCookieを使ったセッション管理によって行われます。curlでこのようなサイトからファイルをダウンロードするには、以下の2ステップのプロセスが必要です。

  1. ログイン: ログインフォームにユーザー名とパスワードをPOSTリクエストで送信し、サーバーからセッションCookieを受け取って保存する。
  2. ダウンロード: 保存したCookieを使って認証済みセッションを維持し、目的のファイルをダウンロードする。

このプロセスで鍵となるのが、Cookieを扱うためのオプションです。

  • -c (--cookie-jar <filename>): サーバーからのレスポンスに含まれるCookieをファイルに保存します。
  • -b (--cookie <data|filename>): 指定したデータまたはファイルからCookieを読み込み、リクエストヘッダーに含めて送信します。

実践例:

“`bash

1. ログインして、Cookieを cookie.txt に保存する

–data でフォームのパラメータを送信

curl -L -c cookie.txt \
–data “username=myuser&password=mypass” \
https://example.com/login

2. 保存した cookie.txt を使って、認証が必要なページからファイルをダウンロード

curl -L -b cookie.txt \
-O https://example.com/members-only/document.pdf
“`

このテクニックは、Webスクレイピングや自動化タスクにおいて非常に強力です。

5. curlによるファイルのアップロード

curlはダウンロードだけでなく、ファイルのアップロードにも広く使われます。主にHTTPのPOSTメソッドやPUTメソッドが利用されます。

5.1. フォームデータのアップロード: -F

Webページで「ファイルを選択」ボタンを押してファイルをアップロードする際、ブラウザはContent-Type: multipart/form-dataという形式でデータを送信します。curlでこれを模倣するのが-F (--form) オプションです。

-F"name=value" の形式でフィールドを指定します。ファイルをアップロードするには、値の先頭に @ 記号を付けます。

例1: テキストファイル report.txt をアップロードする

“`bash

file_field という名前のフォームフィールドに、report.txt を添付してアップロード

curl -F “file_field=@/path/to/report.txt” https://api.example.com/upload
``@は「この後の文字列はファイルパスなので、その内容を読み込んでデータとして使え」というcurl`への指示です。

例2: ファイルと他のテキストデータを同時に送信する

“`bash

user_iddescription というテキストフィールドも一緒に送信

curl -F “user_id=123” \
-F “description=This is a monthly report.” \
-F “report_file=@/path/to/report.txt” \
https://api.example.com/upload
“`

-Fオプションを使うと、curlは適切なContent-Typeヘッダー(multipart/form-dataと、その境界を示すboundary)を自動的に生成してくれます。

さらに、アップロードする際のファイル名やコンテントタイプを明示的に指定することも可能です。

“`bash

ローカルのファイル名は local.txt だが、サーバーには server_name.txt として送信

MIMEタイプも text/plain と明示

curl -F “file=@/path/to/local.txt;filename=server_name.txt;type=text/plain” https://api.example.com/upload
“`

5.2. PUTメソッドによるアップロード: -T

RESTfulなAPIやWebDAVサーバーなどでは、リソースの作成や置換のためにHTTP PUTメソッドが使われます。curlPUTを使ってファイルをアップロードする最も簡単な方法は、-T (--upload-file) オプションです。

“`bash

ローカルの file.txt の内容を、サーバー上の /uploads/remote_file.txt として作成・置換する

curl -T /path/to/local/file.txt https://api.example.com/uploads/remote_file.txt
“`

-Tは、指定したローカルファイルの内容をそのままリクエストのボディとして送信し、リクエストメソッドを自動的にPUTに設定します。

このオプションはHTTPだけでなく、FTPやSFTPサーバーへのアップロードにも利用できます。

“`bash

FTPサーバーにアップロード

curl -T local.zip ftp://user:[email protected]/remote/

SFTPサーバーにアップロード(curlがlibssh2と共にビルドされている必要がある)

curl -T local.zip sftp://user:[email protected]/home/user/
“`

5.3. 生データをPOSTする: -d

-d (--data) オプションは、Content-Type: application/x-www-form-urlencoded という形式でデータをPOSTするために使われます。これは、HTMLの単純なフォーム(ファイルアップロードを含まない)が送信する形式と同じです。

“`bash

key1=value1&key2=value2 というデータをPOSTする

curl -d “key1=value1&key2=value2” https://api.example.com/form
“`

-Fとの主な違いは、-dmultipart/form-dataを扱えない、つまりバイナリファイルのアップロードには適していない点です。

しかし、-d@と組み合わせることで、ファイルの内容をデータとして送信できます。これは、JSONファイルの内容をAPIにPOSTするような場合に非常に便利です。

JSON APIとの連携例:

data.jsonファイル:
json
{
"name": "Taro Yamada",
"email": "[email protected]"
}

コマンド:
“`bash

data.json の内容をリクエストボディとしてPOSTする

Content-Typeヘッダーを明示的に指定するのが一般的

curl -X POST \
-H “Content-Type: application/json” \
-d @/path/to/data.json \
https://api.example.com/users
``
*(補足:
-X POSTは明示的にPOSTメソッドを指定するオプション。-d`を使うとデフォルトでPOSTになるため、この場合は省略可能ですが、可読性のために付けるのが良い習慣です。)*

6. 実践的なスクリプティングと応用例

curlの真価は、シェルスクリプトに組み込んでタスクを自動化する際に発揮されます。

6.1. エラーハンドリング

スクリプトを堅牢にするには、エラーハンドリングが不可欠です。

  • 終了コードの確認:
    curlは成功すると終了コード0を返します。失敗した場合は非ゼロのコードを返します。スクリプトでは$?で直前のコマンドの終了コードを確認できます。

  • --fail オプション:
    curlはサーバーから404 (Not Found) や 500 (Internal Server Error) といったHTTPエラーが返された場合でも、通信自体は成功したとみなし、終了コード0を返すことがあります。
    --fail (または -f) オプションを付けると、このようなHTTPエラー(4xx, 5xx)を受け取った場合に、curlは何も出力せず、終了コード22で失敗するようになります。これにより、スクリプトでエラーを簡単に検知できます。

    “`bash

    !/bin/bash

    curl -f -O https://example.com/non-existent-file.zip

    if [ $? -ne 0 ]; then
    echo “ダウンロードに失敗しました。”
    exit 1
    fi

    echo “ダウンロードに成功しました。”
    “`

  • リトライ処理:
    ネットワークは不安定なものです。一時的なエラーで処理が失敗することはよくあります。curlにはリトライ機能が組み込まれています。

    • --retry <num>: 失敗した場合にリトライする最大回数。
    • --retry-delay <seconds>: リトライするまでの待機時間(デフォルトは1秒)。
    • --retry-max-time <seconds>: リトライ処理を続ける最大時間。

    “`bash

    接続エラーなどが起きた場合、5秒間隔で最大3回リトライする

    curl –retry 3 –retry-delay 5 -O https://example.com/large-file.zip
    “`

6.2. 速度制限: --limit-rate

スクリプトで大量のファイルをダウンロード・アップロードする際、ネットワーク帯域をすべて使い果たしてしまうと、他の作業に支障が出ることがあります。--limit-rateオプションで転送速度を制限できます。

“`bash

ダウンロード速度を 1MB/s に制限する

curl –limit-rate 1M -O https://example.com/very-large-file.iso
``
単位は
k(キロバイト),M(メガバイト),G` (ギガバイト) が使えます。

6.3. プロキシ経由での利用: -x

会社のネットワークなど、プロキシサーバーを経由しないと外部にアクセスできない環境では、-x (--proxy) オプションを使います。

“`bash

プロキシサーバーを指定してアクセス

curl -x http://proxy.example.com:8080 https://google.com

プロキシが認証を要求する場合

curl -x http://proxy.example.com:8080 –proxy-user user:pass https://google.com
“`

また、http_proxyhttps_proxyといった環境変数を設定しておけば、curlは自動的にそのプロキシを利用します。

6.4. 組み合わせ技: Web APIからデータを取得してjqで処理する

curlは、JSONを返すWeb APIとの連携で特に強力です。取得したJSONデータを、コマンドラインJSONプロセッサーであるjqと組み合わせることで、欲しい情報だけを簡単に抽出できます。

例: GitHub APIからcurlリポジトリの情報を取得し、説明文だけを抜き出す

“`bash

-s でプログレスバーを消し、パイプでjqに渡す

jqの ‘.description’ で、JSONオブジェクトのdescriptionキーの値を取得する

curl -s https://api.github.com/repos/curl/curl | jq ‘.description’

出力:

“A command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features”

“`

この「curl + jq」の組み合わせは、APIを扱う開発者にとっての定番テクニックです。

7. まとめ

この記事では、curlを使ったファイルのダウンロードとアップロードについて、基本的なコマンドから始まり、リダイレクト、再開、認証、さまざまなアップロード方法、そしてスクリプティングにおける実践的なテクニックまで、幅広くカバーしました。

最後に、この記事で学んだ重要なポイントを振り返ってみましょう。

  • ダウンロード:

    • 基本はcurl [URL]。標準出力に表示される。
    • ファイルに保存するには-o new_name.txt(名前指定)か-O(URLのまま)。
    • リダイレクトを追跡するには-Lが必須。
    • 巨大なファイルのダウンロードは-C -で中断・再開できる。
    • 進捗表示は-#でシンプルに、-sで非表示に。
  • アップロード:

    • ファイル付きフォームの送信は-F "file=@/path/to/file"
    • PUTメソッドでのアップロードは-T local_file
    • JSON APIなどへのデータ送信は-d @data.json-H "Content-Type: application/json"の組み合わせが強力。
  • 認証とスクリプティング:

    • ベーシック認証は-u user:passまたは安全な-u user
    • フォーム認証は-cでCookieを保存し、-bで利用する。
    • スクリプトでは--failでHTTPエラーを検知し、--retryで堅牢性を高める。

curlは、単にファイルを転送するだけのツールではありません。それは、コマンドラインというインターフェースを通じて、インターネットそのものと対話するための、非常に表現力豊かで強力な言語です。今回紹介した機能は、curlの持つ能力のほんの一部に過ぎません。

さらに深く学びたい方は、公式ドキュメント(man curl)や、curlの作者であるDaniel Stenberg氏によるオンラインブック「Everything curl」を参照することをお勧めします。

このガイドが、あなたのcurlマスターへの道のりの一助となれば幸いです。Happy curling

コメントする

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

上部へスクロール