160

I want to make my Bash scripts more elegant for the end user. How do I hide the output when Bash is executing commands?

For example, when Bash executes

yum install nano

The following will show up to the user who executed the Bash:

Loaded plugins: fastestmirror
base                                                     | 3.7 kB     00:00
base/primary_db                                          | 4.4 MB     00:03
extras                                                   | 3.4 kB     00:00
extras/primary_db                                        |  18 kB     00:00
updates                                                  | 3.4 kB     00:00
updates/primary_db                                       | 3.8 MB     00:02
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package nano.x86_64 0:2.0.9-7.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package         Arch              Version                Repository       Size
================================================================================
Installing:
 nano            x86_64            2.0.9-7.el6            base            436 k

Transaction Summary
================================================================================
Install       1 Package(s)

Total download size: 436 k
Installed size: 1.5 M
Downloading Packages:
nano-2.0.9-7.el6.x86_64.rpm                              | 436 kB     00:00
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
 Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <[email protected]>
 Package: centos-release-6-4.el6.centos.10.x86_64 (@anaconda-CentOS-201303020151.x86_64/6.4)
 From   : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : nano-2.0.9-7.el6.x86_64                                      1/1
  Verifying  : nano-2.0.9-7.el6.x86_64                                      1/1

Installed:
  nano.x86_64 0:2.0.9-7.el6

Complete!

Now I want to hide this from the user and instead show:

    Installing nano ......

How can I accomplish this task? I will definitely help to make the script more user friendly. In case an error occurs then it should be shown to the user.

I would like to know how to show same message while a set of commands are being executed.

3

9 Answers 9

326

Use this.

{
  /your/first/command
  /your/second/command
} &> /dev/null

Explanation

To eliminate output from commands, you have two options:

  • Close the output descriptor file, which keeps it from accepting any more input. That looks like this:

    your_command "Is anybody listening?" >&-
    

    Usually, output goes either to file descriptor 1 (stdout) or 2 (stderr). If you close a file descriptor, you'll have to do so for every numbered descriptor, as &> (below) is a special BASH syntax incompatible with >&-:

    /your/first/command >&- 2>&-
    

    Be careful to note the order: >&- closes stdout, which is what you want to do; &>- redirects stdout and stderr to a file named - (hyphen), which is not what what you want to do. It'll look the same at first, but the latter creates a stray file in your working directory. It's easy to remember: >&2 redirects stdout to descriptor 2 (stderr), >&3 redirects stdout to descriptor 3, and >&- redirects stdout to a dead end (i.e. it closes stdout).

    Also beware that some commands may not handle a closed file descriptor particularly well ("write error: Bad file descriptor"), which is why the better solution may be to...

  • Redirect output to /dev/null, which accepts all output and does nothing with it. It looks like this:

    your_command "Hello?" > /dev/null
    

    For output redirection to a file, you can direct both stdout and stderr to the same place very concisely, but only in bash:

    /your/first/command &> /dev/null
    

Finally, to do the same for a number of commands at once, surround the whole thing in curly braces. Bash treats this as a group of commands, aggregating the output file descriptors so you can redirect all at once. If you're familiar instead with subshells using ( command1; command2; ) syntax, you'll find the braces behave almost exactly the same way, except that unless you involve them in a pipe the braces will not create a subshell and thus will allow you to set variables inside.

{
  /your/first/command
  /your/second/command
} &> /dev/null

See the bash manual on redirections for more details, options, and syntax.

3
  • Hi, I know it's an old question but can the same be done conditionally? Like I want to hide the output under certain condition? I know I can replicate the same part under if-else but is there a better way to do so?
    – usamazf
    Commented Apr 6, 2018 at 14:12
  • 1
    @UsamaZafar I would do that by setting a variable ("shell parameter"), which you set to either /dev/null or /dev/stdout (or /path/to/a/logfile) conditionally earlier in the script, and then redirecting to that destination by using &> $output_dest (or whatever you name it). If you don't want to combine stdout and stderr in that case, you could redirect them separately like > $output_dest 2> $errors_dest. Commented Apr 6, 2018 at 17:03
  • I have no idea that this was the purpose of the braces.
    – user14098813
    Commented Apr 26, 2021 at 10:42
50

You can redirect stdout to /dev/null.

yum install nano > /dev/null

Or you can redirect both stdout and stderr,

yum install nano &> /dev/null.

But if the program has a quiet option, that's even better.

39

A process normally has two outputs to screen: stdout (standard out), and stderr (standard error).

Normally informational messages go to sdout, and errors and alerts go to stderr.

You can turn off stdout for a command by doing

MyCommand >/dev/null

and turn off stderr by doing:

MyCommand 2>/dev/null

If you want both off, you can do:

MyCommand >/dev/null 2>&1 

The 2>&1 says send stderr to the same place as stdout.

1
  • The suggestion for suppressing both doesn't work for me. But this does > /dev/null 2>&1
    – Brad
    Commented Mar 11, 2022 at 6:53
9

You can redirect the output to /dev/null. For more info regarding /dev/null read this link.

You can hide the output of a comand in the following ways :

echo -n "Installing nano ......"; yum install nano > /dev/null; echo " done."; 

Redirect the standard output to /dev/null, but not the standard error. This will show the errors occurring during the installation, for example if yum cannot find a package.

echo -n "Installing nano ......"; yum install nano &> /dev/null; echo " done.";

While this code will not show anything in the terminal since both standard error and standard output are redirected and thus nullified to /dev/null.

1
  • 1
    Great share ....dude can you show me how to output the same message only once for a set of commands Commented Aug 5, 2013 at 16:40
6

>/dev/null 2>&1 will mute both stdout and stderr

yum install nano >/dev/null 2>&1
4

You should not use bash in this case to get rid of the output. Yum does have an option -q which suppresses the output.

You'll most certainly also want to use -y

echo "Installing nano..."
yum -y -q install nano

To see all the options for yum, use man yum.

1
  • Thanks, I assumed yum had one since apt-get used -qq as well to suppress. This was helpful for what I am doing.
    – Hyperion
    Commented Sep 25, 2015 at 2:07
0

you can also do it by assigning its output to a variable, this is particularly useful when you don't have /dev/null.

Yes, I came across a situation when I can't use /dev/null.

The solution I found was to assign the output to a variable which I will never use there after:

hide_output=$([[ -d /proc ]] && [[ mountpoint -q /proc ]] && umount -l /proc)
0

This: command > /dev/null Or this: (to suppress errors as well) command > /dev/null 2>&1

Similar to lots of other answers but they didn't work for me with 2> being in front of dev/null.

-1
.SILENT:

Type " .SILENT: " in the beginning of your script without colons.

2
  • why do you write the colon in the answer if you don't need it? Or is it quotation marks you are referring to?
    – DrBeco
    Commented Feb 16, 2022 at 1:27
  • This syntax is for a Makefile and is not for bash or any other scripting language I am aware of. Makefiles are not scripts.
    – Jay M
    Commented Dec 1, 2022 at 13:51

Not the answer you're looking for? Browse other questions tagged or ask your own question.