如何使用Bash将stdout和stderr重定向并附加到文件中?

时间:2009-05-18 04:19:46

标签: linux bash redirect stream pipe

要将 stdout 重定向到Bash中的截断文件,我知道要使用:

cmd > file.txt

要在Bash中重定向 stdout ,附加到文件,我知道要使用:

cmd >> file.txt

要将 stdout stderr 重定向到截断的文件,我知道要使用:

cmd &> file.txt

如何重定向附加到文件的 stdout stderr cmd &>> file.txt对我不起作用。

8 个答案:

答案 0 :(得分:1771)

cmd >>file.txt 2>&1

Bash从左到右执行重定向,如下所示:

  1. >>file.txt:在追加模式下打开file.txt并在其中重定向stdout
  2. 2>&1:将stderr重定向到stdout当前正在”。在这种情况下,这是一个以追加模式打开的文件。换句话说,&1重用stdout当前使用的文件描述符。

答案 1 :(得分:331)

有两种方法可以执行此操作,具体取决于您的Bash版本。

经典便携式( Bash pre-4 )方式是:

cmd >> outfile 2>&1

Bash 4 开头的非便携式广告

cmd &>> outfile

(类似于&> outfile

对于良好的编码风格,你应该

  • 决定是否关注可移植性(然后使用经典方式)
  • 决定是否可以将Bash pre-4的可移植性作为一个问题(然后使用经典方式)
  • 无论您使用哪种语法,都不要在同一个脚本中进行更改(混淆!)

如果您的脚本已经以#!/bin/sh开头(无论是否有意),那么Bash 4解决方案以及通常任何特定于Bash的代码都不是可行的方法。

还要记住,Bash 4 &>>只是更短的语法 - 它不会引入任何新功能或类似的东西。

此处描述的语法(除了其他重定向语法之外):http://bash-hackers.org/wiki/doku.php/syntax/redirection#appending_redirected_output_and_error_output

答案 2 :(得分:81)

在Bash中,您还可以明确指定重定向到不同的文件:

cmd >log.out 2>log_error.out

追加将是:

cmd >>log.out 2>>log_error.out

答案 3 :(得分:61)

在Bash 4(以及ZSH 4.3.11)中:

cmd &>>outfile

开箱即用

答案 4 :(得分:42)

这应该可以正常工作:

your_command 2>&1 | tee -a file.txt

它会将所有日志存储在 file.txt 中,并将它们转储到终端上。

答案 5 :(得分:23)

试试这个

You_command 1>output.log  2>&1

您对&> x.file的使用在bash4中有效。对不起:(

这里有一些额外的提示。

0,1,2 ... 9是bash中的文件描述符。

0代表stdin,1代表stdout,2代表stderror。任何其他临时使用都可以使用3~9。

可以使用运算符>>>(追加)将任何文件描述符重定向到其他文件描述符或文件。

使用方法: <的类file_descriptor > > < 文件名 |的&安培;类file_descriptor >

请参阅http://www.tldp.org/LDP/abs/html/io-redirection.html

答案 6 :(得分:2)

令我惊讶的是,近十年来,还没有人发布这种方法:

如果使用的bash较旧版本(其中&>>不可用),您还可以执行以下操作:

(cmd 2>&1) >> file.txt

这产生了一个subshel​​l,因此它比cmd >> file.txt 2>&1的传统方法效率低,但是这种方法对我来说更自然,更容易理解:

  1. 将stderr重定向到stdout。
  2. 通过附加到文件来重定向新的标准输出。

此外,括号消除了任何歧义的顺序,尤其是如果您希望将stdout和stderr通过管道传递给另一个命令时。

答案 7 :(得分:2)

从内部脚本重定向

您可以自己从脚本中计划重定向

#!/bin/bash

exec 1>>logfile.txt
exec 2>&1

/bin/ls -ld /tmp /tnt

运行这将创建/附加 logfile.txt,包含:

/bin/ls: cannot access '/tnt': No such file or directory
drwxrwxrwt 2 root root 4096 Apr  5 11:20 /tmp

登录到许多不同的文件

您可以创建两个不同的日志文件,附加到一个整体日志并重新创建另一个最后日志:

#!/bin/bash

if [ -e last.log ] ;then
    mv -f last.log last.old
fi
exec 1> >(tee -a overall.log /dev/tty >last.log)
exec 2>&1

ls -ld /tnt /tmp

运行此脚本将

  • 如果 last.log 已存在,请将它们重命名为 last.old(如果存在,则覆盖 last.old)。
  • 创建一个新的 last.log
  • 将所有内容附加到 overall.log
  • 将所有内容输出到终端。

简单 AND 组合日志

#!/bin/bash

[ -e last.err ] && mv -f last.err lasterr.old
[ -e last.log ] && mv -f last.log lastlog.old

exec 2> >(tee -a overall.err combined.log /dev/tty >last.err)
exec 1> >(tee -a overall.log combined.log /dev/tty >last.log)

ls -ld /tnt /tmp

所以你有

  • last.log 上次运行日志文件
  • last.err 上次运行错误文件
  • lastlog.old 之前的运行日志文件
  • lasterr.old 之前的运行错误文件
  • overall.log 附加了整体日志文件
  • overall.err 附加了整体错误文件
  • combined.log 附加了整体错误和日志组合文件。
  • 仍然输出到终端