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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/876239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:20:01  来源:igfitidea点击:

How to redirect and append both stdout and stderr to a file with Bash?

linuxbashredirectstreampipe

提问by flybywire

To redirect stdoutto a truncated file in Bash, I know to use:

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

cmd > file.txt

To redirect stdoutin Bash, appending to a file, I know to use:

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

cmd >> file.txt

To redirect both stdoutand stderrto a truncated file, I know to use:

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

cmd &> file.txt

How do I redirect both stdoutand stderrappending to a file? cmd &>> file.txtdid not work for me.

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

采纳答案by Alex Martelli

cmd >>file.txt 2>&1

Bash executes the redirects from left to right as follows:

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

  1. >>file.txt: Open file.txtin append mode and redirect stdoutthere.
  2. 2>&1: Redirect stderrto "where stdoutis currently going". In this case, that is a file opened in append mode. In other words, the &1reuses the file descriptor which stdoutcurrently uses.
  1. >>file.txtfile.txt以追加模式打开并重定向到stdout那里。
  2. 2>&1: 重定向stderrstdout当前去哪里”。在这种情况下,这是一个以追加模式打开的文件。换句话说,&1重用stdout当前使用的文件描述符。

回答by TheBonsai

There are two ways to do this, depending on your Bash version.

有两种方法可以做到这一点,具体取决于您的 Bash 版本。

The classic and portable (Bash pre-4) way is:

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

cmd >> outfile 2>&1

A nonportable way, starting with Bash 4is

一种不可移植的方式,从Bash 4开始是

cmd &>> outfile

(analog to &> outfile)

(类似于&> outfile

For good coding style, you should

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

  • decide if portability is a concern (then use classic way)
  • decide if portability even to Bash pre-4 is a concern (then use classic way)
  • no matter which syntax you use, not change it within the same script (confusion!)
  • 决定便携性是否是一个问题(然后使用经典方式)
  • 决定是否考虑 Bash pre-4 的可移植性(然后使用经典方式)
  • 无论您使用哪种语法,都不要在同一个脚本中更改它(混淆!)

If your script already starts with #!/bin/sh(no matter if intended or not), then the Bash 4 solution, and in general any Bash-specific code, is not the way to go.

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

Also remember that Bash 4 &>>is just shorter syntax — it does not introduce any new functionality or anything like that.

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

The syntax is (beside other redirection syntax) described here: http://bash-hackers.org/wiki/doku.php/syntax/redirection#appending_redirected_output_and_error_output

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

回答by A B

In Bash 4 (as well as ZSH 4.3.11):

在 Bash 4(以及 ZSH 4.3.11)中:

cmd &>>outfile

just out of box

刚开箱

回答by Aaron R.

In Bash you can also explicitly specify your redirects to different files:

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

cmd >log.out 2>log_error.out

Appending would be:

附加将是:

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

回答by Quintus.Zhou

Try this

尝试这个

You_command 1>output.log  2>&1

Your usage of &>x.file does work in bash4. sorry for that : (

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

Here comes some additional tips.

这里有一些额外的提示。

0, 1, 2...9 are file descriptors in bash.

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

0 stands for stdin, 1 stands for stdout, 2 stands for stderror. 3~9 is spare for any other temporary usage.

0代表stdin,1代表stdout,2代表stderror。3~9 备用,供其他临时使用。

Any file descriptor can be redirected to other file descriptor or file by using operator >or >>(append).

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

Usage: <file_descriptor> ><filename| &file_descriptor>

用法:< file_descriptor> ><文件名| &file_descriptor>

Please reference to http://www.tldp.org/LDP/abs/html/io-redirection.html

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

回答by Pradeep Goswami

This should work fine:

这应该可以正常工作:

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

It will store all logs in file.txtas well as dump them on terminal.

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

回答by jamesdlin

I am surprised that in almost ten years, no one has posted this approach yet:

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

If using older versions of bash where &>>isn't available, you also can do:

如果在&>>不可用的情况下使用旧版本的 bash ,您还可以执行以下操作:

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

This spawns a subshell, so it's less efficient than the traditional approach of cmd >> file.txt 2>&1, and it consequently won't work for commands that need to modify the current shell (e.g. cd, pushd), but this approach feels more natural and understandable to me:

这会产生一个子shell,因此它的效率低于 的传统方法cmd >> file.txt 2>&1,因此它不适用于需要修改当前shell的命令(例如cd, pushd),但这种方法对我来说更自然且易于理解:

  1. Redirect stderr to stdout.
  2. Redirect the new stdout by appending to a file.
  1. 将 stderr 重定向到 stdout。
  2. 通过附加到文件来重定向新的标准输出。

Also, the parentheses remove any ambiguity of order, especially if you want to pipe stdout and stderr to another command instead.

此外,括号消除了任何顺序上的歧义,特别是如果您想将 stdout 和 stderr 通过管道传输到另一个命令。