ZetCode

Linux wget Command

last modified October 23, 2026

The wget command in Linux downloads files from the web over HTTP, HTTPS, and FTP. It is non-interactive, so it works well in scripts and cron jobs, and it is robust on unreliable connections: it retries failed downloads, resumes partial files, and can download whole websites recursively.

While curl is a general tool for sending requests and working with APIs, wget focuses on fetching files and directory trees. The examples download the Linux 1.0 source archive from kernel.org and use the httpbin.org testing service.

Downloading a file

In the basic form, wget downloads a URL into a file in the current directory.

wget https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz

wget resolves the host name, connects, and prints the HTTP status, the size, and the name of the target file. While downloading, it shows a progress bar with the transfer speed. The file name is taken from the URL; if the file already exists, wget saves the new copy as linux-1.0.tar.gz.1 instead of overwriting it.

$ wget https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
--2026-10-23 10:52:19--  https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
Resolving cdn.kernel.org (cdn.kernel.org)... 199.232.17.176, 2a04:4e42:41::432
Connecting to cdn.kernel.org (cdn.kernel.org)|199.232.17.176|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1259161 (1.2M) [application/x-gzip]
Saving to: ‘linux-1.0.tar.gz’

linux-1.0.tar.gz    100%[===================>]   1.20M  2.15MB/s    in 0.6s    

2026-10-23 10:52:19 (2.15 MB/s) - ‘linux-1.0.tar.gz’ saved [1259161/1259161]

Choosing the output file

The -O option sets the name of the output file. The -q option turns off the output of wget.

wget -q -O kernel.tar.gz https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
wget -qO- https://httpbin.org/user-agent

By default, wget sets the modification time of the file from the server, which is why the archive shows a date from 1994. The special name - writes the downloaded data to standard output; combined with -q, it makes wget usable in pipelines.

$ wget -q -O kernel.tar.gz https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
$ ls -l kernel.tar.gz
-rw-rw-r-- 1 jano jano 1259161 Mar 13  1994 kernel.tar.gz
$ wget -qO- https://httpbin.org/user-agent
{
  "user-agent": "Wget/1.21.2"
}

Less verbose output and target directory

The -nv option prints one line per downloaded file, and -P sets the directory where files are saved.

wget -nv -P downloads https://httpbin.org/robots.txt

The directory is created if it does not exist. The non-verbose mode is a good fit for logs, as it still reports errors.

$ wget -nv -P downloads https://httpbin.org/robots.txt
2026-10-23 10:52:21 URL:https://httpbin.org/robots.txt [30/30] -> "downloads/robots.txt" [1]
$ ls downloads
robots.txt

Resuming a download

The -c option continues a partially downloaded file.

wget -c https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz

We simulate an interrupted download by keeping only the first 400000 bytes of the archive. With -c, wget asks the server for the remaining part, the server answers with 206 Partial Content, and the plus signs in the progress bar mark the data that was already present. The completed file is identical to the full download. Resuming requires a server that supports range requests.

$ head -c 400000 kernel.tar.gz > linux-1.0.tar.gz
$ ls -l linux-1.0.tar.gz
-rw-rw-r-- 1 jano jano 400000 Oct 23 10:52 linux-1.0.tar.gz
$ wget -c https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
--2026-10-23 10:52:21--  https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
Resolving cdn.kernel.org (cdn.kernel.org)... 199.232.17.176, 2a04:4e42:41::432
Connecting to cdn.kernel.org (cdn.kernel.org)|199.232.17.176|:443... connected.
HTTP request sent, awaiting response... 206 Partial Content
Length: 1259161 (1.2M), 859161 (839K) remaining [application/x-gzip]
Saving to: ‘linux-1.0.tar.gz’

linux-1.0.tar.gz    100%[++++++=============>]   1.20M  3.00MB/s    in 0.3s    

2026-10-23 10:52:22 (3.00 MB/s) - ‘linux-1.0.tar.gz’ saved [1259161/1259161]

$ cmp linux-1.0.tar.gz kernel.tar.gz && echo "files are identical"
files are identical

Downloading multiple files

The -i option reads URLs from a file, one per line.

wget -nv -i urls.txt -P list

All three URLs are downloaded into the list directory, and a summary is printed at the end. Several URLs can also be given directly on the command line.

$ printf "%s\n" https://httpbin.org/robots.txt https://httpbin.org/json https://httpbin.org/uuid > urls.txt
$ wget -nv -i urls.txt -P list
2026-10-23 10:52:22 URL:https://httpbin.org/robots.txt [30/30] -> "list/robots.txt" [1]
2026-10-23 10:52:23 URL:https://httpbin.org/json [429/429] -> "list/json" [1]
2026-10-23 10:52:23 URL:https://httpbin.org/uuid [53/53] -> "list/uuid" [1]
FINISHED --2026-10-23 10:52:23--
Total wall clock time: 1.1s
Downloaded: 3 files, 512 in 0s (2.66 MB/s)
$ ls list
json
robots.txt
uuid

Limiting the download speed

The --limit-rate option caps the bandwidth. The value is in bytes per second and accepts the k and m suffixes.

wget --limit-rate=200k -O /dev/null https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz

The download runs at 200 KB/s, so the 1.2 MB file takes about six seconds. Limiting the rate prevents a large download from saturating the network connection. Writing to /dev/null discards the data.

$ wget --limit-rate=200k -O /dev/null https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
--2026-10-23 10:52:23--  https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
Resolving cdn.kernel.org (cdn.kernel.org)... 199.232.17.176, 2a04:4e42:41::432
Connecting to cdn.kernel.org (cdn.kernel.org)|199.232.17.176|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1259161 (1.2M) [application/x-gzip]
Saving to: ‘/dev/null’

