Request basics
Save and name response files
Save a response under an explicit name and understand when the server-provided name is safe to use.
10 minute lesson
By default curl prints the response body to your terminal. For downloads you want a file, and there are two ways to name it. Use --output when the destination filename matters. --remote-name (or -O) derives a local name from the URL path, which is convenient only when you trust that name.
Name the file yourself
Download a text file with an explicit destination:
curl --fail --output robots.txt https://curl.se/robots.txt
Check the exit status and inspect the saved file:
echo $? # 0 means the transfer and the HTTP status were both fine
cat robots.txt
--fail is the option people forget, and it matters. Without it, a 404 page is a “successful” transfer: curl happily saves the HTML error page as robots.txt and exits with 0. Your script continues, and the corruption surfaces much later, far from its cause. --fail makes HTTP responses at or above 400 produce a failed command instead of silently becoming the saved content — exit code 22, no misleading file.
Try it against a URL that does not exist. example.org serves no robots.txt, so curl --fail --output robots.txt https://example.org/robots.txt prints curl: (22) The requested URL returned error: 404 and leaves nothing on disk. Some HTTP/2 transfers report the same failure as exit code 56 — either way, non-zero.
Let the URL name the file
When mirroring a file whose name you already know and trust:
curl --fail -O https://curl.se/robots.txt
curl takes the last path segment, robots.txt, and writes to that name in the current directory. The name comes from a URL you typed, so the trust question is easy here. It stops being easy with --remote-header-name (-J), which lets the server pick the filename via a response header. A hostile or compromised server could suggest a name you did not expect, so treat that option with care and never combine it with directories you care about.
For large downloads that get interrupted, resume instead of restarting:
curl --fail -C - --output ubuntu.iso https://releases.ubuntu.com/24.04/ubuntu-24.04.4-desktop-amd64.iso
-C - tells curl to look at the partial file and continue from where it stopped.
Do not execute what you have not read
Do not pipe an unverified download directly into a shell. The popular curl ... | bash pattern runs whatever bytes arrive, instantly, with your permissions. Save it, inspect it, and verify its expected source or checksum first. The two extra commands cost seconds; running an attacker’s script costs considerably more.
Lesson completed