Is there a command-line shortcut for ">/dev/null 2>&1"
Asked Answered
W

10

27

It's really annoying to type this whenever I don't want to see a program's output. I'd love to know if there is a shorter way to write:

$ program >/dev/null 2>&1

Generic shell is the best, but other shells would be interesting to know about too, especially bash or dash.

Woozy answered 30/5, 2009 at 0:51 Comment(0)
S
17

You can write a function for this:

function nullify() {
  "$@" >/dev/null 2>&1
}

To use this function:

nullify program arg1 arg2 ...

Of course, you can name the function whatever you want. It can be a single character for example.

By the way, you can use exec to redirect stdout and stderr to /dev/null temporarily. I don't know if this is helpful in your case, but I thought of sharing it.

# Save stdout, stderr to file descriptors 6, 7 respectively.
exec 6>&1 7>&2
# Redirect stdout, stderr to /dev/null
exec 1>/dev/null 2>/dev/null
# Run program.
program arg1 arg2 ...
# Restore stdout, stderr.
exec 1>&6 2>&7
Steakhouse answered 30/5, 2009 at 1:23 Comment(1)
This should be the accepted answer, I tried to implement this myself but I accidentally ran the "$@" inside a subshell for some reason. This works flawlessly for my use.Toneytong
L
16
>& /dev/null
Lailalain answered 30/5, 2009 at 0:54 Comment(3)
Thanks, that's good (didn't know that one) but I should have specified that "shortcut" means less than half the number of characters. This is almost as much typing. In fact the 2>&1 part is easy, it's /dev/null that's annoying to type.Woozy
I'm really curious to know what you're running that forces you to pipe stdout and stderr to /dev/null so frequently that typing /dev/null becomes an annoyance.Harlandharle
Bash manual prefers the form "&>/dev/null", to avoid possible ambiguities with ">&n" (where n is an integer). I don't think it's portable outside of Bash, though.Turki
N
15

In bash, zsh, and dash:

$ program >&- 2>&-

It may also appear to work in other shells because &- is a bad file descriptor.

Note that this solution closes the file descriptors rather than redirecting them to /dev/null, which could potentially cause programs to abort.

Nobelium answered 27/7, 2013 at 16:57 Comment(3)
"Can potentially"? I'd call that "usually does". Programs that don't check whether their writes succeed are buggy.Maddy
If I'm right, sh is the name of the default shell for a given distribution, while dash is the name given to the Debian version of ash. See wikipedia. Could you clarify please ?Buyse
@loxaxs: In Ubuntu, sh now runs dash. I can't remember what it did for me at the time of writing (I seem to recall something about running bash in POSIX compatibility mode), but I've removed it now because of the ambiguity.Nobelium
W
7

Most shells support aliases. For instance, in my .zshrc I have things like:

alias -g no='2> /dev/null > /dev/null' 

Then I just type

program no
Wake answered 30/5, 2009 at 1:22 Comment(1)
In bash, that would be: alias no='2> /dev/null > /dev/null'; no command arg argYah
B
3

Edit: the (:) or |: based solutions might cause an error because : doesn't read stdin. Though it might not be as bad as closing the file descriptor, as proposed in Zaz's answer.


  • For bash and bash-compliant shells (zsh...):

    $ program &>/dev/null
    OR
    $ program &> >(:) # Should actually cause error or abortion
    
  • For all shells:

    $ program 2>&1 >/dev/null
    OR
    $ program 2>&1|: # Should actually cause error or abortion
    

    $ program 2>&1 > >(:) does not work for dash because it refuses to operate process substitution right of a file substitution.

Explanations:

  • 2>&1 redirects stderr (file descriptor 2) to stdout (file descriptor 1).
  • | is the regular piping of stdout to the stdin of another command.
  • : is a shell builtin which does nothing (it is equivalent to true).
  • &> redirects both stdout and stderr outputs to a file.
  • >(your-command) is process substitution. It is replaced with a path to a special file, for instance: /proc/self/fd/6. This file is used as input file for the command your-command.

Note: A process trying to write to a closed file descriptor will get an EBADF (bad file descriptor) error which is more likely to cause abortion than trying to write to | true. The latter would cause an EPIPE (pipe) error, see Charles Duffy's comment.

