I have put a very large bash script together that installs packages and configures a LAMP stack etc. With any scripting I usually do, I like to tidy it up by using echo commands to let the user running the script know what's happening on screen and suppressing all output from executed commands using > /dev/null 2>&1. Currently my scripts take the following form: (N.B the use of /dev/null 2>&1 is what I want to avoid using)
echo -n "Starting foo... "
command 1 > /dev/null 2>&1
command 2 > /dev/null 2>&1
echo "Done"
Now I could carry on doing this with all Unix based scripts, but with the amount of lines of code I have it will certainly be a tedious job. Luckily enough I have plenty of comments for command in hand so these can be easily converted to echo commands. However, I would still only like to pass echo commands through and hide the output of every other command without the need of > /dev/null 2>&1. However, if an error does occur I would still like to these to show.
Is there a global parameter that disables stdout except from certain commands such as echo?
UPDATE 2
I found a similar post to mine on stackoverflow here
exec 3>&1 &>/dev/null
some_command
another_command
command_you_want_to_see >&3
command3
3>&1
redirects any command suffixed with >&3
to a new file descriptor which redirects out &1
(STDOUT). In regards to &>/dev/null
I assume this this suppresses all output to /dev/null
?
In my example this script below:
#!/bin/bash
# Hide all output by default
exec 3>&1 &>/dev/null
echo -n "outputting text to file... " >&3
echo "hello world" > ~/"hello_world_output.txt"
echo "I am hidden from output"
echo "Done" >&3
produces the following output:
user@ubuntu:~$ ./test.sh
outputting text to file... Done
user@ubuntu:~$
UPDATE 3
Could you place the below snippets into an example script so that I can see it as a whole with some example commands please? The first example says it can be defined at the beginning of the script. Do I place the rest of my script under the closed bracket?
echo() (
if { true >&3; } 2>/dev/null; then
exec >&3
fi
command echo "$@"
)
Again do I place the rest of my script under this snippet?
exec 3>&1 >/dev/null
echo() (
>&3 command echo "$@"
)