Bash-将所有输出发送到日志文件,但显示错误
在bash脚本中,除了我使用echo专门输出的输出之外,是否可以将所有输出转到日志文件,但是如果输出中有错误,它应该显示在终端中(当然还有日志文件)?UNIX终端通常提供两个输出文件描述符,Bash-将所有输出发送到日志文件,但显示错误,bash,shell,unix,file-descriptor,io-redirection,Bash,Shell,Unix,File Descriptor,Io Redirection,在bash脚本中,除了我使用echo专门输出的输出之外,是否可以将所有输出转到日志文件,但是如果输出中有错误,它应该显示在终端中(当然还有日志文件)?UNIX终端通常提供两个输出文件描述符,stdout和stderr,默认情况下,这两者都将转到终端 性能良好的程序将其“标准”输出发送到stdout,将错误发送到stderr。例如,echo写入标准输出grep将匹配行写入stdout,但如果出现错误,例如无法读取文件,则错误将转到stderr 您可以使用(对于stdout)和2>(对于stderr
stdout
和stderr
,默认情况下,这两者都将转到终端
性能良好的程序将其“标准”输出发送到stdout
,将错误发送到stderr
。例如,echo
写入标准输出grep
将匹配行写入stdout
,但如果出现错误,例如无法读取文件,则错误将转到stderr
您可以使用
(对于stdout
)和2>
(对于stderr
)重定向这些文件。因此:
将输出写入日志
,将错误写入错误
因此,您的部分需求可以通过以下方式得到满足:
command >log
。。。错误将继续通过标准输出发送到终端
您的额外要求是“除了我专门用echo输出的输出”
您的echo
s转到stderr可能就足够了:
echo "Processing next part" >&2
&2
将stdout
从该命令重定向到stderr
。这是在shell脚本中输出错误(有时是信息输出)的标准方法
如果您需要的不止这些,那么您可能需要使用更多的文件描述符来执行更复杂的操作。尝试:
表现良好的UNIX程序往往避免使用额外的文件描述符执行复杂的操作。约定是将自己限制为
stdout
和stderr
,任何进一步的输出都在命令行参数中指定为文件名。以下是使用附加文件描述符可以执行的操作:
#!/bin/bash
# open fd=3 redirecting to 1 (stdout)
exec 3>&1
# redirect stdout/stderr to a file but show stderr on terminal
exec >file.log 2> >(tee >(cat >&3))
# function echo to show echo output on terminal
echo() {
# call actual echo command and redirect output to fd=3
command echo "$@" >&3
}
# script starts here
echo "show me"
printf "=====================\n"
printf "%s\n" "hide me"
ls foo-foo
date
tty
echo "end of run"
# close fd=3
exec 3>&-
运行脚本后,它将在终端上显示以下内容:
show me
ls: cannot access 'foo-foo': No such file or directory
end of run
如果执行cat file.log
,则会显示:
=====================
hide me
ls: cannot access 'foo-foo': No such file or directory
Fri Dec 2 14:20:47 EST 2016
/dev/ttys002
- 在终端上,我们只得到
命令和所有错误的输出echo
- 在日志文件中,我们从脚本中获得错误和剩余输出
echo
的输出显示在标准输出上?那printf呢??我只在脚本中使用“echo”向用户显示状态。一个小小的吹毛求疵。。。并不是UNIX终端提供stdin、stdout和stderr。即使不是在终端中运行的进程在启动时也有这三个文件描述符(重要的区别是,许多守护进程首先关闭这三个文件描述符)。这实际上只是UNIX进程模型的一个特性。。。我想你甚至可以称之为API的一部分。。。
=====================
hide me
ls: cannot access 'foo-foo': No such file or directory
Fri Dec 2 14:20:47 EST 2016
/dev/ttys002