Search code examples
bashshellfile-descriptor

How to put stdout file descriptor in a variable?


I am using echo var >> "${log_file}" 2>&1 to redirect stdout and stderr to a file path stored in the ${log_file}. But when the variable is empty, I would like to send stdout and stderr to their default/standard locations.

For example, if the variable ${log_file} is empty, the output should not go to a file, but to stdout. How I should set the ${log_file} variable value to make it output to stdout?

I tried setting to &1 (the stdout file descriptor)

if [[ -z "${log_file}" ]]; then
    log_file=&1
fi

echo var >> "${log_file}" 2>&1

But it did not work and bash threw this error:

No such file or directory
1: command not found

Solution

  • You have two fundamentally different operations based on the value of the variable:

    1. Redirection both stderr and stdout to the named file
    2. Don't redirect either.

    There's no syntax to handle this dichotomy. I would recommend the following:

    1. Wrap the command whose output you might want to redirection in a function.

      func () {
          echo var
      }
      
    2. Use an if statement to call that function with and without redirection, as necessary.

      if [ -n "$log_file" ]; then
          func >> "$log_file" 2>&1
      else
          func
      fi
      

    Another approach is to define func conditionally, attaching the redirection directly to the function.

    if [ -n "$log_file" ]; then
        func () {
            echo var
        } >> "$log_file" 2>&1
    else
        func () { 
            echo var
        }
    fi
    
    func