Answers:
您正在寻找tee
。
有关man tee
详细信息,请参见。
要与之结合exec
,必须使用流程替代。(有关man bash
详细信息,请参阅。)
exec &> >(tee log.out)
echo "This is stdout"
echo "This is stderr" >&2
exec 2>&1 | tee -a log.out
只是在控制台上打印,没有在日志文件中。也许我使用的语法不正确?
tee
结合进程替代进行了撰写。
the-script | wc -l
,例如,如果有人这样做,那也将计算错误行,并且您将看不到错误。
你可以做:
: > log # empty log file if necessary
{ { {
...the script
} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log >&2 3>&-
} 3>&1
exit "${PIPESTATUS[0]}"
您也可以将其编写为:
: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)
...the script
但是因为bash并不等待以>(...
)开头的进程,所以这种讨厌的效果是有时在命令返回后有时会向终端输出一些东西,如果终端具有“ tostop”属性,它甚至会产生更恶劣的影响(例如静默丢弃该输出)。开启。
无论如何,通过stdout
在两个解决方案中都使用管道,并且由于两个命令独立地输出输出和错误消息,这将影响输出缓冲以及输出和错误消息的显示顺序。
tee -a log >&2 3>&-
我知道这是旧帖子,但为什么不这样做呢?
echo "hi" >> log.txt #stdout -> log
echo "hi" | tee -a log.txt #stdout -> log & stdout
echo "hi" &>> log.txt #stdout & stderr -> log
echo "hi" |& tee -a log.txt #stdout & stderr -> log & stdout
当然,如果您需要标准输出,则可以定期打印。
只需使用这两个基本命令,就可以使用任意所需的流组合来完成此操作。
我知道我来这里时并没有得到一个易于理解/实施的答案,希望这对正在苦苦挣扎的其他人有所帮助。
顺便说一下,对于像我之前的自我那样的菜鸟,所有tee
命令所做的都是将stdin输入输出到stdout以及指定为后续参数的文件。-a
代表append,因此您不必每次使用命令都覆盖文件。如果您还有其他问题,我认为这对于快速学习bash是非常有用的资源。
完成此操作的另一种方法是在函数内使用重定向。
#!/bin/bash
function1 () {
echo 'STDOUT from function 1'
echo 'STDERR from function 1' >&2
}
function2 () {
echo 'STDOUT from function 2'
echo 'STDERR from function 2' >&2
}
function3 () {
echo 'STDOUT from function 3'
echo 'STDERR from function 3' >&2
}
main() {
function1
function2
function3
}
main 2>&1 |tee log.txt
在这里,我们有一个main
调用所有其他函数的函数。现在重定向STDOUT
和STDERR
中main
发挥作用tee
。