/dev/null           100%[===================>]   1.20M   200KB/s    in 6.1s    

2026-10-23 10:52:29 (200 KB/s) - ‘/dev/null’ saved [1259161/1259161]

Downloading in the background

The -b option sends wget to the background immediately after startup.

wget -b -o download.log -O bg.tar.gz https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz

wget prints its process ID and continues working after the terminal is closed. Its messages go to the file given with -o; without it, they are written to wget-log. We check the end of the log after the download finishes.

$ wget -b -o download.log -O bg.tar.gz https://cdn.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
Continuing in background, pid 15445.
$ tail -n 2 download.log
2026-10-23 10:52:30 (2.75 MB/s) - ‘bg.tar.gz’ saved [1259161/1259161]

Retries and timeouts

The --tries option sets the number of attempts, and --timeout sets the network timeout in seconds.

wget -nv --tries=2 --timeout=3 https://httpbin.org/delay/5 -O /dev/null

The server waits five seconds before it responds, which exceeds our timeout, so both attempts fail. By default, wget tries 20 times and uses a read timeout of 900 seconds, which suits long downloads but can make scripts hang for a long time.

$ wget -nv --tries=2 --timeout=3 https://httpbin.org/delay/5 -O /dev/null
Read error (Connection timed out) in headers.
Read error (Connection timed out) in headers.

Authentication

The --user and --password options provide credentials for HTTP basic authentication or FTP.

wget -qO- --user=john --password=secret https://httpbin.org/basic-auth/john/secret

The correct credentials are accepted, and wrong ones are rejected. A password on the command line is visible in the process list and the shell history; the --ask-password option prompts for it instead.

$ wget -qO- --user=john --password=secret https://httpbin.org/basic-auth/john/secret
{
  "authenticated": true, 
  "user": "john"
}
$ wget -nv --user=john --password=wrong https://httpbin.org/basic-auth/john/secret
Authentication selected: Basic realm="Fake Realm"
Username/Password Authentication Failed.

Headers and POST data

The --header option adds a request header, -U sets the user agent, and --post-data sends a POST request.

wget -qO- --header='Accept-Language: sk' -U 'my-client/1.0' https://httpbin.org/headers
wget -qO- --post-data='name=John&occupation=gardener' https://httpbin.org/post

The httpbin service returns the headers and the form data it received; we filter its responses with jq. For more complex requests, curl is usually a better fit.

$ wget -qO- --header='Accept-Language: sk' -U 'my-client/1.0' https://httpbin.org/headers | jq '.headers | del(."X-Amzn-Trace-Id")'
{
  "Accept": "*/*",
  "Accept-Encoding": "identity",
  "Accept-Language": "sk",
  "Host": "httpbin.org",
  "User-Agent": "my-client/1.0"
}
$ wget -qO- --post-data='name=John&occupation=gardener' https://httpbin.org/post | jq .form
{
  "name": "John",
  "occupation": "gardener"
}

Checking links

The --spider option checks that a URL exists without downloading it.

wget --spider -nv https://example.com
wget --spider -nv https://httpbin.org/status/404; echo "exit: $?"

For a missing page, wget reports a broken link and exits with status 8, which signals an error response from the server. This makes --spider useful for simple availability checks.

$ wget --spider -nv https://example.com
2026-10-23 10:52:49 URL: https://example.com/ 200 OK
$ wget --spider -nv https://httpbin.org/status/404; echo "exit: $?"
https://httpbin.org/status/404:
Remote file does not exist -- broken link!!!
exit: 8

Recursive downloads

The -r option follows links in downloaded HTML pages, and -l limits the recursion depth.

wget -r -l 1 -nv --no-parent https://httpbin.org/links/3/0

The start page links to two other pages, which are downloaded as well. wget respects robots.txt, so it fetches that file first. The files are saved in a directory named after the host. The --no-parent option prevents ascending to the parent directory.

$ wget -r -l 1 -nv --no-parent https://httpbin.org/links/3/0
2026-10-23 10:52:50 URL:https://httpbin.org/links/3/0 [115/115] -> "httpbin.org/links/3/0" [1]
2026-10-23 10:52:50 URL:https://httpbin.org/robots.txt [30/30] -> "httpbin.org/robots.txt" [1]
2026-10-23 10:52:51 URL:https://httpbin.org/links/3/1 [115/115] -> "httpbin.org/links/3/1" [1]
2026-10-23 10:52:51 URL:https://httpbin.org/links/3/2 [115/115] -> "httpbin.org/links/3/2" [1]
FINISHED --2026-10-23 10:52:51--
Total wall clock time: 1.3s
Downloaded: 4 files, 375 in 0s (1.73 MB/s)
$ find httpbin.org -type f | sort
httpbin.org/links/3/0
httpbin.org/links/3/1
httpbin.org/links/3/2
httpbin.org/robots.txt

Mirroring a website

To make an offline copy of a website, several options are combined.

wget --mirror --convert-links --page-requisites --no-parent --wait=1 https://example.com/docs/

The --mirror option turns on recursion with infinite depth and timestamping, so that a repeated run downloads only changed files. --convert-links rewrites links for local viewing, and --page-requisites also downloads images, stylesheets, and scripts needed to display the pages. The --wait option pauses between requests to reduce the load on the server. Mirror only sites you are allowed to copy.

Best practices for wget

Source

GNU wget manual

In this article, we have used the wget command to download files, resume and limit downloads, run them in the background, authenticate, check links, and download websites recursively.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.