2016-12-02 30 views
0

是否有可能在一个bash脚本中,使除echo输出我输出的所有输出到日志文件,但如果有错误输出它应该显示在终端(和日志文件也是课程)?Bash - 发送所有输出到一个日志文件,但显示错误

+0

你能确认你想要这3种输出吗? 1)你的回声应该只出现在控制台上,2)其他标准输出应该只出现在日志文件和3)错误输出应该出现在控制台和日志文件都 – Aaron

+0

是完全相同亚伦 –

+0

所以,你想从'只输出echo“出现在stdout上?那么'printf'呢? – anubhava

回答

0

UNIX终端通常提供两个输出文件描述符,stdoutstderr,默认情况下它们都会进入终端。

乖程序发送自己的“标准”输出到stdout,并错误stderr。因此,例如echo写入标准输出。 grep将匹配行写入stdout,但如果出现错误,例如无法读取文件,则错误将发生到stderr

您可以用>(对于stdout)和2>(对于stderr)重定向。所以:

myscript >log 2>errors 

将输出写入log和错误errors

command >log 

...错误会继续去终端,通过标准输出:

所以你的要求的一部分,可以用简单的满足。

您的额外要求是“除了我特别用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程序往往避免使用额外的文件描述符执行复杂的事情。约定将自己限制为stdoutstderr,并在命令行参数中将任何其他输出指定为文件名。

+0

一个小小的挑剔......这不是UNIX终端,提供标准输入,标准输出,和标准错误。即使未在终端运行的进程必须在启动这三个文件描述符(重要的区别,因为许多守护进程刚刚关闭所有三个第一件事)。这是真正的UNIX进程模型只是一个功能...我想你甚至可以把它叫做API的一部分... – twalberg

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 "[email protected]" >&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 
  • 在TE我们只得到echo命令的输出和所有的错误。
  • 在日志文件中我们得到的错误,从脚本输出剩余。
相关问题