If you want to hide all output from the commands you're running (both output and errors), but still be able to print messages yourself, then Hauke Laging's approach is absolutely the right way to do this.
It lets you keep a reference to stdout (aka file descriptor 1) and stderr (aka file descriptor 2), redirect them to /dev/null, but still use them if you want a message to be shown. I'd just like to add a bunch of commenting that explains exactly what it's doing.
exec 3>&1 # Open file descriptor 3, writing to wherever stdout currently writes
exec 4>&2 # Open file descriptor 4, writing to wherever stderr currently writes
exec 1>/dev/null # Redirect stdout to /dev/null, leaving fd 3 alone
exec 2>/dev/null # Redirect stderr to /dev/null, leaving fd 4 alone
# Programs won't show output by default; they write to fd 1 which is now /dev/null.
# This is because programs inherit file descriptors from the shell by default.
# You can choose to show messages by having them write to fd 3 (old stdout) instead.
# This works by saying that echo's fd 1 (stdout) is the shell's fd 3.
echo bar >&3
# And when you're done you can reset things to how they were to start with
exec 1>&3 # Point stdout to where fd 3 currently points (the original stdout)
exec 2>&4 # Point stderr to where fd 4 currently points (the original stderr)
exec 3>&- # Close fd 3 (it now points to the same spot as fd 1, so we don't need it)
exec 4>&- # Close fd 4 (it now points to the same spot as fd 1, so we don't need it)
If you're going to use this in a script of any size, and you'll often want to print status updates about how things are going, you'll probably want to create helper functions that do
echo "$@" >&3 and
echo "$@" >&4 for printing out messages to the original stdout and stderr, so you don't have to pepper references to
&4 all over your script.
And this bash-hackers.org redirection tutorial is a pretty good visual depiction of how moderately complex redirections like these are actually working.