Buyse answered 5/8, 2017 at 20:31 Comment(3)
I wouldn't quite say "equivalent"; >&- actually closes the descriptor, and behavior is rather different (writes to a closed, and thus nonexistent, FD result in a different, more-likely-to-be-fatal error).Maddy
Compare python -c 'print "hello"' >&-, python -c 'print "hello"' | true and python -c 'print "hello"' > /dev/null.Buyse
... | true returns EPIPE, whereas >&- returns EBADF -- two completely separate errors. That the Python runtime doesn't distinguish between them usefully is neither here nor there.Maddy
M
2

If /dev/null is too much to type, you could (as root) do something like:

ln -s /dev/null /n

Then you could just do:

program >/n 2>&1

But of course, scripts you write in this way won't be portable to other systems without setting up that symlink first.

Mckenzie answered 30/5, 2009 at 1:1 Comment(2)
Combining with the answer above, I guess I could do: program &>/n which is pretty good. Thanks!Woozy
Should Have been program >&/nWoozy
I
2

It's also worth noting, that often times redirecting output is not really necessary. Many Unix and Linux programs accept a "silent flag", usually -n or -q, that suppresses any output and only returns a value on success or failure.

For example

grep foo bar.txt >/dev/null 2>&1
if [ $? -eq 0 ]; then
     do_something
fi

Can be rewritten as

grep -q foo bar.txt
if [ $? -eq 0 ]; then
     do_something
fi
Infantryman answered 16/2, 2017 at 13:56 Comment(1)
Checking $? unnecessarily is bad form, as opposed to if grep -q foo bar.txt; then -- it makes your code fragile, such that newly-added log lines can break your tests if someone doing such log instrumentation isn't cautious about where $? is expected to remain unchanged.Maddy
L
1

Ayman Hourieh's solution works well for one-off invocations of overly chatty programs. But if there's only a small set of commonly called programs for which you want to suppress output, consider silencing them by adding the following to your .bashrc file (or the equivalent, if you use another shell):

CHATTY_PROGRAMS=(okular firefox libreoffice kwrite)
for PROGRAM in "${CHATTY_PROGRAMS[@]}"
do
    printf -v eval_str '%q() { command %q "$@" &>/dev/null; }' "$PROGRAM" "$PROGRAM"
    eval "$eval_str"
done

This way you can continue to invoke programs using their usual names, but their stdout and stderr output will disappear into the bit bucket.

Note also that certain programs allow you to configure how much logging/debugging output they spew. For KDE applications, you can run kdebugdialog and selectively or globally disable debugging output.

Lanceted answered 23/8, 2017 at 11:25 Comment(4)
Why use a string as if it were a list? If you're writing native bash (and using the function keyword means your code isn't trying to be portable; POSIX ), then you're guaranteed to have arrays; chatty_programs=( okular firefox whatever ); for program in "${chatty_programs[@]}"; do; that way your code doesn't depend on the current value of IFS.Maddy
I'd also consider letting the shell perform quoting for you: printf -v eval_str '%q() { command %q "$@" &>/dev/null; }' "$program" "$program"; eval "$eval_str" -- that way if someone borrows the idiom and runs it with input names they don't control, some joker creating a script named $(rm -rf ~) (yes, that's a valid filename -- be sure to use single-quotes if trying to create it) won't cause them a bad day.Maddy
@CharlesDuffy: You are right; thanks for the suggested improvements. I have revised my answer accordingly.Lanceted
+1. That said, re: variable naming convention, see pubs.opengroup.org/onlinepubs/9699919799/basedefs/…, fourth paragraph -- all-caps names are used for variables with meaning to POSIX-specified tools (the OS or shell), whereas other names are reserved for application namespace and guaranteed not to change behavior of POSIX-specified tools. Staying out of the all-caps is thus not only useful for avoiding unintentionally overwriting PATH and the like, but also avoiding unintentional changes to shell-internal variables yet-to-be-introduced.Maddy
H
0

Seems to me, that the most portable solution, and best answer, would be a macro on your terminal (PC).

That way, no matter what server you log in to, it will always be there.

If you happen to run Windows, you can get the desired outcome with AHK (google it, it's opensource) in two tiny lines of code. That can translate any string of keys into any other string of keys, in situ.

You type "ugly.sh >>NULL" and it will rewrite it as "ugly.sh 2>&1 > /dev/null" or what not.

Solutions for other platforms are somewhat more difficult. AppleScript can paste in keyboard presses, but can't be triggered that easily.

Herder answered 9/3, 2011 at 19:8 Comment(0)
B
0

Not the most efficient solution, but I simply link dev/null on all my machines to /dev/0, got used to it and it saves some time kinda.

Babi answered 24/1, 2024 at 7:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.