bash 在shell中,“2>&1”是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/818255/
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-09-09 18:09:18  来源:igfitidea点击:

In the shell, what does " 2>&1 " mean?

bashshellunixredirect

提问by Tristan Havelick

In a Unix shell, if I want to combine stderrand stdoutinto the stdoutstream for further manipulation, I can append the following on the end of my command:

在 Unix shell 中,如果我想将stderrstdout合并到stdout流中以进行进一步操作,我可以在命令的末尾附加以下内容:

2>&1

So, if I want to use headon the output from g++, I can do something like this:

因此,如果我想head在 的输出上使用g++,我可以执行以下操作:

g++ lots_of_errors 2>&1 | head

so I can see only the first few errors.

所以我只能看到前几个错误。

I always have trouble remembering this, and I constantly have to go look it up, and it is mainly because I don't fully understand the syntax of this particular trick.

我总是很难记住这一点,我不得不经常去查,这主要是因为我不完全理解这个特殊技巧的语法。

Can someone break this up and explain character by character what 2>&1means?

有人可以分解这个并逐个解释是什么2>&1意思吗?

回答by Ayman Hourieh

File descriptor 1 is the standard output (stdout).
File descriptor 2 is the standard error (stderr).

文件描述符 1 是标准输出 ( stdout)。
文件描述符 2 是标准错误 ( stderr)。

Here is one way to remember this construct (although it is not entirely accurate): at first, 2>1may look like a good way to redirect stderrto stdout. However, it will actually be interpreted as "redirect stderrto a file named 1". &indicates that what follows is a file descriptor and not a filename. So the construct becomes: 2>&1.

这是记住此构造的一种方法(尽管它并不完全准确):乍一看,这2>1似乎是重定向stderrstdout. 但是,它实际上会被解释为“重定向stderr到名为1”的文件。&表示接下来是文件描述符而不是文件名。所以构造变成:2>&1

回答by dbr

echo test > afile.txt

redirects stdout to afile.txt. This is the same as doing

将标准输出重定向到afile.txt. 这和做一样

echo test 1> afile.txt

To redirect stderr, you do:

要重定向 stderr,您可以:

echo test 2> afile.txt

>&is the syntax to redirect a stream to another file descriptor - 0 is stdin, 1 is stdout, and 2 is stderr.

>&是将流重定向到另一个文件描述符的语法 - 0 是标准输入,1 是标准输出,而 2 是标准错误。

You can redirect stdout to stderr by doing:

您可以通过执行以下操作将 stdout 重定向到 stderr:

echo test 1>&2 # or echo test >&2

Or vice versa:

或相反亦然:

echo test 2>&1

So, in short... 2>redirects stderr to an (unspecified) file, appending &1redirects stderr to stdout.

所以,简而言之......2>将stderr重定向到一个(未指定的)文件,附加&1重定向stderr到stdout。

回答by F. Hauri

Some tricks about redirection

关于重定向的一些技巧

Some syntax particularity about this may have important behaviours. There is some little samples about redirections, STDERR, STDOUT, and arguments ordering.

关于此的一些语法特殊性可能具有重要的行为。有一些关于重定向STDERRSTDOUT、 和 参数排序 的小示例。

1 - Overwriting or appending?

1 - 覆盖还是追加?

Symbol >mean redirection.

