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


重定向 标准输出 到Bash中的截断文件,我知道要使用:

cmd > file.txt

重定向 标准输出 在Bash中,附加到文件,我知道使用:

cmd >> file.txt

重定向两者 标准输出 和 标准错误 截断文件,我知道使用:

cmd &> file.txt

如何重定向两者 标准输出 和 标准错误 附加到文件? cmd &>> file.txt 对我不起作用。


1184
2018-05-18 04:19


起源


我想指出&> outfile是一个Bash(和其他)特定的代码而不是可移植的。便携式(类似于附加答案)的方式总是并且仍然是> outfile 2>&1 - TheBonsai


答案:


cmd >>file.txt 2>&1

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

  1. >>file.txt:打开 file.txt 在追加模式和重定向 stdout 那里。
  2. 2>&1:重定向 stderr 至 “哪里 stdout 目前正在“。在这种情况下,这是一个以追加模式打开的文件。换句话说, &1 重用文件描述符 stdout 目前使用。

1561
2018-05-18 04:23



效果很好!但有没有办法理解这一点,还是应该像对待原子bash一样对待它? - flybywire
它是简单的重定向,重定向语句一如既往地从左到右进行评估。 >>文件:红色。 STDOUT to file(追加模式)(1 >>文件的缩写)2>&1:红色。 STDERR到“stdout去哪里”请注意,解释“将STDERR重定向到STDOUT”是错误的。 - TheBonsai
它说“将输出(stdout,文件描述符1)附加到file.txt并将stderr(文件描述符2)发送到与fd1”相同的位置。 - Dennis Williamson
这甚至适用于zsh。谢谢。 - Mark
如果你这样做 cmd >>file1 2>>file2 它应该实现你想要的。 - Woodrow Douglass


有两种方法可以执行此操作,具体取决于您的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


298
2018-05-18 04:42



我更喜欢&>>因为它与&>和>>一致。读取“将输出和错误附加到此文件”也比“将错误发送到输出,将输出附加到此文件”更容易。请注意,虽然Linux通常具有当前版本的bash,OS X,但在撰写本文时,仍需要通过自制软件等手动安装bash 4。 - mikemaccana
我更喜欢它,因为它更短,每行只有tweoi的位置,那么例如zsh可以用“&>>”做什么? - Phillipp
另外需要注意的是,在cron作业中,即使系统具有Bash 4,也必须使用pre-4语法。 - hyperknot
@zsero cron根本不使用bash ......它使用 sh。您可以通过预先添加来更改默认shell SHELL=/bin/bash 到了 crontab -e 文件。 - Ray Foss


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

cmd >log.out 2>log_error.out

附加将是:

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

76
2017-07-24 18:09



使用您的第一个选项将两个流重定向到同一个文件将导致第一个流写入第二个“顶部”,覆盖部分或全部内容。使用 cmd >> log.out 2> log.out 代替。 - Orestis P.
谢谢你抓住了;你是对的,一个会破坏另一个。但是,您的命令也不起作用。我认为写入同一文件的唯一方法就是之前给出的 cmd >log.out 2>&1。我正在编辑我的答案以删除第一个示例。 - Aaron R.


在Bash 4(以及ZSH 4.3.11)中:

cmd &>>outfile

刚开箱即用


57
2018-03-27 18:24



@AoeAoe:这实际上也适用于Bash 4。 - mk12
@all:这是一个很好的答案,因为它适用于bash并且很简短,所以我编辑了以确保它明确提到了bash。 - mikemaccana
@mikemaccana: TheBonsai的答案 显示自2009年以来的bash 4解决方案 - jfs


这应该工作正常:

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

它将存储所有日志 file.txt的 以及将它们转储到终端上。


33
2017-12-12 06:17





尝试这个

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


19
2018-04-10 05:56



您的示例将执行与OP要求不同的操作:它将重定向stderr You_command stdout和stdout You_command 到文件 output.log。此外,它不会附加到文件,但会覆盖它。 - pabouk
正确: 文件描述符 对于所有其他文件,可以是任何大于3的值。 - Itachi
您的答案显示了最常见的输出重定向错误:将STDERR重定向到STDOUT当前指向的位置,并且仅在将STDOUT重定向到文件之后。这不会导致STDERR重定向到同一文件。重定向的顺序很重要。 - Jan Wikholm
这是什么意思,我应该首先将STDERROR重定向到STDOUT,然后将STDOUT重定向到一个文件。 1 > output.log 2>&1 - Quintus.Zhou
@ Quintus.Zhou Yup。您的版本将err重定向到out,同时将其重定向到文件。 - Alex Yaroshevich