关于bash:在shell中,2>&1 是什么意思?

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

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

1
2>&1

所以,如果我想在g++的输出上使用head,我可以这样做:

1
g++ lots_of_errors 2>&1 | head

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

我总是很难记住这一点,我必须不断地去查找它,主要是因为我不完全理解这个特定技巧的语法。

有人能把这件事一个字一个字地说清楚吗?


文件DESCRIPTOR 1是标准输出(stdout)。 2文件DESCRIPTOR是标准误差(stderr)。

这里的冰路。这一构造(尽管它是不准确的说):第一,2>1可能看起来像是一个很好的方式redirect stderrstdout。然而,它会interpreted AA"实际上是两个redirect stderr1命名一个文件"。这是什么&indicates follows DESCRIPTOR冰一个文件而不是一个文件名。所以《建设成为:2>&1


1
echo test > afile.txt

两个afile.txtredirects stdout。这是为做的一样

1
echo test 1> afile.txt

两个redirect stderr,你做的:

1
echo test 2> afile.txt

>&是语法的两个redirect流的另一个文件(2 0 DESCRIPTOR冰stdin,stdout 1和2的冰,冰STDERR。

你可以redirect stderr输出两个城市做的:

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

或反之亦然。

1
echo test 2>&1

所以,在短…2>redirects stderr(不详)的两个文件,appending &1两redirects stderr输出。


redirection about some技巧

about this may have some important syntax behaviours的特殊性。小samples about there is some STDERR,重定向,和STDOUTArguments,序。P></1 overwriting或appending?

redirection象征>均值。P></

  • >均值send to as a Whole completed if exist文件目标,overwriting(EEA noclobber重击在一#特征3)。
  • >>均值加成会发送append if exist to to目标。

在任何房子,如果他们会be created the文件不存在。P></命令行是2 -壳阶相依!!

我们需要为这个简单的测试,它会发送什么命令都由输出:P></

1
2
3
4
5
6
7
8
9
$ 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 *有一个名叫/tnt学院课程目录;,)。好的,我们有它!!P></

我知道,让我们看到:P></

1
2
3
4
5
6
7
$ 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命令行控制台dumps STDERRto the,and not to be the expected恩似乎行为……but…P></

如果你想使一个输出滤波后about some or both the other,:P></

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ 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 --->

that the last命令通知确切的说因为是一款在线this is as in previous款,我似乎wrote not to be the expected(我知道我的行为是好的,这一预期的行为)。P></

好的小技巧,there is about重定向,for做不同的操作都由输出:P></

1
2
3
$ ( 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

注:&9because of ) 9>&2会occur spontaneously描述符。P></

附录:注意!with the New version of bash(there is >4.0)在句法特征和更多的性感做this kind of things for:P></

1
2
3
$ 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

最后,在输出和formatting:cascading for suchP></

1
2
3
$ ((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

附录:注意!新的句法相同,两种:P></

1
2
3
$ 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

我在去一STDOUT特异性STDERRto another和滤波,最后都归在命令行输出merged三通滤波器。P></在3 -和>|syntax option noclobberWord about

这是关于overwriting:P></

set -o noclobberwhile not to any Overwrite existing bash的教学文件,让你>|the syntax THROUGH this限制:P></

1
2
3
4
5
6
7
8
9
10
$ 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

overwritten each time is the文件:现在,嗯P></

1
2
3
4
5
6
7
8
9
$ 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

>|THROUGH:P></

1
2
3
4
5
$ date >| $testfile ; cat $testfile
Mon Jan  7 13:18:58 CET 2013

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

This option和/或不inquiring if already集。P></

1
2
3
4
5
6
7
8
9
10
11
12
$ 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最后的把戏和更多……

redirecting for both given命令输出从表,我们看到,正确的是:P></

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

for this special房屋,there is a shortcut syntax:&>>&orP></

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

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

注:2>&1if exist,太:1>&2is a correct syntaxP></

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

现在威尔4B,你想让它。

1
2
3
4
5
6
7
$ 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的更多信息

你可以读端模式:手动打P></

1
man -Len -Pless\\ +/^REDIRECTION bash

在bash中控制台;-)P></


《参考文件数的descriptors(FD)。

  • stdin
  • stdout
  • 双锥stderr

2>&1redirects FD 1 2两。

本工程的任何号码如果程序文件descriptors辨别他们。

你可以看/usr/include/unistd.h:如果你忘记他们

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

这是说要写C工具,使用非标准的文件descriptors为自定义日志所以你没有看到它,除非你redirect这两个文件或什么的。


我发现这篇关于重定向的精彩文章:关于重定向的所有内容

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

$ command &>file

这一行程序使用&>操作符将输出流(stdout和stderr)从命令重定向到文件。这是bash快速将两个流重定向到同一个目标的快捷方式。

以下是bash重定向两个流后文件描述符表的外观:

Enter image description here

如您所见,stdout和stderr现在都指向file。所以任何写入stdout和stderr的东西都会被写入file

有几种方法可以将两个流重定向到同一目标。您可以逐个重定向每个流:

$ command >file 2>&1

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

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

Enter image description here

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

Enter image description here

下一个bash看到第二个重定向2>1。我们以前没有见过这种重定向。这一个复制了文件描述符2作为文件描述符1的副本,我们得到:

Enter image description here

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

但是在这里要小心!写作

command >file 2>&1

与书写不同:

$ command 2>&1 >file

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

Enter image description here

现在bash处理从左到右的重定向。它首先看到2>&;1,因此它将stderr复制到stdout。文件描述符表变为:

Enter image description here

现在bash看到了第二个重定向,>file,它将stdout重定向到文件:

Enter image description here

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

还要注意,在bash中,

$ command &>file

与以下内容完全相同:

$ command >&file


这是发送生成的标准错误流(stderr)两个标准输出流的位置(stdout),这两种货币的问题已经出现了neglected市其他答案。

你可以做任何redirect输出使用这两个方法的另一个城市,但它的葡萄汁或用两个频道stdoutstderr流到一个单一的数据流的处理。

是一些例子:

1
2
3
4
5
6
7
8
9
10
11
# 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

注意,这是一个直接的货物不会stderroutfile2信息redirects它是什么stdout当参数是encountered(outfile1),然后redirects stdoutoutfile2

这允许一些很复杂的trickery。


2>&1是一个posix shell构造。下面是一个分解,一个代币一个代币:

2"标准错误"输出文件描述符。

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

1标准输出文件描述符。

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

进一步解释:

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

标准输出/错误:请参阅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.


2 is the控制台的标准误差。P></

1 is the控制台输出标准。P></

This is the标准UNIX,Windows和POSIX是茶也。P></

例如,当你运行P></

1
perl test.pl 2>&1

the error is redirected标准输出到标准输出,所以你可以看到两个在一起。P></

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

执行后,你可以看到周围的输出错误,包括debug.log,the。P></

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

然后去到标准输出和标准误差err.log out.log,to。P></

在你尝试了解这些蓝晶石。P></


两个回答你的问题:它需要的任何错误输出(normally晚了两个writes stderr)和它的标准输出(stdout)。

这是有益的和有趣的,例如,当你需要的所有分页输出。这类计划使用信息打印到标准错误。

两帮你。

  • 1 =标准输出(在正常程序的打印输出)
  • 2 =标准误差(在程序的打印错误)

"2"&;1分,"一切都晚了两个简单的标准错误输出,而不是两个。

在阅读这个邮件也recommend在线误差redirecting在这冰覆盖在全社会零售。


从程序员的角度来看,它的确切含义是:

1
dup2(1, 2);

参见手册页。

了解到2>&1是一个副本也解释了为什么…

1
command >file 2>&1

…与…

1
command 2>&1 >file

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


如果您的系统中不存在/foo/tmp的话…

1
$ ls -l /tmp /foo

将打印/tmp的内容,并打印/foo的错误消息。

1
$ ls -l /tmp /foo > /dev/null

/tmp的内容发送到/dev/null并打印/foo的错误消息。

1
$ ls -l /tmp /foo 1> /dev/null

将完全相同(注意1)

1
$ ls -l /tmp /foo 2> /dev/null

将打印/tmp的内容并向/dev/null发送错误消息。

1
$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

将同时向/dev/null发送列表和错误消息。

1
$ ls -l /tmp /foo > /dev/null 2> &1

速记


This is just like the error to the通过stdout or the终端。P></

cmdthat is,is not a命令:P></

1
2
3
4
$cmd 2>filename
cat filename

command not found

the error is sent to the这样的文件:P></

1
2>&1

标准误差is sent to the终端。P></


人们总是记得paxdiablo的提示(redirection流位置的目标……它是重要的。

我的个人mnemonic的运营商,这是一2>&1

  • 想一想&AA或'add''and'意义的字符是一个ampers鸭,不是吗?)
  • 所以我成为:"redirect 2(stderr)在两个1(stdout)/目前已经和添加两个冰流。

在相同的工作mnemonic竞相使用的其他redirection也是,1>&2

  • 想一想&意义andadd…(你得到的想法(ampersand,是吗?)
  • 所以我成为:"redirect 1(stdout)在两个2(stderr)/目前已经和添加两个冰流。

永远记住:你和链有两个读大学的重定向从比从左,右两个(而不是从左右)。


Redirecting Input

Redirection of input causes the file whose name
results from the expansion of word to be opened for reading on file
descriptor n, or the standard input (file descriptor 0) if n is
not specified.

The general format for redirecting input is:

1
[n]<word

Redirecting Output

Redirection of output causes the file whose
name results from the expansion of word to be opened for writing on
file descriptor n, or the standard output (file descriptor 1) if n
is not specified. If the file does not exist it is created; if it
does exist it is truncated to zero size.

The general format for redirecting output is:

1
[n]>word

Moving File Descriptors

The redirection operator,

1
[n]<&amp;digit-

moves the file descriptor digit to file descriptor n, or the
standard input (file descriptor 0) if n is not specified.
digit is closed after being duplicated to n.

Similarly, the redirection operator

1
[n]>&amp;digit-

moves the file descriptor digit to file descriptor n, or the
standard output (file descriptor 1) if n is not specified.

参考:

1
man bash

当地redirection/^REDIRECTto learn to the section,and more…P></

西安地图版本:3.6 is here重定向P></PS:

很多manof the time,to learn the powerful工具为Linux。P></


0表示输入,1表示stdout,2表示stderr。

一个提示:somecmd >1.txt 2>&1是正确的,而somecmd 2>&1 >1.txt是完全错误的,没有效果!