cURL & Wget — Complete Guide
A comprehensive practical guide covering command-line data transfer tools: cURL (Client URL) and Wget (World Wide Web Get).
1. Overview & Comparison
Both cURL and Wget are command-line utilities used for downloading data and interacting with servers over network protocols (HTTP, HTTPS, FTP, etc.).
flowchart LR
subgraph cURL["cURL (API & Protocol Powerhouse)"]
direction TB
C1["Bidirectional (Transfer & Receive)"]
C2["REST API Testing & Debugging"]
C3["Supports 25+ Protocols"]
C4["Powered by libcurl"]
end
subgraph Wget["Wget (File & Web Crawler Specialist)"]
direction TB
W1["Non-interactive Background Downloads"]
W2["Recursive Web Crawling & Mirroring"]
W3["Automatic Retry & Resume Support"]
W4["Simple CLI for Bulk File Fetching"]
end
Key Differences
| Feature | cURL (curl) |
Wget (wget) |
|---|---|---|
| Primary Focus | Data transfer, API testing, HTTP methods | File downloads, site mirroring |
| Direction | Bidirectional (Upload + Download) | Primarily Download |
| HTTP Methods | Full support (GET, POST, PUT, DELETE, etc.) |
Limited (GET, basic POST) |
| Recursive Download | ❌ No | ✅ Yes (-r, --mirror) |
| Protocol Support | 25+ (HTTP, HTTPS, FTP, SFTP, LDAP, SCP, etc.) | HTTP, HTTPS, FTP, FTPS |
| Library | Built on libcurl (usable in code) |
Standalone executable |
| Piping & stdout | Defaults to stdout |
Defaults to file on disk |
| Background execution | Manual (& or nohup) |
Built-in (-b) |
2. cURL (curl) In-Depth
curl is designed to transfer data to or from a server using one of the supported protocols.
Common Flags & Options
| Flag | Long Flag | Description |
|---|---|---|
-X |
--request |
Specify HTTP request method (GET, POST, PUT, DELETE) |
-H |
--header |
Pass custom HTTP header (e.g., -H "Content-Type: application/json") |
-d |
--data |
Send data in POST/PUT request body |
-o |
--output |
Write output to specified file |
-O |
--remote-name |
Write output to a local file named like the remote file |
-i |
--include |
Include HTTP response headers in the output |
-I |
--head |
Fetch response headers only (HEAD request) |
-L |
--location |
Follow HTTP 3xx redirects automatically |
-u |
--user |
Specify user credentials (user:password) |
-v |
--verbose |
Make the operation verbose (debugging info) |
-s |
--silent |
Silent mode (no progress meter or error messages) |
-k |
--insecure |
Allow insecure SSL connections (skip cert validation) |
-C |
--continue-at |
Resume a previously interrupted download |
-F |
--form |
Send multipart form data (file uploads) |
-b |
--cookie |
Send cookies from string or file |
-c |
--cookie-jar |
Save received cookies to file |
HTTP Request Examples
1. Basic GET Request
curl https://api.example.com/users2. Save Output to File
# Save to specific filename
curl -o user_data.json https://api.example.com/users
# Save using remote file's original name
curl -O https://example.com/downloads/archive.tar.gz3. POST Request with JSON Data
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "email": "john@example.com"}'4. POST Request with Data from File
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d @payload.json5. PUT Request (Update Resource)
curl -X PUT https://api.example.com/users/123 \
-H "Content-Type: application/json" \
-d '{"name": "Jane Doe", "email": "jane@example.com"}'6. PATCH Request (Partial Update)
curl -X PATCH https://api.example.com/users/123 \
-H "Content-Type: application/json" \
-d '{"email": "newemail@example.com"}'7. DELETE Request
curl -X DELETE https://api.example.com/users/1238. Follow Redirects (301 / 302)
curl -L http://example.comAuthentication & Headers
1. Bearer Token Authentication
curl -H "Authorization: Bearer YOUR_API_TOKEN" https://api.example.com/protected2. Basic Authentication
curl -u username:password https://api.example.com/dashboard3. Custom Headers
curl -H "X-Custom-Header: CustomValue" \
-H "Accept-Language: en-US" \
https://api.example.com/data4. API Key Header
curl -H "x-api-key: secret-api-key-12345" https://api.example.com/v1/metricsFile Uploads & Forms
1. Multipart Form Upload (multipart/form-data)
curl -F "file=@/path/to/photo.jpg" \
-F "description=Profile Photo" \
https://api.example.com/upload2. Standard Form URL-Encoded (application/x-www-form-urlencoded)
curl -d "username=admin" \
-d "password=secret" \
https://example.com/loginCookies & Sessions
1. Save Cookies to a File
curl -c cookies.txt -d "user=admin&pass=123" https://example.com/login2. Send Cookies with Request
curl -b cookies.txt https://example.com/dashboard3. Inline Cookie String
curl -b "session_id=abc123xyz; dark_mode=true" https://example.com/preferencesDebugging, Metrics & Performance
1. Inspect Response Headers Only
curl -I https://example.com2. Include Headers with Response Body
curl -i https://api.example.com/users3. Verbose Network Tracing
curl -v https://api.example.com/users4. Formatted Timing Metrics (-w)
curl -s -w "\
HTTP Code: %{http_code}\n\
DNS Lookup: %{time_namelookup}s\n\
TCP Connect: %{time_connect}s\n\
TLS Handshake: %{time_appconnect}s\n\
Pre-transfer: %{time_pretransfer}s\n\
Start Transfer: %{time_starttransfer}s\n\
Total Time: %{time_total}s\n" \
-o /dev/null https://google.com5. Rate Limiting & Resuming Downloads
# Limit download speed to 500 KB/s
curl --limit-rate 500k -O https://example.com/largefile.zip
# Resume interrupted download
curl -C - -O https://example.com/largefile.zip3. Wget (wget) In-Depth
wget is a free, non-interactive network downloader that supports HTTP, HTTPS, and FTP protocols.
Common Flags & Options
| Flag | Long Flag | Description |
|---|---|---|
-O |
--output-document |
Concatenate output and write to specified file |
-P |
--directory-prefix |
Save files to a specific directory |
-c |
--continue |
Resume getting a partially-downloaded file |
-b |
--background |
Go to background immediately after startup |
-r |
--recursive |
Turn on recursive retrieving |
-l |
--level |
Maximum recursion depth (default 5, 0 or inf for infinite) |
-m |
--mirror |
Turn on options suitable for mirroring (-r -N -l inf --no-remove-listing) |
-k |
--convert-links |
Make links in downloaded HTML point to local files |
-p |
--page-requisites |
Download all images, CSS, etc. needed to display HTML page |
-np |
--no-parent |
Don't ascend to parent directory when retrieving recursively |
-i |
--input-file |
Read URLs from a local or external file |
-A |
--accept |
Comma-separated list of accepted file extensions |
-R |
--reject |
Comma-separated list of rejected file extensions |
-t |
--tries |
Set number of retries (0 or inf for infinite) |
-Q |
--quota |
Set download quota (e.g., 100m) |
--limit-rate |
--limit-rate |
Limit download rate (e.g., 200k, 2m) |
Downloading Files
1. Download a Single File
wget https://example.com/files/document.pdf2. Download and Save with Custom Name
wget -O custom_name.pdf https://example.com/files/document.pdf3. Save into Specific Folder
wget -P /path/to/downloads https://example.com/files/document.pdf4. Resume an Interrupted Download
wget -c https://example.com/files/large_archive.iso5. Download in the Background
wget -b https://example.com/files/large_archive.iso
# View download progress in log
tail -f wget-log6. Download Multiple Files from a URL List
wget -i urls.txtWebsite Crawling & Mirroring
1. Mirror an Entire Website for Offline Viewing
wget --mirror --convert-links --adjust-extension --page-requisites --no-parent https://example.com/--mirror(-m): Enables recursion, timestamps, and infinite depth.--convert-links(-k): Converts links to point to local files.--adjust-extension(-E): Appends.htmlto files if needed.--page-requisites(-p): Downloads all CSS, JS, and image assets.--no-parent(-np): Restricts downloads to the current subpath.
2. Download Specific File Types (e.g., all PDFs)
wget -r -A.pdf -np https://example.com/documents/3. Reject Specific File Types
wget -r -R.zip,.tar.gz https://example.com/files/Authentication & Rate Limiting
1. Basic HTTP Authentication
wget --http-user="myuser" --http-password="mypassword" https://example.com/secure/file.zip2. Custom Request Header
wget --header="Authorization: Bearer YOUR_TOKEN" https://example.com/api/export.csv3. Limit Download Speed & Retries
wget --limit-rate=1m --tries=10 --timeout=30 https://example.com/video.mp44. Side-by-Side Command Cheatsheet
| Task | cURL (curl) |
Wget (wget) |
|---|---|---|
| Download file to disk | curl -O <url> |
wget <url> |
| Download with custom name | curl -o file.zip <url> |
wget -O file.zip <url> |
| Save to directory | curl -o dir/file.zip <url> |
wget -P dir/ <url> |
| Resume download | curl -C - -O <url> |
wget -c <url> |
| Limit download rate | curl --limit-rate 500k -O <url> |
wget --limit-rate=500k <url> |
| Fetch headers only | curl -I <url> |
wget --spider -S <url> |
| Send GET request | curl <url> |
wget -qO- <url> |
| Send POST JSON | curl -X POST -H "Content-Type: application/json" -d '{"k":"v"}' <url> |
wget --post-data='{"k":"v"}' --header="Content-Type: application/json" <url> |
| Bearer token auth | curl -H "Authorization: Bearer <token>" <url> |
wget --header="Authorization: Bearer <token>" <url> |
| Basic auth | curl -u user:pass <url> |
wget --user=user --password=pass <url> |
| Follow redirects | curl -L <url> |
Automatic (default) |
| Silent output | curl -s <url> |
wget -q <url> |
| Ignore invalid SSL cert | curl -k <url> |
wget --no-check-certificate <url> |
| Recursive download | ❌ Not supported | wget -r -np -A.pdf <url> |
| Offline website mirror | ❌ Not supported | wget -mkEp <url> |
5. Practical Automation Recipes
1. API Health Check Script (curl)
#!/usr/bin/env bash
ENDPOINT="https://api.example.com/health"
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$ENDPOINT")
if [ "$HTTP_STATUS" -eq 200 ]; then
echo "✅ Endpoint is healthy (HTTP $HTTP_STATUS)"
else
echo "❌ Endpoint failed with status HTTP $HTTP_STATUS"
exit 1
fi2. Formatted JSON API Query with jq (curl)
curl -s -H "Accept: application/json" https://jsonplaceholder.typicode.com/todos/1 | jq .3. Bulk Document Downloader (wget)
#!/usr/bin/env bash
# Downloads all PDFs from a target directory with retry and rate limit
TARGET_URL="https://example.com/whitepapers/"
wget -r -l 2 -np -nc \
-A "*.pdf" \
--limit-rate=2m \
--tries=5 \
--wait=1 \
-P ./whitepapers/ \
"$TARGET_URL"6. Summary: When to Choose Which?
flowchart TD
Start{"What is your primary goal?"}
Start -- "API Testing & REST Operations" --> cURL["Use cURL"]
Start -- "Bulk Files & Site Mirroring" --> Wget["Use Wget"]
subgraph cURL_Scope["cURL Capabilities"]
cURL --> C1["• Full HTTP verbs: GET, POST, PUT, DELETE"]
cURL --> C2["• Custom headers & JSON payloads"]
cURL --> C3["• Timing & handshake metrics (-w)"]
end
subgraph Wget_Scope["Wget Capabilities"]
Wget --> W1["• Recursive site crawling & mirroring (-m)"]
Wget --> W2["• Non-interactive background downloads (-b)"]
Wget --> W3["• Automatic retries & resume on disconnect (-c)"]
end