Wax
Wax

Reputation: 127

Redirect STDOUT by variable in Bash

I want to create a script which can be run both in verbose and silent mode if preferred. My idea was to create a variable which contains "&> /dev/null" and if the script is runned silently I just clear it. The silent mode works fine but if I want to pass this as the last "argument" to something (see my example down) it does not work.

Here is an example: I want to zip something (I know there is a -q option, the question is more like theorethical) and if I write this it works as I intended:

$ zip bar.zip foo
  adding: foo (stored 0%)
$ zip bar.zip foo &> /dev/null
$

But when I declare the &> /dev/null as a variable I get this:

$ var="&> /dev/null"
$ zip bar.zip foo "$var"
zip warning: name not matched: &> /dev/null
updating: foo (stored 0%)

I saw other solutions to redirect parts of the script by intention but I'm curious if my idea can work and if not, why not? It would be more convenient to use something like this in my script because I only need to redirect some lines or commands but too much to surround each with an if:

I'm trying something like this to be clear:

if verbose
verbose="&> /dev/null"
else
verbose=

command1 $1 $2
command2 $1
command3 $1 $2 $3 "$verbose"
command4

Upvotes: 4

Views: 8712

Answers (2)

chepner
chepner

Reputation: 531125

bash will recognize a file name of /dev/stdout as standard output, when used with a redirection, whether or not your file system has such an entry.

# If an argument is given your script, use that value
# Otherwise, use /dev/stdout
out=${1:-/dev/stdout}

zip bar.zip foo > "$out"

Upvotes: 9

Eddie
Eddie

Reputation: 10138

Your issue is the order of expansion performed by the shell. The variable is replaced by your stdout redirect AFTER passing the commands to the command zip

You need the shell to expand that variable BEFORE invoking zip command. TO do this you can use eval which takes a first pass at expanding variables and such.

eval zip bar.zip foo "$var"

However be weary of using eval, as unchecked values can lead to exploits, and its use is generally discouraged.

You could consider setting up your own file descriptor and set that to be /dev/null, a real file, or even stdout. ANd then each command that should go to one of those would be:

zip bar.zip foo > 3

http://www.tldp.org/LDP/abs/html/io-redirection.html#FDREF

Upvotes: 0

Related Questions