如何将 stdout 和/或 stderr 重定向到我在变量中指定的路径?笔记:我不想覆盖变量本身,我想让std[xxx]写入变量中指定的文件。
例如,一个简单的脚本,如果命令scp
失败,它不会将失败消息打印到stderr
or 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.log
到stdout
.所以就好像什么也没写一样&>
。
我已经确认我的特定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