Why curl defaults to stdout
daniel.haxx.se
daniel.haxx.se
I will admit that rather than learn the right command to have curl print to file -- when I _do_ want to write to file, I do use wget (and appreciate it's default progress bar; there's probably some way to make curl do that too, but I've never learned it either).
When I want writing to stdout, I reach for curl, which is most of the time. (Also for pretty much any bash script use, I use curl; even if I want write to a file in a bash script, I just use `>` or lookup the curl arg).
It does seem odd that I use two different tools, with mostly entirely different and incompatible option flags -- rather than just learning the flags to make curl write to a file and/or to make wget write to stdout. I can't entirely explain it, but I know I'm not alone in using both, and choosing from the toolbox based on some of their default behaviors even though with the right args they can probably both do all the same things. Heck, in the OP the curl author says they use wget too -- now I'm curious if it's for something that the author knows curl doesn't do, or just something the author knows wget will do more easily!
To me, they're like different tools focused on different use cases, and I usually have a feel for which is the right one for the job. Although it's kind of subtle, and some of my 'feel' may be just habit or superstition! But as an example, recently I needed to download a page and all it's referenced assets (kind of like browsers will do with a GUI; something I only very rarely have needed to do), and I thought "I bet wget has a way to do this easily", and looked at the man page and it did, and I have no idea if curl can do that too but I reached for wget and was not disappointed.
Both can be quickly rectified, but it's still a pretty big pain.
Witten only partially in jest. I've submitted patches to both projects and both are relatively straight-forward code bases to dive in to.
You have it reversed. Wget will output to the screen/pipe if you output to the "file" --. Curl does not. "curl http://www.google.com/index.html -o --" does not output to the screen. It creates a file named "--".
I'm afraid I side with the left-handedness argument. Years of muscle memory make me want to type "w".
curl -O https://example.com/file.txt
It'll save to file.txt.
However, just as curl (in standard usage) is an analog to cat, I feel that wget (in standard usage) is an analog to cp, and whilst I certainly can copy files by doing 'cat a > b', semantically cp makes more sense.
Most of the time if I'm using curl or wget, I want to cp, not cat. I always get confused by curl and not being able to remember the command to just cp the file locally, so I tend to default to wget because it's easier to remember,
Curl? :p
No need to answer, just helping out the non-native speakers in the thread.
echo "GET / HTTP/1.1
Host: news.ycombinator.com
"|nc news.ycombinator.com 80 >ycI use wget for long-running downloads when I need to be able to continue later, for simple mirroring, and for bootstrapping web scraping scripts. In fact, the combination of wget -i (url-file) -k and egrep can be enough for many simple web scraping needs. The -k is really handy - converting relative links to absolute links.
If I must use curl, I generally bootstrap it with "Copy as cURL" in the network tab of a browser's developer tools. But it's just not needed very often.
This kind of question (and the other question you make above) remind me of the people that answer Stack Overflow questions with their opinions of "best practices" and "what you should be doing instead" instead of answering what the poster asks. E.g:
Q. "How do I store JSON in mysql?"
A. "Why do you ask? What do you want to achieve with this? You'll be better served with a NoSQL database".
etc, etc.
Yes, I think of wget more like cp, and I think of curl more like cat, and there are times when I want exactly curl as cat, as opposed to wget as cp.
Different tools, I like them both, and I use them differently. And, I only scratch the surface of capability for both tools.
I'm not saying he should change it. But if he thinks it's about typing less... he doesn't seem to realise how his users behave.
If you don't use the tools often enough to remember how they work, I don't think your needs are going to come up high on the developer's priority list.
It's tough to get a representative sample from something like voluntary correspondence, because it doesn't tell you the majority opinion, just the majority opinion from people who decided to write in.
EDIT: To note, it's entirely possible that the silent majority of curl users really do hate the default-to-stdout choice. But absent a real way of surveying, it's difficult to make a call either way.
$ curl -o news.ycombinator.com
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
$ curl -O news.ycombinator.com
curl: Remote file name has no length!
curl: try 'curl --help' or 'curl --manual' for more information
$ curl -O foo news.ycombinator.com
curl: Remote file name has no length!
curl: try 'curl --help' or 'curl --manual' for more information
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
$ wget news.ycombinator.com
--2014-11-17 14:27:18-- http://news.ycombinator.com/
Resolving news.ycombinator.com (news.ycombinator.com)... 198.41.191.47, 198.41.190.47
Connecting to news.ycombinator.com (news.ycombinator.com)|198.41.191.47|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://news.ycombinator.com/ [following]
--2014-11-17 14:27:19-- https://news.ycombinator.com/
Connecting to news.ycombinator.com (news.ycombinator.com)|198.41.191.47|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘index.html’
[ <=> ] 22,353 --.-K/s in 0.07s
2014-11-17 14:27:19 (331 KB/s) - ‘index.html’ saved [22353]
With wget, I can just through any URL to it and it‘ll probably do the right thing with the least amount of surprises. „Grab a file“ is my usecase 99.99% of the time, „Print a file“ is the rest 0.01%.Most of the time downloading anything, I need it on another machine, and normally the easiest way is copy/pasting an URL from my local web browser to a remote terminal, and fetch it using wget. In which case an auto redirect to a mirror selector that again auto downloads the item, all handled by javascript, is pretty frustrating.
Firefox has: https://addons.mozilla.org/en-US/firefox/addon/cliget/
and it's sorta built-in on chrome: https://coderwall.com/p/-fdgoq/chrome-developer-tools-adds-c...
Of course it would be a smoother experience for you if it worked more like the rest of the tools you are familiar with, but changing it would be a mistake. If curl were changed, then it would be one of the few unix tools that differs from the rest. That would make it jarring to people who use unix. Nobody wants to erode the good parts of unix and destroy the unix way just to make some commands slightly less jarring to people who don't regularly use unix.
Especially when you don't even need curl. That's the wrong option for you. Right next to the option in Chrome to copy a curl command is the option to copy just the url. Just use that and paste the url into your browser, which will work more like you'd expect.
If you must use curl, you almost certainly don't want to use "-o". That's an advanced option for when you are downloading multiple resources with a single command. You use it to provide a template for the multiple output filenames necessary in that particular situation.
If you only want to specify a single filename, then do like you would with any other typical unix command and redirect the output to a file. For example, append ">filename.html" to the end of the command.
Unix tools rarely have options to specify output filenames. They are as unnecessary as a button in a web browser that will let you "Display this webpage." Displaying webpages is what a web browser does, and writing output to a file is what a unix command does. It's just that the default file for a unix command is your terminal. Your shell makes it dead simple to pick a different one if that's what you want.
For instance when I download some archive I don't have to bother selecting where to download the file from the GUI (I hate navigating filesystems from GUIs), waiting for it to finish before switching to the command line to extract it. I just get the address, "curl $link | tar xzv" and I'm done.
I could obviously just use curl for this, but wget requires no additional options or thought.
When I'm in the middle of projects, there are several terminals, all on different 'machines' (ssh/chroot/and now docker) in different directories, and I need a file, be it source code or a binary or an rpm/deb/tgz/zip or just plain data to be where I am right now. I might use scp for this purpose, I might use rsync if the connection is flakey. Some times there's a shared file server and I can just use 'cp' instead.
Http is just yet another protocol where files come from, and when I use curl/wget I don't want the file in ~/Downloads along with all the other random crap, I want that it downloaded to where my terminal window is pointed, which may be a machine half-way around the world from me, or at the very least, in the right directory.
It doesn't make sense to download it to my machine, then upload it to where it needs to go either - just wget it directly, on the machine it needs to be on, in the directory where it needs to go.
curl www.example.com | ...
wget -O - www.example.com | ...
I guess it depends on what you're trying to achieve.curl https://news.ycombinator.com > hn.html
That way I am sure I don't overwrite some other file I already have in this folder with the same name which wget will give it.
I'd say that it's too late for a change. Changing the default behaviour would break way too many existing scripts and cronjobs.
IMHO cURL is the best tool for interacting with HTTP and wget is the best tool for downloading files.
Wget on the other hand end up within shell scripts and similar (i have before me a distro where the package manager is made of shell scripts, core utils and wget).
curl is like swiss army knife and wget is fixed blade knife ;-)
"curl -O foo" is not the same as "wget foo". wget will rename the incoming file to as to not overwrite something. curl will trash whatever might be there, and it's going to use the name supplied by the server. It might overwrite anything in your current working directory.
Try it and see.
Write output to a local file named like the remote file we get. (Only the file part of the remote file is used, the path is cut off.)
The remote file name to use for saving is extracted from the given URL, nothing else.
wget is a hugely useful tool for making local copies of websites and similar things -- the no-clobber rule is useful there, and the built-in crawling and resource fetching is fantastic. OTOH, for most things, I actually like curl's 'dumb' behaviour; it seems to match up better with the rest of the UNIX ecosystem.""curl http://...", screen is filled with garbage, ctrl-c, ctrl-c, ctrl-c, damn I'm on a remote host and ssh needs to catch up, ctrl-c, "cur...", actually terminal is broken and I'm writing garbage now, "reset", "wget http://..."."
I admit it happened to me more than once.
curl -silent http://i.imgur.com/0nCbgbi.jpg |hexdump -C |less
Now you could automate this for testing, etc.There are use cases for terminal output and changing this behavior now would probably wreck many 3rd party scripts. And if you really just want a simple download manager you probably should use wget anyways.
Maybe if it's a terminal print a warning with a simple explanation, or a Y/N prompt?
It's quite nice because it will put all your cookies on the command line so you can trivially download files protected by a login page directly to remote servers.
Luckily, Curl is much more than that and it is a great and powerful tool for people that work with HTTP. The fact that it writes to stdout makes things easier for people like me that are no gurus :) as it just works as I would expect.
When working with customers with dozens of different sites I like to be able to run a tiny script that leverages Curl to get me the HTTP status code from all the sites quickly. If you're migrating some networking bits this is really useful for a first quick check that everything is in place after the migration.
Also, working with HEAD instead of GET (-I) makes everything cleaner for troubleshooting purposes :)
My default set of flags is -LIkv (follow redirects, only headers, accept invalid cert, verbose output). I also use a lot -H to inject headers.
Haha I would never realize that
For me the perfect password is one that you type the consecutive characters alternating between left and right hand.
Words that you type with just one hand you do a little 'twist' with the hand that, IMO, is a little slower and uncomfortable to do. As soon your finger reach a key the other hand is already moving to the next and this goes back and forth.
But I guess I'm making a point more about comfort than laziness.
I really, really like libcurl's api (or at least the easy api, I didn't play around with the heavy duty multi api for simultaneous stuff). It's very clean and simple.
The one case where I will reach for wget first is making a static copy of a website. I need to do this sometimes for archival purposes, and though I always need to look up the specific wget options to do this properly, this use case seems to be one where wget is stronger than curl (especially converting links so they work properly in the downloaded copy).
Why not just alias it ("make a File from URL" -> furl?) if people want to use it with -O flag set as default?
Unless you forgot what the option was since you don't use it multiple times a day.
No big deal.
#!/usr/bin/env sh
case $(curl -sLI $1 | grep -i content-type) in
*text*) echo "curl $1"
;;
*) echo "curl $1 > $(basename $1)"
;;
esac
https://gist.github.com/agumonkey/b85cef0874822c470cc6Costs of one round trip though.