将 stdout 和/或 stderr 重定向到变量中的路径

将 stdout 和/或 stderr 重定向到变量中的路径

如何将 stdout 和/或 stderr 重定向到我在变量中指定的路径?笔记:我不想覆盖变量本身,我想让std[xxx]写入变量中指定的文件。

例如,一个简单的脚本,如果命令scp失败,它不会将失败消息打印到stderror stdout(我不确定失败时输出到哪个),而是将其输出到指定的日志文件。日志文件的路径存储在$LOG变量中:

LOG=/path/to/file.log
scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
    whatever
else
    # else log both stdout/stderr to ${LOG} file
    &>"${LOG}"
    # DEBUG - print contents of ${LOG} var for testing purposes
    printf "${LOG}"

该脚本的结果不会显示/path/to/file.log文件中的任何内容,并且简单打印/path/to/file.logstdout.所以就好像什么也没写一样&>

我已经确认我的特定scp命令有效,所以我知道这不是潜在的问题。

或者这是否是处理自定义日志文件的最正确方法?配置自己的日志系统是否有比在变量中存储日志文件路径更好的做法?

答案1

看来您最终对这个问题的结果感到满意,但我提出了不同的建议。

#!/bin/bash
LOG=/path/to/file.log    
DEBUG=0 # 0 = True, 1 = False
OUTPUT=$(scp file1 host@remote 2>&1)

# do 'whatever' if scp command succeeds:
if [ $? -eq 0 ];
then
    echo "Success"
elif [[ DEBUG -eq 0 ]]
    # else log both stdout/stderr to ${LOG} file and user
    # DEBUG - Use tee to display ${LOG} contents efficiently
    printf "$OUTPUT" | tee $LOG
else
    # Send output to $LOG
    printf "$OUTPUT" >> $LOG
fi

无论如何,本质上都是在变量中捕获 STDIN/STDOUT,如果成功则执行“任意操作”,但如果失败则将 STDIN/STDOUT 重定向到$LOG.此外,通过$DEBUG标志,您可以同时显示tee内容。$OUTPUT$LOG

另外,对于整数比较,您确实应该使用-eq而不是=or==

答案2

看起来您正在尝试记录输出你运行命令,这是不可能的。

如果您想无条件记录命令的输出scp,那么您只需将重定向运算符包含在与命令本身相同的行上,即:

&>"${LOG}" scp file1 host@remote

如果您只想在命令失败时保存日志输出(正如您试图在代码中执行的那样),那么将输出重定向到临时文件,然后将文件移动到所需位置怎么样?它可能看起来像这样:

#!/bin/bash

# Set path the real log file location
LOG=/path/to/file.log

# Create a temporary file to capture standard output and standard error
TEMPLOG="$(mktemp)"

# Run command and redirect output to temporary logfile
2>"${TEMPLOG}" scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
    echo 'Command successful!'

# else log both stdout/stderr to ${LOG} file
else
    # Move the log file from the temporary location to the desired location
    mv "${TEMPLOG}" "${LOG}"

    # DEBUG - print contents of ${LOG} var for testing purposes
    printf "${LOG}"
fi

相关内容