我想在bash脚本中提供可选的日志记录参数,并希望从一开始就使用exec
到tee
管道。但是,打开tee
进程导致脚本挂起,我相信因为stdout没有关闭:
# Output to a log file, if set
if [[ $OPT_LOG ]]; then
exec > >(tee -a $OPT_LOG)
fi
我试图结束:
exec >&-
但它仍然挂起 - 有没有另一种正确关闭tee
的方法,以便脚本在执行结束时正确退出?
答案 0 :(得分:4)
由于某些原因,使用tee
似乎会停止显示提示符($PS1
),因为shell脚本尚未退出。作为解决方法,我通常在调用sleep
后使用短tee
。
#!/bin/bash
exec > >(tee -a mylog)
sleep .1
# my code
答案 1 :(得分:3)
将评论转换为答案,并进行少量修改。
我noted:
以下代码在Mac OS X 10.10.3上为我退出。
OPT_LOG=file.name if [[ $OPT_LOG ]] then exec > >(tee -a $OPT_LOG) fi for ((i = 0; i < 10; i++)) do echo "Logging message $i at $(date)" sleep 1 done
您的问题可能在您未显示的代码中。你在运行什么命令?你从
bash -x yourscript.sh
获得了什么?
如果您从示例中删除了睡眠和日期调用,则安德鲁告诉该脚本不再正常退出:
OPT_LOG=file.name; if [[ $OPT_LOG ]]; then exec > >(tee -a $OPT_LOG); fi; for ((i = 0; i < 10; i++)); do echo "Logging message $i"; done
我回答说:
现在这是一个有趣的观察!我可以重现你的结果。
我试验了一下:
pwd
,只是'只有回声',这不会影响事情(但pwd
可能是内置的Bash)。bash -c 'exit 0'
(不是内置的),代码终止了。> >(tee -a $OPT_LOG &)
并且输出没有出现。 (我觉得这很令人惊讶,但这是一次尝试的解决方法,而不是工作的主要部分。)我的印象是安德鲁在Bash中发现了一个可以被报道的错误。 (有关如何执行此操作,请参阅Reporting Bugs上的Bash手册。)我认为不会因为I / O重定向没有执行外部命令而退出。我可以确认Apple的Bash 3.2.57有问题; Bash 4.3.27也是如此(我为自己构建的,所以它修补了ShellShock bug的修复程序。)
shell脚本不会调用任何外部命令,并且在exec重定向之后调用任何外部命令似乎可以抑制该错误,这是相对不寻常的。
它还确认chatraed的workaround有效,尽管速度比最低限度要慢。对于生产用途,我选择sleep 0
,其速度比sleep 0.1
快十分之一秒。只有一秒钟的睡眠只适用于某些系统;经典地(并且根据POSIX),sleep
不会在小数秒内睡眠。 OTOH,如果你在不支持小数秒的系统上编写sleep 0.1
,包括领先的0
,可能会让它在零秒内休眠;写.1
可能会或可能不会产生相同的效果。