どちらもHTTP経由でデータを取得する2つのコマンドラインツールは、ほぼすべてのマシンにインストールされており、絶えず比較されているものの、有意義な形で区別されることはめったにない。
この違いについて最も信頼できる情報源は、嬉しいことに、curlのメンテナンス担当者が公開している比較資料である。この資料には、wgetがcurlよりも優れている点について明確に解説したセクションが含まれている。 以下の事実に基づく主張はすべて、誰かの主観的な印象ではなく、その文書や各プロジェクトの公式マニュアルに裏付けられています。これは、記憶頼りで書かれることが多い比較記事においては重要な点です。
私たちは Geonode であり、プロキシを販売していますが、率直な所感としては一言で済みます:どちらのツールも、ユーザーがそれらを利用する目的の大部分において、プロキシを必要としません。 ファイルの取得、APIの呼び出し、サービスが応答するかどうかを確認すること――これらはいずれもプロキシを必要としません。 プロキシのサポートに関しては、両者に実在するもののあまり文書化されていない違いがあり、それについては後述しますが、ダウンロードツールの選択を目的にここを訪れたのであれば、安心して無視して構いません。
要約すると、これらのツールは異なる思考モデルに基づいて構築されており、表面上の違いのほとんどはそこから派生しています。curl は cat のように動作します — 何かを取得して標準出力に書き出します。wget は cp のように動作します — 何かを取得してファイルに書き出します。 これはメンテナー自身の枠組みですが、これを理解すれば、リダイレクトのデフォルト設定、フラグの違い、再帰機能などが、もはや恣意的なものではなくなります。
詳細に入る前に、簡単にまとめると:ディスクにファイルを保存したい場合は wget を、それ以外は curl を使用してください。
一文で表す違い
curl は、そのメンテナンス担当者の言葉を借りれば、「従来の Unix の cat
コマンドのように」動作します。一方、wget は「cp
のように」動作します。
この一点の違いが、以下で説明する内容の大部分を説明しています。
実用上の意味
curl https://example.com/file.txt # prints the contents to your terminal
wget https://example.com/file.txt # saves file.txt to the current directory
どちらも間違っているわけではありません。それぞれが異なる問いに応えているのです。
curl の設計は、ユーザーがデータを取得したいと想定しており、その後に何が起こるかはユーザー次第――パイプで渡す、解析する、リダイレクトする、読み込む――としています。 標準出力への書き込みは、他の処理と組み合わせやすい選択肢であり、それがcurlがシェルパイプラインに自然に組み込まれる理由です。
wgetの設計は、ユーザーがファイルを欲しがっていると想定しています。wgetはファイル名を選択し、ファイルを作成し、進行状況バーを表示し、最終的にディスク上に何かを残して処理を完了します。
なぜその影響は見た目以上に大きいのか
ツールの役割が「ファイルをディスクに保存する」ことになると、一連の挙動が明らかに正しいものとなります。ファイルが移動したためリダイレクトに従うこと、目的は試行そのものではなくファイルそのものであるため失敗時に再試行すること、ファイルの半分だけでは目的が達成されないため、中断したダウンロードを再開することなどです。wgetはこれらすべてをデフォルトで行います。
一方、ツールの役割が「この転送を実行し、結果を返す」となると、正しい動作は異なります。つまり、ユーザーに代わって判断するのではなく、何が起きたかを報告し、求められたことを正確に実行し、残りの処理は呼び出し元に任せることです。curlはリダイレクトを報告して停止します。なぜなら、リダイレクトに従うことはユーザーが求めたことではないからです。
どちらのデフォルト設定も、他より優れているわけではありません。 これらはそれぞれ異なる目的に沿った一貫性を持っており、どちらのツールに対しても人々が感じる不満の多くは、もう一方のツールの前提を期待してしまうことに起因しています。
wgetにはなくcurlにはある機能
メンテナンス担当者の比較によると、そのリストはかなり充実しています。
まずはライブラリである
curlにはlibcurlが同梱されており、これは「誰もが利用できる安定したAPI」を備えていると説明されています。 これが最も重要な違いであり、ターミナル上からは最も目立ちにくい点でもあります。
libcurlは、言語バインディング、アプリケーション、デバイスなど、膨大な数のソフトウェアに組み込まれています。コマンドラインツールは、ある意味ではこのライブラリの実演版と言えます。wgetは単なるプログラムですが、curlは他のプログラムが利用するライブラリの上に構築されたプログラムなのです。
PHPのcURL関数や、libcurlを基盤とした言語のHTTPバインディングを使用したことがあるなら、curlを実行せずにcurlを利用していたことになります。
はるかに多くのプロトコル
公開されているリストは長い:「FTP(S)、GOPHER(S)、HTTP(S)、SCP、SFTP、TFTP、TELNET、DICT、LDAP(S)、 MQTT、FILE、POP3(S)、IMAP(S)、SMB(S)、SMTP(S)、RTMP、RTSP、WS(S)」
wgetはHTTP、HTTPS、FTPに対応しています。Web利用においては、通常これだけで十分です。 メールプロトコル、SFTP、MQTT、またはWebSocketが関わるものについては、ここで取り上げている2つのツールのうち、curlだけが対応しています。
新しいバージョンのHTTP
curlはHTTP 0.9、1.0、1.1、2、および3をサポートしています。 特にHTTP/2やHTTP/3でのサーバーの挙動をテストする必要がある場合は、curlが適しています。
その他のプロキシの種類
curlは、HTTPSプロキシ、SOCKS4プロキシ、およびSOCKS5プロキシをサポートしています。 これは、wgetにはなくcurlにのみ備わっている機能の一つであり、実際の運用において重要な意味を持ちます。詳細は以下のプロキシのセクションを参照してください。
並列転送
curlは、-Zオプションを使用して、複数の転送を同時に実行できます。小さなリソースを多数取得する場合で、1つずつ処理することによる遅延が大きな問題となる際に役立ちます。
双方向転送とフォームのアップロード
データの受信だけでなく、送信も可能です。マルチパート形式のフォームアップロード、PUT、任意のメソッドに対応しています。wgetは基本的に取得ツールですが、curlは転送ツールであり、アップロードも主要な機能の一つです。
より多くのマシンにプリインストールされている
curlはmacOSおよびWindows 10、11にプリインストールされています。何も追加されていないWindowsマシンでは、curlは利用可能ですが、wgetは一般的に利用できません。これは、クロスプラットフォームのスクリプトにおいて、本来あるべき以上に重要な問題となっています。
wgetにあってcurlにない機能
これもcurlのメンテナンス担当者自身によるもので、だからこそこのリストは信頼に値するのです。
再帰的ダウンロード
「curlと比較してwgetの最大の強みは、再帰的にダウンロードできる点です。」
これは非常に重要な点であり、決して些細な機能ではありません。wgetはページ内のリンクを辿り、指定された深さまで見つけたコンテンツをダウンロードすることができ、その過程でローカル閲覧用にリンクを変換します。ドキュメントサイトをミラーリングしてオフラインで読むのも、たった1つのコマンドで可能です。
wget -r -np -k -p https://example.com/docs/
再帰的、親ディレクトリの制限なし、ローカル閲覧用にリンクを変換、画像やスタイルシートなどのページに必要な要素も取得。
curlにはこれが全くできません。 curlは指定されたURLを取得するだけです。HTMLを解析せず、リンクを発見せず、サイトという概念もありません。 もし「Webサイトのこのセクションをコピーする」という作業であれば、wgetが最適な選択肢であり、試す価値のあるcurlの代替手段は存在しません。
中断された転送の再開
wgetは「途中で中断された転送から回復し、ダウンロードを再開できる」ものです。-cを指定すれば、中断されたダウンロードは停止した箇所から再開されます。
curl でも -C - を使用すれば同様の処理が可能ですが、wget の再試行や再開に関する動作はより自動的かつ寛容です。これは、転送量が大きく、接続が不安定な場合に重要になります。
一般的なケースではオプションが不要
wgetはフラグなしでファイルをダウンロードします。一方、curlでは、ターミナルではなくファイルに書き込むために「-o または -O」が必要です。
どちらのツールでも最も頻繁に行われるタスク、つまり「このファイルをダウンロードする」という点において、wgetの方がコマンドが短く、毎日使用するツールとしては、これが大きな利点となります。
ダウンロードに関する、より合理的なデフォルト設定
wgetは「デフォルトでより多くの機能を有効にしています:クッキー、リダイレクトの追跡、タイムスタンプ」。
特にタイムスタンプについては注目に値します。-Nを指定すると、wgetはリモート側のバージョンが新しい場合にのみファイルを再ダウンロードします。 一連のファイルの定期的な同期を行う場合、これはまさに理想的な動作であり、curlにはこれに直接相当する機能はありません。
ライセンス
wgetはGPL v3、curlはMITライセンスです。いずれかを製品に組み込む場合、この違いは、このページで紹介されているどの機能よりも重要になる可能性が高いでしょう。
時間を浪費させるデフォルト設定
午後の作業を混乱させる可能性が最も高い違い。
リダイレクト
wget はデフォルトでリダイレクトを追跡しますが、curl は追跡しません。
これが、「なぜ curl は何も返さなかったのか」という疑問の最も一般的な原因です。サーバーが 301 レスポンスを返すと、curl はそれを報告して処理を停止し、標準出力は空に見えます。
curl -L https://example.com/moved # follow them
wget https://example.com/moved # already following them
これは curl の不備ではありません。リダイレクトに従うということは、要求していないホストに対して、要求していないリクエストを行うことを意味します。curl の動作モデルは、指示されたことを実行し、それ以外のことは報告しないというものです。一方、wget の動作モデルはファイルを取得することであり、そのファイルは移動してしまっていたのです。
出力の保存先
上記で触れましたが、多くの人がつまずく点なので改めて説明します。curl URL は表示し、wget URL は保存します。
エラー処理
どちらにも特有の挙動があります。curl は 404 を転送成功とみなして終了ステータス 0 を返します — 転送は成功し、サーバーが応答したからです。HTTP エラーで終了ステータスが 0 以外になるようにするには、-f を使用します。
wgetはデフォルトでHTTPエラー時に非ゼロの終了ステータスを返します。これはダウンロードツールとしてはより直感的な動作です。
スクリプト内では、curl -sSfという組み合わせを覚えておく価値があります。これが省略されていることが、正常に動作していないジョブが動作しているように見えてしまうよくある原因です。
再試行
wgetはデフォルトで再試行を行います。curlは、--retryで明示的に指定しない限り再試行しません。
これもモデルと一貫しています。ダウンロードツールは粘り強く続けるべきであり、転送ツールはエラーを報告すべきです。
実践的なアドバイス
自動化されたスクリプトを作成する場合は、各ツールのデフォルト設定に頼るのではなく、動作を明示的に設定してください。curl -sSfL --max-time 30 は、あなたが望む動作を明確に示しています。wget --tries=3 --timeout=30 も同様です。明示的なコマンドは、1年後に他の誰かが読み返しても理解できるものです。
比較表
| タスク | curl | wget |
|---|
| ターミナルに出力 | curl URL | wget -O - URL |
| ファイルに保存 | curl -O URL | wget URL |
| 指定した名前で保存 | curl -o name URL | wget -O name URL |
| リダイレクトに従う | curl -L URL | デフォルト |
| ダウンロードを再開 | curl -C - -O URL | wget -c URL |
| ヘッダーのみ | curl -I URL | wget --spider -S URL |
| カスタムヘッダー | curl -H "K: V" URL | wget --header="K: V" URL |
| 基本認証 | curl -u user:pass URL | wget --user=u --password=p URL |
| POSTデータ | curl -d "a=b" URL | wget --post-data="a=b" URL |
| 静音モード | curl -s URL | wget -q URL |
| サイトのミラーリング | 不可 | wget -m URL |
| ファイルのアップロード | curl -T file URL | 不可 |
| SOCKS5 の使用 | curl -x socks5h://host URL | ネイティブでは不可 |
| 並列転送 | curl -Z ... | 未対応 |
表の読み方
この対称性は日常的な操作にも当てはまります。ほとんどのタスクには直接対応する機能があり、フラグの表記が異なる点は重要というより、むしろ煩わしい程度です。
「不可能」とマークされた4つの行こそが、実際に選択を行うべき箇所です。 サイトのミラーリングは wget のみです。アップロードは curl のみです。SOCKS プロキシは curl のみです。並列転送は curl のみです。
もしあなたのタスクがこれらの行のいずれかに該当する場合、比較はこれで終わりであり、これ以上読む必要はありません。該当しない場合は、どちらのツールでも動作するため、より使い慣れた方を使用してください。
フラグの衝突に関する注意
-O は、2つのツールで異なる意味を持ち、これは紛れもない落とし穴です。
curl では、-O は「URL から取得したファイル名で保存する」ことを意味し、-o name は「この名前で保存する」ことを意味します。wget では、-O name は「この名前で保存する」ことを意味し、もう一方のオプションは必要ありません。
したがって、curl -O と wget -O は同等ではなく、両者の間で不注意にコマンドを置き換えると、予期しない動作を引き起こすことになります。
タスクに応じた使い分け
結論というよりは、判断の指針です。
wget を使うべき場合
ファイルをディスクに保存したいとき。 オプション不要、進行状況バーあり、適切なデフォルト設定。これは、ほとんどの人にとって最も一般的なケースです。
ミラーリングや再帰的なダウンロードを行いたい場合。 これしか選択肢はありません。wget -m または wget -r を、適切な制限値と共に使用します。
接続が不安定で、ファイルサイズが大きい場合。 自動再試行と -c による再開機能。
ローカルコピーを同期させたい場合。 -N によるタイムスタンプ機能で、変更された部分のみをダウンロードします。
可能な限り短いコマンドを望む場合。他の人が読むスクリプト内で、単純なダウンロードを行うためです。
以下の場合は curl を使用してください
API を操作している場合。 ヘッダー、メソッド、リクエスト本文、および JSON プロセッサにパイプされる出力。
データを取得するだけでなく、送信する必要がある場合。
デバッグを行っている場合。-v および -w を使用すると、送信されたリクエスト、レスポンス、およびフェーズごとの処理時間を確認できます。これは curl の日常的な最大の利点であり、他のツールとは比べ物になりません。
HTTP や FTP 以外のプロトコルが必要な場合。
SOCKSやHTTPSプロキシのサポートが必要です。
WindowsやmacOSを使用していて、何もインストールされていない場合、curlは標準で搭載されていますが、wgetは通常インストールされていません。
コードとして実装するものを開発している場合、libcurlのバインディングにより、コマンドの構造が自然にコードに変換されるためです。
両方を使う
ほとんどの実用的な環境における正直な答えです。どちらも軽量で、無料で、それぞれ異なる点で優れています。両方をインストールし、状況に応じて適切な方を選ぶことは、優柔不断なのではなく、それらが本質的に異なるツールであるからこそ導き出される正しい選択なのです。
両方のプロキシ
私たちの領域ですが、知っておくべき重要な違いが1つあります。
curl
# HTTP proxy
curl -x http://proxy.example.com:8080 https://example.com
# With credentials
curl -x http://user:pass@proxy.example.com:8080 https://example.com
# SOCKS5, with the proxy resolving hostnames
curl -x socks5h://proxy.example.com:1080 https://example.com
curlは、HTTPプロキシ、HTTPSプロキシ、SOCKS4/SOCKS5
をサポートしており、これらはすべて、スキームを指定した同じ-x
オプションを通じて利用できます。
wget
# Via environment variables
export http_proxy="http://proxy.example.com:8080"
export https_proxy="http://proxy.example.com:8080"
wget https://example.com
# With credentials
wget --proxy-user=user --proxy-password=pass https://example.com
wgetは標準のプロキシ環境変数を読み取り、プロキシの認証情報に関するオプションも備えています。
重要な違い
wgetにはネイティブなSOCKSサポートがありません。 curlの比較リストには、curlがサポートしているがwgetがサポートしていないものとして、SOCKS4やSOCKS5
が挙げられています。
プロキシがSOCKS専用である場合、wgetはそれを直接使用できません。一般的な回避策としては、proxychainsのようなツールを介してwgetを実行するか、その前にローカルのHTTP-to-SOCKSブリッジを配置する方法があります。どちらも機能しますが、どちらも静かに失敗する可能性のあるコンポーネントを追加することになります。
この2つの選択肢から選ぶ場合、環境にSOCKSが設定されているなら、それが決定的な要因となります。
DNSの詳細(再掲)
curlをSOCKSと併用する際には常に適用されるため、繰り返し述べておく価値があります。socks5://
はローカルマシン上でホスト名を解決し、socks5h://
はホスト名をプロキシに送信します。 前者の場合、トラフィックは正しくルーティングされていても、アクセスしたすべてのホスト名がローカルのリゾルバーに漏洩してしまいます。また、地域に依存するインフラを持つサイトの場合、地域的に不適切なアドレスが返される可能性があります。
特に避けるべき理由がない限り、socks5h://
を使用してください。
そして、自分たちで売り込みを台無しにしてしまう部分
ファイルのダウンロード、認証情報を持つAPIへの呼び出し、あるいはサービスの稼働状況の確認を行う場合、プロキシはまったく必要ありません。プロキシがこれらのツールでその存在意義を発揮するのは、地理的な確認や、アドレスごとのレート制限に縛られる大量の処理を行う場合に限られます。それ以外の用途では、プロキシは遅延、障害点、そして費用を生み出すだけです。
どちらのツールも適していない場合
よくある状況の中には、別の手段を必要とするものがいくつかあり、どちらのツールを使っても午後を無駄にしてしまうことになります。
ページが JavaScript によってレンダリングされている場合。 どちらのツールも、サーバーから送信されたデータを取得します。コンテンツがその後ブラウザ内で組み立てられる場合、空のシェルしか得られず、どのフラグを設定しても解決しません。 必要なのはヘッドレスブラウザ――Playwright、Puppeteer、あるいは類似のツールです。
ページと対話する必要がある場合。 クリック、スクロール、フォームへの入力、何かが表示されるのを待つなど。答えは同じです。
コードで保守性の高いものを構築している場合。 アプリケーションからcurlを呼び出すのはよくある手っ取り早い方法ですが、長期的には問題が生じます。使用している言語のHTTPライブラリ、またはlibcurlのバインディングを使用し、適切なエラー処理を行ってください。
ディレクトリを双方向に同期する必要があります。 rsync がそのためのツールであり、再帰的なwgetよりもはるかに優れています。
自分が管理するサーバー間で転送している場合。 scp、rsync、または sftp — 専用に設計されており、高速で、権限や部分転送も適切に処理します。
転送中のトラフィックを検査または変更する必要がある場合。 インターセプトプロキシツールが適切な手段です。
動画プラットフォームからメディアをダウンロードする場合。 専用ツールであれば、これらでは対応できないマニフェストの解析やストリームの組み立てを適切に処理できます。
データが別の方法で提供されている場合。 API、一括ダウンロード、公開データセット、RSSフィードなどです。確認には10分ほどかかりますが、多くの場合、プロジェクトが始まる前に中止することになります。
再帰的ダウンロードに関する注意
wget -r に関する具体的な警告です。これは強力ですが、意図しない対象を指定してしまう危険性があります。
-np を指定しないと、親ディレクトリへと遡ってダウンロードしてしまいます。--level を指定しないと、下位のディレクトリへと深く降りてしまいます。 --wait を指定しないと、サーバーからの応答速度と同じペースでリクエストを送信してしまいます。これは他人のインフラに対して失礼な行為であり、アクセスを遮断される原因にもなりかねません。
最低限、wget -r -np --level=3 --wait=1 URL を指定してください。また、事前に robots.txt およびサイトの利用規約を確認してください。wget はデフォルトで robots.txt を尊重しており、これを無効にするのは単なる利便性ではなく、熟考すべき判断です。
よくある質問
curl と wget の違いは何ですか?
curlはcatのように動作し、データを取得して標準出力に書き出します。wgetはcpのように動作し、データを取得してファイルとして保存します。curlは、はるかに多くのプロトコル、アップロード、SOCKSプロキシ、並列転送に対応しています。一方、wgetは再帰的なダウンロードやサイトのミラーリングが可能ですが、curlにはこれらの機能は一切ありません。
curlはwgetより優れていますか?
どちらが優れているというわけではありません。curlはライブラリを基盤とした転送ツールであり、対応プロトコルの範囲がはるかに広いです。一方、wgetはダウンロードに特化したツールで、デフォルトの設定が優れており、独自の再帰的ダウンロード機能を備えています。多くの場合、両方を併用することでメリットが得られます。
curlはwgetのように再帰的にダウンロードできますか?
いいえ。curlは指定されたURLを取得するだけで、HTMLを解析したりリンクを検出したりはしません。再帰的なダウンロードやサイトのミラーリングはwget独自の機能であり、curlのメンテナンス担当者自身もこれをwgetの最大の強みとして挙げています。
なぜ curl はリダイレクトを追跡しないのですか?
設計上の仕様です。curl は、ユーザーが要求していないリクエストを行うのではなく、サーバーからの応答をそのまま報告します。リダイレクトを追跡するには、-L を追加してください。wget はデフォルトでリダイレクトを追跡します。これは、wget の目的がファイルの取得であり、ファイルが移動したためです。
curl と wget、どちらが速いですか?
単一の転送に関しては、その差は無視できるほど小さいです。どちらもネットワークの速度に制限されます。curl は -Z オプションを使用して複数の転送を並行して実行できるため、多数の小さなリソースを取得する際には、実質的に高速になります。
wgetはSOCKSプロキシに対応していますか?
ネイティブには対応していません。curlはSOCKS4、SOCKS5、HTTPSプロキシに対応しています。wgetは標準のHTTPプロキシ環境変数を使用します。wgetでSOCKSを使用するには、proxychainsなどのラッパーやローカルブリッジが必要です。
スクリプトではどちらを使うべきですか?
どちらでも構いませんが、明示的なオプションを指定してください。API やレスポンスを検証する必要がある場合は、curl -sSfL --max-time 30。ファイルの取得には、wget --tries=3 --timeout=30。自動化を行う際は、どちらのツールのデフォルト設定にも依存しないでください。
curl や wget はデフォルトでインストールされていますか?
curl は macOS および Windows 10、11 にプリインストールされています。wget はほとんどの Linux ディストリビューションでは標準ですが、macOS や Windows ではインストールされていないことがよくあります。クロスプラットフォームのスクリプトを作成する場合は、curl を使用するのが無難です。
まとめ
この比較は、その人気から想像されるよりも早く結論が出ます。というのも、この2つのツールは異なる動詞を基に構築されているからです。
curl は転送し、wget はダウンロードします。 curl は cat のように標準出力に書き出し、指示されたことを正確に実行し、残りを報告します。そのため、リダイレクトを追跡せず、再試行も行わず、ファイルに書き込むにはフラグが必要です。一方、wget は cp のようにディスクに書き出し、デフォルトでの動作のすべては、最終的にファイルが作成されるという目的から派生しています。
4つの機能によって選択は決定づけられ、もしあなたのタスクがそれらのいずれかを含むのであれば、残りの比較は関係ありません。 再帰的なダウンロードとサイトのミラーリングは wget のみが可能です — curl のメンテナンス担当者はこれを wget の最大の強みとして挙げており、curl には同等の機能がありません。アップロード、SOCKS プロキシ、並列転送は curl のみが可能です。
これら以外については、どちらのツールも機能し、実用上の違いはオプションの表記やデフォルト設定に限られます。両ツール間でコマンドを変換する際は、-Oという衝突に注意してください。これは、それぞれのツールで正反対の意味を持つからです。また、自動化された処理においては、どちらかのツールの想定に頼るのではなく、意図を明示的に記述してください。例えば、curl -sSfL --max-time 30 や wget --tries=3 --timeout=30 といったコマンドは、来年それらを読む人にとっても依然として意味を成すものです。
プロキシについて:弊社ではプロキシを販売していますが、これらのツールのほとんどの用途ではプロキシは必要ありません。プロキシが必要な場合、curl のサポート範囲はより広範ですが、ツールそのものよりも重要なのは、socks5:// ではなく socks5h:// を使用することです。そうすることで、ホスト名の解決がトラフィックと同じ経路を通るようになります。
正直なところ、両方をインストールすることをお勧めします。どちらも軽量で無料ですし、どちらが優れているかという議論は、実稼働中のマシンのほとんどが両方をインストールしているという事実によって、何年も前に決着がついています。