91

I have tried all sorts of ways to redirect both stdout and stderr to /dev/null without any success. I have almost my entire life run bash which I've never had this issue with, but for once in BSD I'm stuck with /bin/sh.

What I've tried:

if ls ./python* 2> /dev/null; then
    echo found Python
fi

... which works; if Python is not present it will mute the error messages from ls. However, if python.tgz is present, a line with be outputted which looks like this:

# ./test.sh
./python-2.7.3p1.tgz

I've tried:

if ls ./python* &> /dev/null; then
    echo found Python
fi

and

if ls ./python* 2>1 > /dev/null; then
    echo found Python
fi

and

if ls ./python* > /dev/null; then
    echo found Python
fi

Nothing really works. I can only redirect one of the outputs, not both at the same time.

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Torxed
  • 3,567
  • 7
  • 27
  • 44

1 Answers1

148

This will work in any POSIX-compatible shell:

ls good bad >/dev/null 2>&1

You have to redirect stdout first before duplicating it into stderr; if you duplicate it first, stderr will just point to what stdout originally pointed at.

Bash, zsh and some other shells also provide the shortcut

ls good bad &>/dev/null

which is convenient on the command-line but should be avoided in scripts which are intended to be portable.

rici
  • 9,670
  • 1
  • 36
  • 37
  • 1
    Indeed, i read the bourn shell manual. It stated that later versions of `/bin/sh` have implemented the `&>/dev/null` syntax, aparently not so or i have a older version (which i can't echo in any way, running OpenBSD 5.3 tho so should be sufficient) – Torxed Jun 25 '13 at 19:29
  • 9
    @Torxed, OpenBSD's `sh` is based on pdksh. There's no more Bourne shell nowadays. `csh` introduced `>&` also available in `zsh`. `bash` chose `&>` (now also supported by `zsh` and some `pdksh` derivatives) though it clearly breaks POSIX compliance since `foo &> file` is perfectly valid POSIX syntax which means something completely different. – Stéphane Chazelas Jun 25 '13 at 19:42
  • 4
    @StéphaneChazelas *(...) which means something completely different* You left me wondering what it means in this case...:) – Piotr Dobrogost Dec 09 '14 at 13:52
  • 6
    @PiotrDobrogost, `foo &> file` is like `foo & > file` or `foo & : > file`, that is run foo in background and open file for writing for no command at all (unlikely to be used like that). – Stéphane Chazelas Dec 09 '14 at 13:59
  • @StéphaneChazelas Thanks for info. As this is *unlikely to be used like that* it seems somehow sensible that bash re-purposed this notation for *special* redirection. If, however `>&` was not specified in POSIX then it would make more sense for bash to choose this notation instead and be POSIX compliant. Do you see any way out of this mess? – Piotr Dobrogost Dec 09 '14 at 14:20
  • 8
    @PiotrDobrogost, `>&` is not ideal either as it conflicts with the `>&2`, `>&-` operators. `zsh` added it for convenience for csh users (csh doesn't have `>&2`). They're just syntactic sugar, just use `> file 2>&1` which is standard and portable (to Bourne-like shells). – Stéphane Chazelas Dec 09 '14 at 14:26
  • I like the `&>` shortcut, this works in Cygwin, which I'm stuck with. – Bill Naylor Oct 31 '20 at 12:10
  • This was perfect for me. Thank you. – naltun Feb 17 '21 at 23:16