Redirect stderr and stdout in Bash

后端 未结 15 963
日久生厌
日久生厌 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:47

    The following functions can be used to automate the process of toggling outputs beetwen stdout/stderr and a logfile.

    #!/bin/bash
    
        #set -x
    
        # global vars
        OUTPUTS_REDIRECTED="false"
        LOGFILE=/dev/stdout
    
        # "private" function used by redirect_outputs_to_logfile()
        function save_standard_outputs {
            if [ "$OUTPUTS_REDIRECTED" == "true" ]; then
                echo "[ERROR]: ${FUNCNAME[0]}: Cannot save standard outputs because they have been redirected before"
                exit 1;
            fi
            exec 3>&1
            exec 4>&2
    
            trap restore_standard_outputs EXIT
        }
    
        # Params: $1 => logfile to write to
        function redirect_outputs_to_logfile {
            if [ "$OUTPUTS_REDIRECTED" == "true" ]; then
                echo "[ERROR]: ${FUNCNAME[0]}: Cannot redirect standard outputs because they have been redirected before"
                exit 1;
            fi
            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
    
            save_standard_outputs
    
            exec 1>>${LOGFILE%.log}.log
            exec 2>&1
            OUTPUTS_REDIRECTED="true"
        }
    
        # "private" function used by save_standard_outputs() 
        function restore_standard_outputs {
            if [ "$OUTPUTS_REDIRECTED" == "false" ]; then
                echo "[ERROR]: ${FUNCNAME[0]}: Cannot restore standard outputs because they have NOT been redirected"
                exit 1;
            fi
            exec 1>&-   #closes FD 1 (logfile)
            exec 2>&-   #closes FD 2 (logfile)
            exec 2>&4   #restore stderr
            exec 1>&3   #restore stdout
    
            OUTPUTS_REDIRECTED="false"
        }
    

    Example of usage inside script:

    echo "this goes to stdout"
    redirect_outputs_to_logfile /tmp/one.log
    echo "this goes to logfile"
    restore_standard_outputs 
    echo "this goes to stdout"
    

提交回复
热议问题