Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Shouldn't it be:

which curl >/dev/null 2>&1

?

(what I learned from man bash)



Sadly, much of this article is an example of why you shouldn't learn from other people's shell scripts. Too often shell scripts are quickly written without much attention to best practices, so they have a lot of bad habits in them. For much the same reason bad code tends to get copy and pasted about until it becomes common such common practice no one questions it.

One shouldn't use which at all. It forks an external process, it is vulnerable to PATH issues unless you specify what will surely be a non-portable path to the executable, often isn't included in chroot'd environments, and doesn't actually return an exit status on many platforms. In short: it sucks in almost all possible ways you could hope to suck.

The proper expression to use is:

    command -v curl >/dev/null 2>&1
If you know you are in bash, type -P and possibly hash become acceptable alternatives, but then... why not just use command -v right?


But why -v ? Wouldn't just:

    command curl # optionally 2> /dev/null
                 # but there really shouldn't be any
                 # output -- so any error you probably
                 # want to see...
do what's intended (exit with non-zero return if curl isn't available as a command)?

[edit: Because command runs the command by default, it outputs info with -v!. So if the command does something by default (eg: command halt) -- then:

    command halt #halts!
    command -v halt #outputs something like /sbin/halt
Whops.]



Sounds like one for my site, which I'm still not sure if it's OK to plug here.


One "moment of clarity" I had is to realise that 2>&1 is a RIGHT-TO-LEFT assignment - file descriptor 1 gets assigned to file descriptor 2.

This is why (to redirect both stdout and stderr to $file) you have to do e.g. 1>$file 2>&1 rather than the more obvious-looking 2>&1 1>$file.


`2>&1 > /dev/null` will drop stdout and write stderr to stdout.

`> /dev/null 2>&1` will drop both stdout and stderr.

For myself, with `which` I would just use `> /dev/null`, as `which` writes to stdout and not stderr: if anything comes through stderr, you probably want to know about it.


All right, but he wrote: "The 2>&1 > /dev/null puts both output stream and error stream to /dev/null (which means nothing printed on console).". So the intention was different.

PS. I think "which" will never produce anything on stderr


As Chris said, `2>&1 > /dev/null` will drop stdout and write stderr to stdout. If you do not want anything to printed on console, you can use it. Now only i came to know that `which` never produce the stderr. So it is enough to use `>/dev/null`.


If you're using Bash, you can use this shorthand: which curl >& /dev/null


or &>/dev/null




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: