2015-05-14 36 views
1

我正在写一个bash脚本,并使用下面的技巧到标准输出重定向到由三通消耗命名管道:进程替换返回提示

exec > >(tee -a $LOGFILE) 2>&1 

然而,脚本退出时,它不返回壳,直到我按下输入。有没有简单的方法来解决这个问题,同时仍然使用这种方法?

编辑:这是我在这个运行环境:简单的脚本的

Centos 7 
Bash version 4.2.45 

内容称为redirect.sh:

#!/bin/bash 
exec > >(tee -a /tmp/haha) 2>&1 
echo "hi there" 
exit 0 

样品会话:

[[email protected] ~]# ./redirect.sh 
[[email protected] ~]# hi there 

[[email protected] ~]# 
+1

未经测试:您退出脚本之前,关闭输出:'EXEC 1>& - 2>& - ' - 可能会关闭发球台。 –

+0

感谢您的评论,但它不起作用。 – duffsterlp

+0

我建议你用'set -x'运行你的脚本,这样你就可以看到发生了什么事情。我认为stdout重定向不需要你输入。 –

回答

1

提示正在打印;不幸的是,它在tee的输出被打印之前被打印(这是它在样本输出中出现在hi there之前的原因)。

由于tee进程是异步运行的,因此不能保证在脚本终止之前它将输出发送到控制台。您真正想要做的是关闭tee进程,然后等待它退出脚本之前终止。不幸的是,这不能通过进程替换来完成,但可以通过coprocesses(在bash 4中)或使用命名管道来完成,如bash: How do I ensure termination of process substitution used with exec?的回答中所解释的

对于更简单(但不可靠)的解决方案,关闭管道喂养tee过程(这将迫使其关闭),然后等待几毫秒:

#!/bin/bash 
exec 3>&1 > >(tee -a /tmp/haha) 2>&1 
echo "hi there" 
exec 1>&3 2>&3 
sleep 0.1 
+1

stdbuf -o0的添加无效。 – duffsterlp

+0

@duffsterlp:是的,这不可靠。增加了睡眠解决方案(也是不可靠的),但正确的解决方案是链接答案中的解决方案。也许我应该将其标记为重复项并删除我的答案。 – rici