Search code examples
bashshell

Redirect/pipe (or not) via a variable?


I'd like to be able to redirect a command, or not, by setting a variable - this is my attempt that doesn't work, does anyone know why/how I can get it to?

# REDIRECT is not set - this works fine
$ echo hi ${REDIRECT}
hi

# If I set this, I want to redirect to tmp...
$ REDIRECT="> /tmp/tmp"

# ...but this passes it as an argument to echo
$ echo hi ${REDIRECT}
hi > /tmp/tmp

I can't just set REDIRECT to the filename as sometimes I don't want to redirect at all, and later I'll possibly want to pipe (e.g. REDIRECT="| tee -a ...").

Anyone know how I can get bash to interpret the values as redirects, not arguments?


Solution

  • It sounds like an XY problem. Rather than trying to redirect based on a variable, just do the redirect when you otherwise would have set the variable. In other words, instead of:

    # BROKEN
    if want_to_redirect; then
        REDIRECT="> /tmp/tmp"
    fi
    echo hi $REDIRECT   # DOES NOT WORK
    

    You can do:

    exec 3>&1
    if want_to_redirect
        exec > /tmp/tmp
    fi
    echo hi
    
    # If you want output of further commands to go back
    # to the original output stream:
    exec >&3
    

    In the above want_to_redirect is some command that perhaps checks the environment or in some way decides whether or not you want to redirect; it's not really important what it is. The point is: redirect the output of the shell, since all the commands that the shell executes will inherit its output streams.