#!/bin/bash
STATUSFILE=x.out
LOGFILE=x.log
### All output to screen
### Do nothing, this is the default
### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1
### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1
### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)
### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)
### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}
### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)
### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}
### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)
echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}
我想你还是想在终端上看到STDERR和STDOUT。你可以去找乔希·凯利的答案,但我发现在后台保留一个
tail
,它会输出你的日志文件,非常烦琐。请注意,您需要保存一个exra FD,并通过终止它来进行清理,技术上应该在trap '...' EXIT
中这样做。有更好的方法可以做到这一点,而且您已经发现了:
tee
。只是,不要只把它用在stdout上,要有一个stdout的tee和一个stderr的tee。你将如何做到这一点?进程替换和文件重定向:
让我们分开来解释一下:
>(...)
(进程替换)创建一个FIFO并让tee
监听它。然后,它使用>
(文件重定向)将command
的STDOUT重定向到第一个tee
正在侦听的FIFO。同样的第二件事:
我们再次使用进程替换来生成
tee
进程,该进程从STDIN读取并将其转储到stderr.log
。tee
将它的输入输出回STDOUT,但是由于它的输入是我们的STDERR,我们想再次将tee
的STDOUT重定向到我们的STDERR。然后我们使用文件重定向将command
的STDERR重定向到FIFO的输入(tee
的STDIN)。见http://mywiki.wooledge.org/BashGuide/InputAndOutput
进程替换是那些非常可爱的东西之一,你可以选择
bash
作为外壳,而不是sh
(POSIX或Bourne)。在
sh
中,您必须手动执行以下操作:为什么不干脆:
这只会将
stderr
重定向到stdout
,因此tee会同时回显到日志和屏幕。也许我漏掉了一些东西,因为其他的解决方案看起来很复杂。注意:由于bash版本4,您可以使用
|&
作为2>&1 |
的缩写:这可能对人们通过谷歌找到这个有用。只需取消注释您想要尝试的示例。当然,可以随意重命名输出文件。
相关问题 更多 >
编程相关推荐