我想将流程的标准输出和标准错误重定向到单个文件。我在巴什怎么做?


当前回答

bash your_script.sh 1>file.log 2>&1

1> log指示shell将标准输出发送到file.log文件,2>&1告诉它将标准错误(文件描述符2)重定向到标准输出(文件描述符1)。

注意:正如liw.fi指出的那样,顺序很重要,2>&11>file.log不起作用。

其他回答

“最简单”的方法(仅限Bash 4):

ls * 2>&- 1>&-
LOG_FACILITY="local7.notice"
LOG_TOPIC="my-prog-name"
LOG_TOPIC_OUT="$LOG_TOPIC-out[$$]"
LOG_TOPIC_ERR="$LOG_TOPIC-err[$$]"

exec 3>&1 > >(tee -a /dev/fd/3 | logger -p "$LOG_FACILITY" -t "$LOG_TOPIC_OUT" )
exec 2> >(logger -p "$LOG_FACILITY" -t "$LOG_TOPIC_ERR" )

它是相关的:将标准输出和标准错误写入syslog。

它几乎可以工作,但不能从xinetd;(

奇怪的是,这是有效的:

yourcommand &> filename

但这会产生语法错误:

yourcommand &>> filename
syntax error near unexpected token `>'

您必须使用:

yourcommand 1>> filename 2>&1

以下函数可用于自动切换stdout/stderr和日志文件之间的输出。

#!/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"
    }

脚本内部用法示例:

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"

我想要一个解决方案,将stdout和stderr的输出写入日志文件,并且stderr仍在控制台上。所以我需要通过tee复制stderr输出。

这是我找到的解决方案:

command 3>&1 1>&2 2>&3 1>>logfile | tee -a logfile

第一次交换stderr和stdout然后将stdout附加到日志文件将stderr管道到tee,并将其附加到日志文件中