在bash脚本中是否可以使所有输出(除了输出i特别用echo输出)转到日志文件,但是如果输出中的错误应该显示在终端中(并且日志文件也是当然的)?
答案 0 :(得分:1)
通过使用附加文件描述符,您可以执行以下操作:
#!/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
命令和所有错误。答案 1 :(得分:0)
UNIX终端通常提供两个输出文件描述符,stdout
和stderr
,默认情况下都会转到终端。
表现良好的程序将其“标准”输出发送到stdout
,将错误发送到stderr
。例如,echo
写入stdout。 grep
将匹配的行写入stdout
,但如果出现问题,例如无法读取文件,则错误会转到stderr
。
您可以使用>
(适用于stdout
)和2>
(适用于stderr
)重定向这些内容。所以:
myscript >log 2>errors
将输出写入log
,将错误写入errors
。
因此,只需使用以下内容即可满足您的部分要求:
command >log
...错误将继续通过stdout传递到终端。
您的额外要求是“除了输出我专门用echo输出”。
你的echo
去stderr:
echo "Processing next part" >&2
>&2
将此命令的stdout
重定向到stderr
。这是在shell脚本中输出错误(有时是信息输出)的标准方法。
如果您需要更多,可能需要使用更多文件描述符来执行更复杂的操作。尝试:https://unix.stackexchange.com/questions/18899/when-would-you-use-an-additional-file-descriptor
表现良好的UNIX程序往往避免使用额外的文件描述符来处理复杂的事情。惯例是将自己限制为stdout
和stderr
,并在命令行参数中将任何其他输出指定为文件名。