wget Command Deep Dive
If curl is a precise HTTP client, wget approaches the same network from a different direction: retrieving files and resources. The commands can overlap, but the difference becomes obvious when you move beyond “download this one URL” into recursive downloads, continuing interrupted transfers, and mirroring a site.
The useful question isn’t “which command is better?” It is:
Am I trying to interact with a specific HTTP request, or am I primarily trying to retrieve resources?
What Is wget?
wget is a command-line utility designed primarily for downloading resources over protocols such as HTTP and HTTPS.
The simplest example is:
wget https://example.com/file.tar.gzInstead of writing the response body directly to your terminal, wget normally saves the downloaded resource as a file.
Conceptually:
URL
↓
wget
↓
HTTP request
↓
Response
↓
Local fileThat default behavior immediately makes wget convenient for ordinary downloads.
Compare it with:
curl https://example.com/file.tar.gzwhich writes the response body to standard output unless you tell it otherwise.
With curl, you explicitly choose how to save the result:
curl -O https://example.com/file.tar.gzWith wget, saving the resource is already the normal operation:
wget https://example.com/file.tar.gzA Basic Download
Run:
wget https://example.com/file.tar.gzIf the server allows the download, you’ll see progress information and a local file will be created.
List the directory:
lsYou should find:
file.tar.gzThe important difference from a simple curl command is the default intent:
curl
→ give me the HTTP response
wget
→ download this resourceBoth can perform the other task, but their defaults reflect their different strengths.
Choose The Output Filename
You can choose the local filename with:
wget -O archive.tar.gz https://example.com/file.tar.gzHere -O means:
Write the downloaded response to this file.
This is similar in purpose to:
curl -o archive.tar.gz https://example.com/file.tar.gzNotice that the capitalization differs:
curl
-o
wget
-ODon’t rely on the option name alone when switching between the two tools.
Continue An Interrupted Download
One of wget’s particularly useful download-oriented features is continuing an existing download.
Suppose:
large-file.isowas only partially downloaded.
You can try:
wget -c https://example.com/large-file.isoThe -c option means continue.
Conceptually:
Already downloaded:
[==================== ]
wget -c
↓
Continue from here
[==============================]This is useful for large files or unreliable connections.
The remote server must support the necessary range requests for resuming to work correctly.
With curl, the equivalent pattern is:
curl -C - -O https://example.com/large-file.isoSo both tools can resume downloads, but wget makes the operation feel more natural because downloading is its primary job.
Follow Redirects
Modern URLs frequently redirect.
For example:
http://example.com/file.tar.gz
↓
https://downloads.example.com/file.tar.gzwget normally follows HTTP redirects when retrieving resources.
This is one reason it is convenient for downloads: you usually don’t need to explicitly add a redirect-following option for the ordinary case.
With curl, you commonly write:
curl -L -O https://example.com/file.tar.gzThe difference illustrates the broader design philosophy:
curl
→ explicit control over the request
wget
→ convenient retrieval behaviorSee HTTP Headers
wget can display server response information using:
wget --server-response https://example.comYou may see information including:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: ...This is useful when you need to understand what the server returned but your primary goal is still downloading the resource.
With curl, the corresponding common inspection patterns are:
curl -i https://example.comor:
curl -v https://example.comcurl generally gives you a more direct request/response debugging experience.
Quiet Downloads
If you don’t want the normal progress display, use:
wget -q https://example.com/file.tar.gzThe -q option means quiet.
This is useful in scripts where normal progress output isn’t useful.
You can combine it with other options when you only care whether the download succeeds.
Set A Timeout
Network operations should not always be allowed to wait indefinitely.
You can set a timeout with:
wget --timeout=10 https://example.com/file.tar.gzYou can also control retry behavior.
For example:
wget --tries=3 https://example.com/file.tar.gzThis asks wget to make a limited number of attempts rather than retrying indefinitely.
These options become useful when wget is used in scripts or scheduled jobs.
Download Multiple URLs
wget can work with multiple URLs directly:
wget https://example.com/file1.tar.gz \
https://example.com/file2.tar.gz \
https://example.com/file3.tar.gzIt can also read URLs from a file.
Create:
urls.txtwith:
https://example.com/file1.tar.gz
https://example.com/file2.tar.gz
https://example.com/file3.tar.gzThen:
wget -i urls.txtThe -i option tells wget to read URLs from the specified input file.
This is useful when the download list is generated separately from the actual downloading step.
Why wget Is Interesting For Website Downloads
Now we reach the area where wget starts to become substantially different from the way you normally use curl.
Suppose this page:
https://example.com/docs/contains links to:
/docs/install.html
/docs/config.html
/docs/networking.htmlA normal curl command retrieves one response:
curl https://example.com/docs/It does not automatically crawl the links found in that HTML.
wget can recursively retrieve linked resources.
For example:
wget --recursive https://example.com/docs/Now the operation is closer to:
docs/
│
├── index.html
├── install.html
├── config.html
└── networking.htmlInstead of manually discovering every URL and downloading it yourself, wget can follow links and retrieve additional resources.
This is one of its biggest practical advantages over curl.
Limit Recursion
Recursive downloading needs boundaries.
You normally don’t want to tell a downloader:
"Follow everything you can find on the Internet."You can limit recursion depth.
For example:
wget --recursive --level=2 https://example.com/docs/This limits how deeply wget follows links.
Conceptually:
Start page
│
├── Level 1
│ ├── page A
│ └── page B
│
└── Level 2
├── page C
└── page DWithout a sensible boundary, recursive retrieval can produce far more content than you intended.
Download A Site’s Dependencies
A common goal is to retrieve a page and the resources required to view it locally.
For example:
index.html
├── style.css
├── app.js
└── image.pngYou can use:
wget --page-requisites https://example.com/The --page-requisites option tells wget to retrieve resources needed by the page.
This is different from simply downloading the HTML document.
The distinction is:
wget URL
→ download the resource
wget --page-requisites URL
→ download the page and resources it needsConvert Links For Local Browsing
If you download a collection of HTML pages, their links may still point to the original website.
For a local copy, you may want those links rewritten.
wget supports this with:
wget --convert-links https://example.com/docs/Now links in downloaded documents can be adjusted so that they point to the corresponding local files.
This becomes especially useful when combined with recursive retrieval.
For example:
wget --recursive --convert-links https://example.com/docs/The result is much closer to a browsable local copy.
Mirror A Website
wget provides a higher-level mode specifically intended for mirroring.
For example:
wget --mirror https://example.com/docs/--mirror enables a collection of options appropriate for mirroring a site.
A more explicit form might be:
wget --mirror --convert-links --page-requisites https://example.com/docs/This is the kind of operation where wget becomes much more convenient than curl.
With curl, you’d have to build the crawling, URL discovery, file naming, and link handling yourself.
With wget, those concerns are already part of the tool’s purpose.
Warning
Don’t mirror a large website casually. Recursive downloading can generate many requests and consume substantial bandwidth and storage. Always make sure you are allowed to retrieve the content and keep the recursion scope under control.
Restrict Downloads To One Domain
Recursive downloading can become dangerous if links lead outside the site you intended to retrieve.
You can restrict recursion to the target domain:
wget --recursive --no-parent --domains=example.com https://example.com/docs/Here:
--recursive
follow links
--no-parent
don't move above the starting directory
--domains=example.com
restrict retrieval to the specified domainThis is a much safer pattern for a controlled documentation download.
A Practical Documentation Download
Suppose you want a local copy of:
https://example.com/docs/and the documentation consists of multiple linked pages.
A reasonable demonstration is:
wget --recursive --convert-links --page-requisites --no-parent --domains=example.com https://example.com/docs/The important parts are:
recursive
follow documentation links
convert-links
make downloaded links useful locally
page-requisites
retrieve resources required by pages
no-parent
stay below /docs/
domains
don't wander onto unrelated domainsThis is a good example of why wget exists as a distinct tool rather than simply being another spelling of curl.
wget And HTTP Requests
Although wget is download-oriented, it can still make HTTP requests and provide useful control.
For example:
wget --header='Accept: application/json' https://example.com/api/usersThis adds a request header.
You can also send data:
wget --header='Content-Type: application/json' --post-data='{"name":"alice"}' https://example.com/api/usersSo wget is not limited to anonymous file downloads.
However, once your task becomes:
inspect exact request
debug headers
send several custom headers
reproduce an API request
inspect TLS/connection detailscurl usually becomes the more natural tool.
curl Versus wget
The overlap is large enough that people often ask which one they should use.
The better way to think about it is by task.
| Task | Prefer | Why |
|---|---|---|
| Download one file | wget | Downloading is its primary workflow |
| Download and choose exact filename | Either | Both support it |
| Resume large download | wget | Simple -c pattern |
| Make a precise HTTP request | curl | Strong request-oriented interface |
| Inspect request and response | curl | -v is excellent for this |
| Send custom headers | curl | Convenient request construction |
| Send JSON to an API | curl | Natural API/testing workflow |
| Download many known URLs | wget | Built around retrieval |
| Read URLs from a file | wget | Simple -i workflow |
| Recursively follow links | wget | Built-in recursive retrieval |
| Mirror a site | wget | Designed for this use case |
| Debug HTTP/TLS behavior | curl | More direct diagnostic output |
| Automate a specific API request | curl | Precise and reproducible |
Neither tool is universally better.
A useful rule is:
Need to interact with an HTTP service?
↓
curl
Need to retrieve resources?
↓
wgetIt’s not an absolute rule, but it is a very good starting point.
The Same Download With Both Tools
Suppose you need:
https://example.com/file.tar.gzWith curl:
curl -L -O https://example.com/file.tar.gzWith wget:
wget https://example.com/file.tar.gzBoth accomplish the same basic task.
Now suppose you want to inspect the HTTP exchange.
With curl:
curl -v https://example.com/file.tar.gzThis is where curl starts to feel more natural.
Now suppose you want to recursively download an entire documentation tree:
wget --recursive https://example.com/docs/This is where wget has a clear advantage.
The important lesson is not to memorize a winner.
It is to recognize the problem shape.
wget And The Networking Layers
Like curl, wget exercises the layers you’ve already studied:
wget https://example.com/file.tar.gz
│
▼
DNS
│
▼
IP address
│
▼
Routing
│
▼
Network interface
│
▼
TCP connection :443
│
▼
TLS
│
▼
HTTP
│
▼
downloaded fileThe difference is mainly in what the application does with the HTTP interaction.
curl exposes the request/response exchange as the primary object.
wget treats retrieval as the primary object and adds features around that workflow.
A Useful wget Pattern Collection
You don’t need to memorize the entire manual. These patterns cover the most useful operations for this course.
Download:
wget https://example.com/file.tar.gzChoose the local filename:
wget -O archive.tar.gz https://example.com/file.tar.gzContinue an interrupted download:
wget -c https://example.com/large-file.isoRead URLs from a file:
wget -i urls.txtShow server response information:
wget --server-response https://example.comQuiet operation:
wget -q https://example.com/file.tar.gzRecursive download:
wget --recursive https://example.com/docs/Limit recursion:
wget --recursive --level=2 https://example.com/docs/Download page dependencies:
wget --page-requisites https://example.com/Rewrite links for local browsing:
wget --convert-links https://example.com/docs/Mirror a site:
wget --mirror https://example.com/docs/Restrict a recursive download:
wget --recursive --no-parent --domains=example.com https://example.com/docs/The important thing is to understand what each pattern is trying to accomplish rather than memorizing every option.
What You Should Remember
wget and curl overlap, but they have different centers of gravity.
curl is particularly strong when you want to control and inspect a specific HTTP interaction:
request
↓
responsewget is particularly strong when you want to retrieve resources:
URL
↓
download
↓
local filesAnd when the task becomes recursive:
page
↓
linked pages
↓
linked resources
↓
local copywget becomes especially convenient.
The practical distinction is:
Reach for
curlwhen the HTTP request itself is the thing you’re investigating or constructing. Reach forwgetwhen downloading and retrieving resources is the main job.
Knowing both means you don’t have to force one tool into a job the other handles naturally.
What’s Next
We’ve now used curl and wget to interact with network services from the command line. The next topic brings the pieces together into network debugging: how to determine whether a failure is caused by the interface, IP configuration, routing, DNS, a listening service, or the connection itself.