在 bash 脚本中将输出重定向到日志文件和控制台时出现问题

在 bash 脚本中将输出重定向到日志文件和控制台时出现问题

我有一个 shell 脚本,它同时成功地将所有输出重定向到日志文件和标准输出(控制台)。但是,当它退出时,它似乎等待键盘上的一些用户输入(实验上,任何键似乎都可以工作)...所以,我运行脚本,查看输出,它退出,我必须先按空格键终端提示符再次出现。然后键入echo $?会给出正确的退出代码。

该脚本的基础知识是:

#!/bin/bash
LOG="./test.log"
rm -f $LOG
exec > >(tee $LOG) 2>&1
if [[ "$1" = "T" ]]; then
 echo "twas true..."
 exit 0
else
 echo "twas false..."
 exit 100
fi

感谢任何帮助...我不仅不想按空格键,而且我想了解发生了什么事?

修正案: 看来我得打了进入恢复终端提示。根据我有限的使用经验附注命令看起来我的脚本已经终止并且巴什shell 处于可中断睡眠状态S。看来终端提示输出可能已被消耗或错误重定向?我不明白为什么......

答案1

我可以在我的机器上重现您的问题。我看到它$PS1是在执行时打印的tee $LOG,但不是在脚本结束后打印的。执行脚本后,命令提示符为空,但您实际上可以键入下一个命令,它将被执行。

看起来进程替换在后台>()运行。tee然后exec将所有输出重定向到该后台进程。但tee后台仍然将其输出打印到终端。如果你运行你会看到这样的东西syslog | tee&

当所有 shell 输出都到达后台进程时tee,bash 打印了一个命令提示符$PS1,这意味着您已经可以输入新命令了。并且仅在打印命令提示符后,您的echo命令才会将其输出打印到后台进程tee,然后将tee其打印到终端。

就好像你运行了整个脚本背景

这就是我所理解的为什么整个脚本执行后命令提示符没有被打印的原因。就像echo "twas true..." | tee $LOG&。这里的&意思是“在后台运行前面的命令”。

尝试以下代码。它会做同样的事情,但没有这个问题。

#!/bin/bash
LOG="./test.log"
rm -f $LOG
{
    if [[ "$1" = "T" ]]; then
     echo "twas true..."
     exit 0
    else
     echo "twas false..."
     exit 100
    fi
} | tee $LOG 2>&1

还。默认情况下tee重写文件,因此看起来rm -f $LOG不需要。

相关内容