符号>表示重定向

  • >mean send to as a whole completed file, overwriting target if exist (see noclobberbash feature at #3later).
  • >>mean send in addition towould append to target if exist.
  • >意味着发送到一个完整的文件,如果存在则覆盖目标(请参阅后面#3 的noclobberbash 功能)。
  • >>意味着发送除了将附加到目标(如果存在)。

In any case, the file would be created if they not exist.

在任何情况下,如果文件不存在,就会创建该文件。

2 - The shell command lineis order dependent!!

2 - shell 命令行是顺序相关的!!

For testing this, we need a simple command which will send something on both outputs:

为了测试这个,我们需要一个简单的命令来在两个输出上发送一些东西

$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

(Expecting you don't have a directory named /tnt, of course ;). Well, we have it!!

(当然,希望您没有名为 的目录/tnt;)。嗯,我们有!!

So, let's see:

那么,让我们看看:

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1

$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory

The last command line dumps STDERRto the console, and it seem not to be the expected behaviour... But...

最后一个命令行转储STDERR到控制台,这似乎不是预期的行为......但是......

If you want to make some post filteringabout one output, the other or both:

如果您想对一个输出、另一个或两者进行一些后期过滤

$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'

$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->

Notice that the last command line in this paragraph is exactly same as in previous paragraph, where I wrote seem not to be the expected behaviour(so, this could even be an expected behaviour).

请注意,本段中的最后一个命令行与上一段中的完全相同,我写的似乎不是预期的行为(因此,这甚至可能是预期的行为)。

Well, there is a little tricks about redirections, for doing different operation on both outputs:

好吧,有一些关于重定向的小技巧,用于 对两个输出进行不同的操作

$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2  2>&1  | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan  7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory

Nota: &9descriptor would occur spontaneously because of ) 9>&2.

注意:&9由于 ,描述符会自发出现) 9>&2

Addendum: nota!With the new version of bash(>4.0) there is a new feature and more sexy syntax for doing this kind of things:

附录:注意!使用新版本的bash( >4.0) 有一个新功能和更性感的语法来做这种事情:

$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory

And finally for such a cascading output formatting:

最后对于这样的级联输出格式:

$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
     1  O: drwxrwxrwt 118 root root 196608 Jan  7 12:29 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

Addendum: nota!Same new syntax, in both ways:

附录:注意!相同的新语法,两种方式:

$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
     1  O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

Where STDOUTgo through a specific filter, STDERRto another and finally both outputs merged go through a third command filter.

哪里STDOUT通过一个特定的过滤器,STDERR到另一个,最后合并的两个输出通过第三个命令过滤器。

3 - A word about noclobberoption and >|syntax

3 - 关于noclobber选项和>|语法的一个词

That's about overwriting:

那是关于覆盖

While set -o noclobberinstruct bash to notoverwrite any existing file, the >|syntax let you pass through this limitation:

虽然set -o noclobber指示 bash不要覆盖任何现有文件,但>|语法允许您通过此限制:

$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:15 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:19 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:21 CET 2013

The file is overwritten each time, well now:

该文件每次都被覆盖,现在好了:

$ set -o noclobber

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

Pass through with >|:

通过>|

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:18:58 CET 2013

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:19:01 CET 2013

Unsetting this option and/or inquiring if already set.

取消设置此选项和/或询问是否已设置。

$ set -o | grep noclobber
noclobber           on

$ set +o noclobber

$ set -o | grep noclobber
noclobber           off

$ date > $testfile ; cat $testfile
Mon Jan  7 13:24:27 CET 2013

$ rm $testfile

4 - Last trick and more...

4 - 最后一招和更多...

For redirecting bothoutput from a given command, we see that a right syntax could be:

为了重定向给定命令的两个输出,我们看到正确的语法可能是:

$ ls -ld /tmp /tnt >/dev/null 2>&1

for this specialcase, there is a shortcut syntax: &>... or >&

对于这种特殊情况,有一个快捷语法:&>... 或>&

$ ls -ld /tmp /tnt &>/dev/null

$ ls -ld /tmp /tnt >&/dev/null

Nota: if 2>&1exist, 1>&2is a correct syntax too:

注意:如果2>&1存在,1>&2也是正确的语法:

$ ls -ld /tmp /tnt 2>/dev/null 1>&2

4b- Now, I will let you think about:

4b- 现在,我会让你思考:

$ ls -ld /tmp /tnt 2>&1 1>&2  | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

$ ls -ld /tmp /tnt 1>&2 2>&1  | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

4c- If you're interested in moreinformation

4c-如果您对更多信息感兴趣

You could read the fine manual by hitting:

您可以通过点击阅读精美的手册:

man -Len -Pless\ +/^REDIRECTION bash

in a bashconsole ;-)

bash控制台中 ;-)

回答by Deen John

I found this brilliant post on redirection: All about redirections

我发现了这篇关于重定向的精彩帖子:关于重定向

Redirect both standard output and standard error to a file

将标准输出和标准错误都重定向到一个文件

$ command &>file

$命令&>文件

This one-liner uses the &>operator to redirect both output streams - stdout and stderr - from command to file. This is Bash's shortcut for quickly redirecting both streams to the same destination.

这种单行使用&>运算符将两个输出流(stdout 和 stderr)从命令重定向到文件。这是 Bash 快速将两个流重定向到同一目的地的快捷方式。

Here is how the file descriptor table looks like after Bash has redirected both streams:

以下是 Bash 重定向两个流后文件描述符表的样子:

Enter image description here

在此处输入图片说明

As you can see, both stdout and stderr now point to file. So anything written to stdout and stderr gets written to file.

如您所见,stdout 和 stderr 现在都指向file. 因此,任何写入 stdout 和 stderr 的内容都会写入file.

There are several ways to redirect both streams to the same destination. You can redirect each stream one after another:

有多种方法可以将两个流重定向到同一目的地。您可以一个接一个地重定向每个流:

$ command >file 2>&1

$ 命令>文件2>&1

This is a much more common way to redirect both streams to a file. First stdout is redirected to file, and then stderr is duplicated to be the same as stdout. So both streams end up pointing to file.

这是将两个流重定向到文件的更常见的方法。首先将 stdout 重定向到文件,然后将 stderr 复制为与 stdout 相同。所以两个流最终都指向file.

