This is episode four in my mini-series about shiny new features in the upcoming curl 8.10.0 release.
One of the most commonly used curl command line options is the dash capital O (-O
) which also is known as dash dash remote-name (--remote-name
) in its long form.
This option tells curl to create a local file using the name from the filename part of the provided URL when downloading. I.e. when you tell curl
curl -O https://example.com/file.html
This command line conveniently creates a local file called file.html
in which it saves the downloaded data.
The -O option has been supported with this functionality since curl first shipped, in March 1998. An important point here is that it picks the name from the URL so that a user can tell what filename it creates. No surprises. The remote server is not involved in naming it.
What about no filename scenarios?
URLs do not necessarily need to have filename parts. Like these examples:
http://example.com/
http://example.com/path/
http://example.com/one/two/?id=12345
Since there are no filename parts in these URLs, they used to cause curl to refuse to operate with -O and instead return error. curl could not create a local filename to use:
$ curl -O http://example.com/
curl: Remote filename has no length
curl: (23) Failed writing received data to disk/application
Trying harder
Starting in curl 8.10.0, curl works a little harder to come up with a filename to store the download in when -O is used. While there is no filename part in the URL, the user did ask curl to download the URL to a local file so it now tries a few extra steps:
- Use the filename part from the URL if there is one, like before.
- If there is no filename but there is a path provided in the URL, extract the right-most directory name from the URL and use as filename.
- If there is neither a filename nor a path in the URL, curl uses a default, fixed, filename as a final backup:
curl_response
. This name intentionally has no extension because curl has no idea what data that will come and using an extension could mislead users into believing it says something about the type of content.
Several people have insisted that index.html
would be better and sensible default file name. I cannot agree with that, since it might just as well be an image or a tarball of your favorite open source project. I think naming such a file index.html would be more misleading than simply sticking to the neutral curl_response.
Let me give you a little table showing what filenames that will be used with curl -O and a given set of URLs:
URL | local filename |
http://example.com/one.html | one.html |
http://example.com/one.html?clues=no | one.html (curl ignores the query part) |
http://example.com/one/two/?id=42 | two (because it is the right-most directory piece) |
http://example.com/path/ | path (because it is the right-most directory piece) |
http://example.com/ | curl_response (because no filename nor directory to use) |
Find out which name
You can use curl’s -w, –write-out option and its %{filename_effective}
variable to learn exactly which name that was used.
Prefer another name?
There is always the -o
(lowercase o) option that lets you specify whatever filename you like. You do not have to let curl pick the filename for you.
Clobber or not
curl will by default overwrite, clobber if you will, any previously existing file using the same name. If you rather curl took a more careful approach, consider using –no-clobber in your command lines. It makes curl pick an alternative filename if the chosen one already exists when curl is about to download data into a local file.
Would be cool to use the `Content-Disposition` filename, is there any option for that too?
@R: sure, see -J, –remote-header-name