torresjrjr(7) 0xF7959E95

Stop using /dev/null

Byron Torres

Or rather, learn this:

$ cmd >&-
$ cmd 1>&-
$ cmd 2>&-
$ cmd 3>&-
$ ...

That is the builtin shell way of silencing the output of a command. The integer specifies the fd (file descriptor) to close. No integer implies fd 1, stdout (standard output). This syntax is defined in POSIX, is concise and expressive, and does not open a new file descriptor.

You may have instead been used to the following trick, which works similarly. It doesn’t close an fd. Instead, it writes the data to the /dev/null “virtual device” file.

$ command 2>/dev/null   # here, silencing the stderr (standard error)

The >&- syntax doesn’t always work, as some programs complain when a file descriptor is closed.

$ curl >&-
curl: (23) Failure writing output to destination
$ curl >/dev/null  # writes quietly

Nonetheless, it’s useful interactively, and helps keep your scripts neater.


Ex: Silence the stdout output (fd 1) of ping (only print errors):

$ ping >&-

Ex: Silence all output of curl:

$ curl -v  >&- 2>&-

Ex: Test whether I’m anywhere inside a git repository, without printing needless error messages (full script):

git log -0 2>&- && {
    # pretty print git info
    git log -1 --abrev-commit --format=short --color --decorate \
    | sed -n '1p; /^    /p'
    git status -s

Bonus link: - An excellent handbook for POSIX shell and utilities.