我想将stdout复制到来自的 bash脚本中的日志文件,这意味着我不想通过输出管道调用脚本来发送tee,我希望脚本本身能够处理它。我已成功使用this答案来完成此操作,使用以下代码:
#!/bin/bash
exec > >(sed "s/^/[${1}] /" | tee -a myscript.log)
exec 2>&1
# <rest of script>
echo "hello"
sleep 10
echo "world"
这样可行,但是在脚本完成之前,输出的缺点是缓冲,如链接的答案中所述。在上面的例子中,只有在10秒过后,“hello”和“world”才会显示在日志中。
我知道stdbuf命令,如果用
运行脚本stdbuf -oL ./myscript.sh
然后stdout确实连续打印到文件和终端。 但是,我希望这也可以在脚本中处理。有没有办法将这两种解决方案结合起来?我宁愿不使用一个包装脚本来简单地调用用“stdbuf -oL”括起来的原始脚本。
答案 0 :(得分:0)
如果存在特殊参数,您可以使用变通方法并使脚本使用stdbuf
执行自身:
#!/bin/bash
if [[ "$1" != __BUFFERED__ ]]; then
prog="$0"
stdbuf -oL "$prog" __BUFFERED__ "$@"
else
shift #discard __BUFFERED__
exec > >(sed "s/^/[${1}] /" | tee -a myscript.log)
exec 2>&1
# <rest of script>
echo "hello"
sleep 1
echo "world"
fi
这将主要起作用:
./test
运行脚本,则会显示无缓冲的[] hello\n[] world
。./test 123 456
运行脚本,则会显示您想要的[123] hello\n[123] world
。bash test
运行它 - $0
设置为test
,而不是您的脚本。但是,解决这个问题并不在这个问题的范围内。答案 1 :(得分:0)
第一个解决方案的延迟是由sed
引起的,而不是tee
引起的。试试这个:
#!/bin/bash
exec 6>&1 2>&1>&>(tee -a myscript.log)
要“撤消”tee
效果:
exec 1>&6 2>&6 6>&-