Skip to content
VLSI Mentor

Linux & Bash · Part I · Module 12 · Streams, Redirection and Pipes

Discarding Output, and /dev/null

Sometimes you do not want a command's output at all — you only want to know whether it worked. There is a file for that, and pointing a stream at it is trivial. Deciding which stream, and resisting the urge to silence both, is where the judgement lives.

Foundation15 min readLinuxPart IFundamentalsStreamsRedirection

Part I · Module 12 · Chapter 12.7 · Discarding Output, and /dev/null

Several chapters have ended commands with > /dev/null and moved on. Here is what that is.

1. A File That Keeps Nothing

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
$ echo "lots of text" > /dev/null
$ wc -c < /dev/null
       0

/dev/null is a special file that accepts any amount of data and stores none of it. Writing to it always succeeds and always discards. Reading from it gives immediate end-of-input.

It is a real entry in the filesystem:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
$ ls -l /dev/null
crw-rw-rw- 1 root wheel 3, 2 Oct  8 11:02 /dev/null

The c is the file type from Chapter 2.5 — a character device rather than an ordinary file. It is world-writable by design, and nothing accumulates, so there is no cleanup and no disk cost.

2. The Three Forms

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
command > /dev/null            # discard results, keep errors visible
command 2> /dev/null           # discard errors, keep results visible
command > /dev/null 2>&1       # discard both

Measured:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
$ ls /tmp /nope > /dev/null
ls: /nope: No such file or directory

$ ls /tmp /nope 2> /dev/null
/tmp:
agent.sock  build  scratch

$ ls /tmp /nope > /dev/null 2>&1
$

The ordering rule from Chapter 12.3 applies unchanged: > /dev/null 2>&1 silences both, and 2>&1 > /dev/null silences only the results. &> /dev/null is the Bash shorthand for the first.

3. The Existence Check

By far the most common use, and worth recognising as an idiom rather than parsing each time:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
command -v vcs > /dev/null 2>&1 || { echo "vcs not on PATH" >&2; exit 3; }

Both streams are discarded because only the exit status matters. command -v prints the path when it finds something and says nothing when it does not — and you want neither.

The same shape appears everywhere:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
grep -q ERROR run.log                         # -q already implies silence
diff -q a.txt b.txt > /dev/null               # only "are they the same?"
ping -c1 buildhost > /dev/null 2>&1           # only "is it up?"
git diff --quiet                              # only "is anything changed?"

4. Reading From It

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
$ wc -l < /dev/null
       0

Chapter 12.4 covered this: < /dev/null gives a command immediate end-of-input, which is the guard against an unattended job hanging on a prompt.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
./possibly_interactive_tool < /dev/null > tool.log 2>&1

Worth having on anything that runs in cron, in a regression harness, or over a connection you are about to close.

5. The Mistake

Silencing is easy. Silencing the wrong thing is the subject.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
./run_sim.sh > /dev/null 2>&1

That is a simulation whose output and error messages have both been thrown away. When it fails — and it will — there is nothing. No log, no message, no clue. The exit status is all you have, and Chapter 11.1 showed that several tools lie about it.

6. Send Them Somewhere Instead

The usual alternative to discarding errors is keeping them where nobody has to look unless something goes wrong:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
./run_sim.sh > "$logdir/sim.log" 2> "$logdir/sim.err"

if [ -s "$logdir/sim.err" ]; then
  echo "the simulation wrote to the error stream:" >&2
  head -20 "$logdir/sim.err" >&2
fi

Nothing on your screen during a clean run, and everything available after a bad one. This is Chapter 12.3's separate-files pattern, and it is what people usually mean when they reach for 2>/dev/null.

And if the noise is a known, specific nuisance, filter it rather than silencing the channel:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
./noisy_tool.sh 2>&1 | grep -v '^INFO:' | tee run.log

7. The Other Device Files

/dev/null has a few relatives worth recognising:

FileDoes
/dev/nullDiscards writes; reads give end-of-input
/dev/zeroReads give an endless stream of zero bytes
/dev/urandomReads give random bytes
/dev/ttyAlways your terminal, whatever the redirections
/dev/stdoutWhatever stream two currently points at
/dev/stderrWhatever stream three currently points at

/dev/tty appeared in Chapter 12.6; it is how you reach the terminal from inside a redirected pipeline.

/dev/stdout is occasionally the only way to make a tool that insists on a filename write to a stream:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
some_tool --output /dev/stdout | grep ERROR

/dev/urandom is the right source for anything security-related, as Chapter 8.5 noted when discussing $RANDOM:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n'