When Bash sees several redirections it processes them from left to right. Let's go through the steps and see how that happens. Before running any commands, Bash's file descriptor table looks like this:

当 Bash 看到几个重定向时,它会从左到右处理它们。让我们完成这些步骤,看看这是如何发生的。在运行任何命令之前,Bash 的文件描述符表如下所示:

Enter image description here

在此处输入图片说明

Now Bash processes the first redirection >file. We've seen this before and it makes stdout point to file:

现在 Bash 处理第一个重定向 > 文件。我们以前见过这个,它使 stdout 指向文件:

Enter image description here

在此处输入图片说明

Next Bash sees the second redirection 2>&1. We haven't seen this redirection before. This one duplicates file descriptor 2 to be a copy of file descriptor 1 and we get:

接下来 Bash 看到第二个重定向 2>&1。我们以前从未见过这种重定向。这将文件描述符 2 复制为文件描述符 1 的副本,我们得到:

Enter image description here

在此处输入图片说明

Both streams have been redirected to file.

两个流都已重定向到文件。

However be careful here! Writing

不过这里要小心!写作

command >file 2>&1

命令>文件2>&1

is not the same as writing:

与写作不同:

$ command 2>&1 >file

$命令2>&1>文件

The order of redirects matters in Bash! This command redirects only the standard output to the file. The stderr will still print to the terminal. To understand why that happens, let's go through the steps again. So before running the command, the file descriptor table looks like this:

重定向的顺序在 Bash 中很重要!此命令仅将标准输出重定向到文件。stderr 仍将打印到终端。要了解为什么会发生这种情况,让我们再次执行这些步骤。所以在运行命令之前,文件描述符表如下所示:

Enter image description here

在此处输入图片说明

Now Bash processes redirections left to right. It first sees 2>&1 so it duplicates stderr to stdout. The file descriptor table becomes:

现在 Bash 处理从左到右的重定向。它首先看到 2>&1 所以它复制 stderr 到 stdout。文件描述符表变为:

Enter image description here

在此处输入图片说明

Now Bash sees the second redirect, >file, and it redirects stdout to file:

现在 Bash 看到第二个重定向,>file,并将标准输出重定向到文件:

Enter image description here

在此处输入图片说明

Do you see what happens here? Stdout now points to file, but the stderr still points to the terminal! Everything that gets written to stderr still gets printed out to the screen! So be very, very careful with the order of redirects!

你看到这里发生了什么吗?标准输出现在指向文件,但标准错误仍然指向终端!写入 stderr 的所有内容仍然会打印到屏幕上!所以要非常非常小心重定向的顺序!

Also note that in Bash, writing

另请注意,在 Bash 中,编写

$ command &>file

$命令&>文件

is exactly the same as:

完全相同:

$ command >&file

$ 命令>&file

回答by Colin Burnett

The numbers refer to the file descriptors (fd).

这些数字指的是文件描述符 (fd)。

  • Zero is stdin
  • One is stdout
  • Two is stderr
  • 零是 stdin
  • 一个是 stdout
  • 二是 stderr

2>&1redirects fd 2 to 1.

2>&1将 fd 2 重定向到 1。

This works for any number of file descriptors if the program uses them.

如果程序使用它们,这适用于任意数量的文件描述符。

You can look at /usr/include/unistd.hif you forget them:

/usr/include/unistd.h如果你忘记了,你可以看看:

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

That said I have written C tools that use non-standard file descriptors for custom logging so you don't see it unless you redirect it to a file or something.

也就是说,我已经编写了使用非标准文件描述符进行自定义日志记录的 C 工具,因此除非将其重定向到文件或其他内容,否则您看不到它。

回答by paxdiablo

That construct sends the standard error stream (stderr) to the currentlocation of standard output (stdout) - this currency issue appears to have been neglected by the other answers.

该构造将标准错误流 ( stderr) 发送到标准输出 ( )的当前位置stdout- 这个货币问题似乎已被其他答案忽略。

You can redirect any output handle to another by using this method but it's most often used to channel stdoutand stderrstreams into a single stream for processing.

您可以使用此方法将任何输出句柄重定向到另一个句柄,但它最常用于将通道stdoutstderr流传输到单个流中进行处理。

Some examples are:

一些例子是:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

Note that that last one will notdirect stderrto outfile2- it redirects it to what stdoutwas when the argument was encountered (outfile1) and thenredirects stdoutto outfile2.

请注意,最后一个将不会直接stderroutfile2-它重定向到什么stdout是遇到的参数时,( outfile1),并随后重定向stdoutoutfile2

This allows some pretty sophisticated trickery.

这允许一些非常复杂的技巧。

回答by wjordan

2>&1is a POSIX shell construct. Here is a breakdown, token by token:

