Redirect stderr and stdout in Bash

后端 未结 15 791
日久生厌
日久生厌 2020-11-22 08:18

I want to redirect both stdout and stderr of a process to a single file. How do I do that in Bash?

相关标签:
15条回答
  • 2020-11-22 08:42

    I wanted a solution to have the output from stdout plus stderr written into a log file and stderr still on console. So I needed to duplicate the stderr output via tee.

    This is the solution I found:

    command 3>&1 1>&2 2>&3 1>>logfile | tee -a logfile
    
    • First swap stderr and stdout
    • then append the stdout to the log file
    • pipe stderr to tee and append it also to the log file
    0 讨论(0)
  • 2020-11-22 08:44

    Take a look here. Should be:

    yourcommand &>filename
    

    (redirects both stdout and stderr to filename).

    0 讨论(0)
  • 2020-11-22 08:44

    In situations when you consider using things like exec 2>&1 I find easier to read if possible rewriting code using bash functions like this:

    function myfunc(){
      [...]
    }
    
    myfunc &>mylog.log
    
    0 讨论(0)
  • 2020-11-22 08:44

    For tcsh, I have to use the following command :

    command >& file
    

    If use command &> file , it will give "Invalid null command" error.

    0 讨论(0)
  • 2020-11-22 08:45

    @fernando-fabreti

    Adding to what you did I changed the functions slightly and removed the &- closing and it worked for me.

        function saveStandardOutputs {
          if [ "$OUTPUTS_REDIRECTED" == "false" ]; then
            exec 3>&1
            exec 4>&2
            trap restoreStandardOutputs EXIT
          else
              echo "[ERROR]: ${FUNCNAME[0]}: Cannot save standard outputs because they have been redirected before"
              exit 1;
          fi
      }
    
      # Params: $1 => logfile to write to
      function redirectOutputsToLogfile {
          if [ "$OUTPUTS_REDIRECTED" == "false" ]; then
            LOGFILE=$1
            if [ -z "$LOGFILE" ]; then
                echo "[ERROR]: ${FUNCNAME[0]}: logfile empty [$LOGFILE]"
            fi
            if [ ! -f $LOGFILE ]; then
                touch $LOGFILE
            fi
            if [ ! -f $LOGFILE ]; then
                echo "[ERROR]: ${FUNCNAME[0]}: creating logfile [$LOGFILE]"
                exit 1
            fi
            saveStandardOutputs
            exec 1>>${LOGFILE}
            exec 2>&1
            OUTPUTS_REDIRECTED="true"
          else
            echo "[ERROR]: ${FUNCNAME[0]}: Cannot redirect standard outputs because they have been redirected before"
              exit 1;
          fi
      }
      function restoreStandardOutputs {
          if [ "$OUTPUTS_REDIRECTED" == "true" ]; then
          exec 1>&3   #restore stdout
          exec 2>&4   #restore stderr
          OUTPUTS_REDIRECTED="false"
         fi
      }
      LOGFILE_NAME="tmp/one.log"
      OUTPUTS_REDIRECTED="false"
    
      echo "this goes to stdout"
      redirectOutputsToLogfile $LOGFILE_NAME
      echo "this goes to logfile"
      echo "${LOGFILE_NAME}"
      restoreStandardOutputs 
      echo "After restore this goes to stdout"
    
    0 讨论(0)
  • 2020-11-22 08:46
    do_something 2>&1 | tee -a some_file
    

    This is going to redirect stderr to stdout and stdout to some_file and print it to stdout.

    0 讨论(0)
提交回复
热议问题