8. In Practice

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
#!/bin/bash
set -uo pipefail

logdir="${1:?usage: $0 <logdir>}"
mkdir -p "$logdir" || { echo "cannot create $logdir" >&2; exit 2; }

# Status only — both streams discarded, deliberately.
command -v vcs > /dev/null 2>&1 || { echo "vcs not on PATH" >&2; exit 3; }

# Removing something that may not be there. The error is genuinely expected.
rm -f "$logdir/stale.lock" 2>/dev/null

# Real work: nothing discarded, errors kept separately, input closed.
./run_sim.sh < /dev/null > "$logdir/sim.log" 2> "$logdir/sim.err"
status=$?

# Known noise filtered; everything else kept and shown.
grep -v '^INFO:' "$logdir/sim.log" | tail -20

if [ -s "$logdir/sim.err" ]; then
  echo "--- error stream ---" >&2
  head -20 "$logdir/sim.err" >&2
fi

exit "$status"

Four uses of /dev/null, each with a stated reason, and none of them on the command that does the work. That is the pattern worth copying: the checks are silenced and the work is recorded.

Practice

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
mkdir -p /tmp/dn && cd /tmp/dn

1 — Confirm it keeps nothing.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
echo "lots of text" > /dev/null
wc -c < /dev/null
ls -l /dev/null

2 — Silence each stream in turn.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
ls /tmp /nope > /dev/null
ls /tmp /nope 2> /dev/null | head -2
ls /tmp /nope > /dev/null 2>&1; echo "  (silent, status $?)"

3 — Confirm the ordering rule still applies.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
ls /tmp /nope 2>&1 > /dev/null
echo "  ^ the error still appeared — wrong order"

4 — Use the existence idiom.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
command -v bash > /dev/null 2>&1 && echo "  bash found"
command -v nosuchtool > /dev/null 2>&1 || echo "  nosuchtool not found"

5 — Prefer a quiet flag.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
printf 'a\nERROR\nb\n' > f.txt
grep -q ERROR f.txt && echo "  grep -q: found"
grep ERROR f.txt > /dev/null && echo "  redirect: found"

6 — Give a command empty input.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
wc -l < /dev/null

7 — Filter noise instead of silencing the channel.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
noisy() { echo "INFO: starting"; echo "real output"; echo "INFO: done"; echo "ERROR: bad" >&2; }
noisy 2>/dev/null
echo "--- vs ---"
noisy 2>&1 | grep -v '^INFO:'

The first hid the error. The second kept it.

8 — Meet the relatives.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
head -c 8 /dev/zero | od -An -tx1
head -c 8 /dev/urandom | od -An -tx1
echo "to the terminal regardless" > /dev/tty

9 — Clean up. cd /tmp && rm -rf /tmp/dn

Check Your Understanding

1. What happens to data written to /dev/null, and what do you get reading from it?

2. What is the difference between cmd > /dev/null and cmd 2> /dev/null?

3. Why is command -v tool > /dev/null 2>&1 the right use and make 2>/dev/null the wrong one?

4. find / -name x 2>/dev/null hides the permission errors. What else does it hide?

5. When should you prefer grep -q to grep … > /dev/null?

6. You want a long run recorded but nothing on screen. Which form, and why not /dev/null?

9. Remember

  • /dev/null accepts any amount of data and keeps none. Reads from it give immediate end-of-input.
  • It is a real file — a character device, world-writable, with no disk cost.
  • > /dev/null discards results; 2> /dev/null discards errors; > /dev/null 2>&1 discards both.
  • The ordering rule still applies. 2>&1 > /dev/null silences only the results.
  • cmd > /dev/null 2>&1 is the existence-check idiom, where only the status carries information.
  • Prefer a tool's own quiet flag — grep -q, diff -q, curl -s. It is clearer and often faster.
  • < /dev/null stops an unattended job hanging on a prompt.
  • Discard output freely; discard errors reluctantly. A silenced error is a bug met later with no information.
  • 2>/dev/null on a command that does real work is almost always wrong. Send errors to a file instead.
  • Filter known noise rather than silencing the channel: 2>&1 | grep -v PATTERN.
  • /dev/tty is always the terminal; /dev/stdout is wherever stream two points; /dev/urandom is for anything security-related.
  • Silence the checks, record the work.

One question about pipelines has been raised three times and deferred each time. The last chapter of the module answers it: when a pipeline fails, how do you find out?

Where this fits

Part of the Linux & Bash curriculum.