2>&1是 POSIX shell 构造。这是一个细分,逐个标记:



2: "Standard error" output file descriptor.

2:“标准错误”输出文件描述符。

>&: Duplicate an Output File Descriptoroperator (a variant of Output Redirectionoperator >). Given [x]>&[y], the file descriptor denoted by xis made to be a copy of the output file descriptor y.

>&复制输出文件描述符运算符(输出重定向运算符的变体>)。鉴于[x]>&[y],由 表示的文件描述符x是输出文件描述符的副本y

1"Standard output" output file descriptor.

1标准输出”输出文件描述符。

The expression 2>&1copies file descriptor 1to location 2, so any output written to 2("standard error") in the execution environment goes to the same file originally described by 1("standard output").

该表达式将2>&1文件描述符复制1到 location 2,因此2在执行环境中写入(“标准错误”)的任何输出都将转到最初由1(“标准输出”)描述的同一文件。



Further explanation:

进一步解释:

File Descriptor: "A per-process unique, non-negative integer used to identify an open file for the purpose of file access."

文件描述符:“每个进程唯一的非负整数,用于标识打开的文件以进行文件访问。”

Standard output/error: Refer to the following note in the Redirectionsection of the shell documentation:

标准输出/错误:请参阅shell 文档的重定向部分中的以下注释:

Open files are represented by decimal numbers starting with zero. The largest possible value is implementation-defined; however, all implementations shall support at least 0 to 9, inclusive, for use by the application. These numbers are called "file descriptors". The values 0, 1, and 2 have special meaning and conventional uses and are implied by certain redirection operations; they are referred to as standard input, standard output, and standard error, respectively. Programs usually take their input from standard input, and write output on standard output. Error messages are usually written on standard error. The redirection operators can be preceded by one or more digits (with no intervening characters allowed) to designate the file descriptor number.

打开的文件由从零开始的十进制数表示。最大可能值是实现定义的;但是,所有实现都应至少支持 0 到 9,包括 0 到 9,供应用程序使用。这些数字称为“文件描述符”。值 0、1 和 2 具有特殊含义和常规用途,并且由某些重定向操作隐含;它们分别被称为标准输入、标准输出和标准错误。程序通常从标准输入获取输入,并在标准输出上写入输出。错误消息通常写在标准错误上。重定向操作符前面可以有一位或多位数字(不允许中间字符)来指定文件描述符编号。

回答by Marcus Thornton

2 is the console standard error.

2 是控制台标准错误。

1 is the console standard output.

1 是控制台标准输出。

This is the standard Unix, and Windows also follows the POSIX.

这是标准的 Unix,Windows 也遵循 POSIX。

E.g. when you run

例如,当你跑步时

perl test.pl 2>&1

the standard error is redirected to standard output, so you can see both outputs together:

标准错误被重定向到标准输出,因此您可以同时看到两个输出:

perl test.pl > debug.log 2>&1

After execution, you can see all the output, including errors, in the debug.log.

执行后,您可以在 debug.log 中看到所有输出,包括错误。

perl test.pl 1>out.log 2>err.log

Then standard output goes to out.log, and standard error to err.log.

然后标准输出到 out.log,标准错误到 err.log。

I suggest you to try to understand these.

我建议你试着去理解这些。

回答by Andrioid

To answer your question: It takes any error output (normally sent to stderr) and writes it to standard output (stdout).

回答您的问题:它需要任何错误输出(通常发送到 stderr)并将其写入标准输出(stdout)。

This is helpful with, for example 'more' when you need paging for all output. Some programs like printing usage information into stderr.

例如,当您需要对所有输出进行分页时,这会很有帮助。一些程序喜欢将使用信息打印到标准错误中。

To help you remember

为了帮助你记住

  • 1 = standard output (where programs print normal output)
  • 2 = standard error (where programs print errors)
  • 1 = 标准输出(程序打印正常输出)
  • 2 = 标准错误(程序打印错误)

"2>&1" simply points everything sent to stderr, to stdout instead.

"2>&1" 只是将发送到 stderr 的所有内容指向 stdout。

I also recommend reading this post on error redirectingwhere this subject is covered in full detail.

我还建议阅读有关错误重定向的这篇文章,其中详细介绍了该主题。

回答by ams

From a programmer's point of view, it means precisely this:

从程序员的角度来看,这恰恰意味着:

dup2(1, 2);

See the man page.

请参阅手册页

Understanding that 2>&1is a copyalso explains why ...

理解这2>&1是一个副本也解释了为什么......

command >file 2>&1

... is not the same as ...

……与……不一样

command 2>&1 >file

The first will send both streams to file, whereas the second will send errors to stdout, and ordinary output into file.

第一个会将两个流发送到file,而第二个会将错误发送到stdout,并将普通输出发送到file