Shell,将所有输出重定向到文件,但仍打印echo。

3

我有多个vagrant provisions(shell脚本),希望将所有命令输出重定向到文件,同时保留echo输出在stdout中。

目前我通过以下方式重定向所有输出:

exec &>> provision.log

每个条款的开头

这很好用,但是控制台没有任何输出。因此,我想将除了echo命令以外的所有内容都重定向到一个文件中。

如果有可能将所有输出(包括echo)都重定向到一个文件中,并且只在stdout中保留echo,那么这将是最好的。

结果应该如下所示:

控制台

Starting provision "master"
Updating packages...
Installing MySQL...
ERROR! check provision.log for details

provision.log

Starting provision "master"
Updating packages...
...
(output from apt-get)
...
Installing MySQL...
...
(output from apt-get install mysql-server-5.5)
...
ERROR! check provision.log for details

我知道我可以将输出重定向附加到每个命令,但那样会很混乱。

2个回答

4
您可以采用复制stdout文件描述符并使用自定义的echo函数重定向到复制的文件描述符的方法。
#!/bin/bash

# open fd=3 redirecting to 1 (stdout)
exec 3>&1

# function echo to show echo output on terminal
echo() {
   # call actual echo command and redirect output to fd=3 and log file
   command echo "$@"
   command echo "$@" >&3
}

# redirect stdout to a log file    
exec >>logfile

printf "%s\n" "going to file"
date
echo "on stdout"
pwd

# close fd=3
exec 3>&-

魔法!现在回显输出有点问题了。某些行出现在其他行之前/之后。 - Tomas
运行得非常好!谢谢。现在我只需要弄清楚如何在vagrant上全局设置它,这样我就不必在每个provision文件中都包含它了。顺便问一下,当我执行echo "Nginx version $(nginx -v)时,它会打印出nginx -v的第一行结果和第二行的Nginx version。有什么办法让它们在同一行上吗? - Tomas
似乎只是针对某些软件包,一些软件包版本被打印在同一行上。 - Tomas
可能是因为nginx将其写入了标准错误输出。nginx -V | cat -vte对你显示了什么? - anubhava
让我们在聊天中继续这个讨论 - Tomas
显示剩余3条评论

0

您可以仅重定向stdout并保留stderr在终端显示。当然,您的脚本应该使用echo something > /dev/stderrecho something >&2输出到stderr

您也可以将echo-s重定向到/dev/tty,这只有在脚本是在终端上启动(而不是通过atcrontab)时才有意义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接