3

I want to be able to specify the redirection command/options via a variable (that I might set based on certain conditions, etc.). But when I run this bash script for example :

REDIRECT=">>test"
exec echo hi ${REDIRECT}

I get (via bash -x output) :

+ REDIRECT='>>test'
+ exec echo hi '>>test'
hi >>test

It looks like exec is placing the value of REDIRECT variable inside single quotes, instead of literally substituting its value.

How can I fix/get around this?

2
  • What's the reason you'd like to do this? If you want to change where the redirected output goes to, then you could instead just have an outfile variable and exec echo hi >>$outfile, or do you sometimes want to append and sometimes not?
    – Kusalananda
    Commented Jul 26, 2016 at 17:09
  • I want to sometimes output to a file, and sometimes to stdout. (This would be controlled by an argument to the script).
    – user98708
    Commented Jul 26, 2016 at 17:10

3 Answers 3

3

To avoid using eval:

opt_file=""

# Command line parsing bit here, setting opt_file to a
# file name given by the user, or leaving it empty.

if [[ -z "$opt_file" ]]; then
  outfile="/dev/stdout"
else
  outfile="$opt_file"
fi

exec echo hi >>"$outfile"

A slightly shorter variant that does the same thing:

# (code that sets $opt_out to a filename, or not,
# and then...)

outfile=${opt_file:-/dev/stdout}
exec echo hi >>"$outfile"
1
  • when using that on linux, all the caveats about /dev/stdout, /dev/fd/1, /proc/self/fd/1 being not really the same thing as the standard out fd apply: su otheruser -c 'echo OK; echo NOK >/dev/stdout' => bash: /dev/stdout: Permission denied, sh -c 'echo a; echo b >/dev/stdout' >file => only writes b to file, etc.
    – user313992
    Commented Sep 20, 2019 at 6:41
1

I think that the only way to do this would be to use eval and all classic caveats about eval would apply. That said, you could do something like this:

REDIRECT=">>test"
eval echo hi ${REDIRECT}
0

You can redirect the whole of stdout to a file with the exec command eg

exec >> outfile

Now any output will be sent to outfile.

For example:

#!/bin/bash

exec >> outfile

echo start
echo hello
echo there
echo end

If we run this:

$ ./x

$ cat outfile 
start
hello
there
end

$ ./x

$ cat outfile
start
hello
there
end
start
hello
there
end

So we can see each execution appends.

This becomes simple to add in a test

if [ -n "$REDIRECT" ]
then
  exec >> $REDIRECT
fi

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .