torresjrjr(7) 0x85A5ADE2

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 https://fediverse.party/ >&-
curl: (23) Failure writing output to destination
$ curl https://fediverse.party/ >/dev/null  # writes quietly
...

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

Examples

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

$ ping fediverse.party >&-

Ex: Silence all output of curl:

$ curl -v https://fediverse.party  >&- 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
	echo
}

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