如何根据条件将Bash脚本的输出写入文件?
解决方法
你的核心问题是先产生了输出,再判断是否写入文件,这时候已经没法回溯控制之前的输出了。必须先根据用户输入的结果,决定是否启用tee的输出捕获,再执行后续的输出逻辑。下面是两种可行的实现方式:
方法一:用exec重定向标准输出(推荐)
这种方式可以一次性配置好后续所有输出的处理逻辑,无需重复代码:
read -p "Enter (1-4): " # 根据输入判断是否开启文件写入 if [ "$REPLY" = "1" ]; then # 将标准输出同时定向到终端和日志文件 # 如果需要同时捕获错误输出,加上 2>&1 exec > >(tee -a "$(date +%F).txt") 2>&1 fi # 后续所有输出都会自动应用上面的规则 echo "foo" if [ "$REPLY" = "1" ]; then echo "writing to file" fi # 脚本其他逻辑... # 比如测试错误输出是否被捕获 ls non_existent_file
原理说明
exec > >(tee -a file.txt) 会替换当前shell的标准输出:后续所有命令的标准输出都会被送到tee命令,tee会同时把内容输出到终端和追加到指定文件。加上2>&1可以让标准错误也跟着标准输出走,实现错误信息也写入文件。
方法二:用代码块分支执行
如果不想修改shell的全局输出配置,可以把所有输出逻辑放到分支里,避免代码重复的话可以用函数:
# 定义所有输出逻辑为函数 script_logic() { echo "foo" if [ "$1" = "1" ]; then echo "writing to file" fi # 脚本其他逻辑... } read -p "Enter (1-4): " if [ "$REPLY" = "1" ]; then # 输入1时,通过tee写入文件并输出到终端 script_logic "$REPLY" | tee -a "$(date +%F).txt" else # 其他输入时,直接输出到终端 script_logic "$REPLY" fi
为什么你之前的方法无效?
你之前的写法是先执行了输出内容,再判断是否用tee,但此时输出已经发送到标准输出了,判断逻辑在输出之后,根本没法控制之前的内容是否写入文件。必须先判断,再执行输出逻辑。
内容的提问来源于stack exchange,提问作者AlexK
相关产品推荐
相关产品推荐

