要将stderr和stdout合并到stdout流中,我们将其附加到命令中:

2>&1

例如,查看编译g++main.cpp时的前几个错误:

g++ main.cpp 2>&1 | head

2>&1的详细含义是什么?


当前回答

关于重定向的一些技巧

这方面的某些语法特殊性可能具有重要的行为。这里有一些关于重定向、STDERR、STDOUT和参数排序的小示例。

1-覆盖还是附加?

符号>表示重定向。

>意味着作为一个完整的文件发送到,如果存在则覆盖目标(请参阅后面的noclobber bash特性)。>>表示除了发送之外,如果存在,将附加到目标。

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

2-shell命令行依赖于顺序!!

为了测试这一点,我们需要一个简单的命令,它将在两个输出上发送一些信息:

$ 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

(当然,您应该没有名为/tnt的目录;)。好吧,我们成功了!!

那么,让我们看看:

$ 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

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

如果要对标准输出、错误输出或两者进行一些后置过滤:

$ 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 --->

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

嗯,关于重定向有一些小技巧,可以在两个输出上执行不同的操作:

$ ( 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

注意:&9描述符会自发出现,因为)9>&2。

附录:nota!在新版本的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

最后,对于这种级联输出格式:

$ ((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

附录:nota!两种方式都有相同的新语法:

$ 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通过特定的过滤器,STDERR到另一个,最后合并的两个输出通过第三个命令过滤器。

2b-改用|&

语法命令|&。。。可以用作命令2>&1|…的别名。。。。关于命令行顺序的规则也适用。更多详细信息,请参见bash中运算符|&的含义是什么?

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

这是关于覆盖:

虽然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

文件每次都会被覆盖,现在:

$ 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

通过>|:

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

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

取消设置此选项和/或查询(如果已设置)。

$ 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-最后一个技巧和更多。。。

对于重定向给定命令的两个输出,我们看到正确的语法可以是:

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

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

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

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

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

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

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-如果您对更多信息感兴趣

您可以点击以下按钮来阅读精细手册:

man -Len -Pless\ +/^REDIRECTION bash

在bash控制台中;-)

其他回答

这些数字表示文件描述符(fd)。

零是标准输入一个是标准输出二是标准错误

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

如果程序使用任何数量的文件描述符,这都适用。

如果忘记了,可以查看/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.  */

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

要将stdout重定向到file.txt:

echo test > file.txt

这相当于:

echo test 1> file.txt

要将stderr重定向到file.txt:

echo test 2> file.txt

所以>是将流重定向到另一个文件描述符的语法(&I):

0是标准输入1是标准输出2是标准错误

要将stdout重定向到stderr:

echo test 1>&2   # equivalently, echo test >&2

要将stderr重定向到stdout:

echo test 2>&1

因此,在2>&1中:

2> 将stderr重定向到(未指定)文件。&1将stderr重定向到stdout。

关于重定向的一些技巧

这方面的某些语法特殊性可能具有重要的行为。这里有一些关于重定向、STDERR、STDOUT和参数排序的小示例。

1-覆盖还是附加?

符号>表示重定向。

>意味着作为一个完整的文件发送到,如果存在则覆盖目标(请参阅后面的noclobber bash特性)。>>表示除了发送之外,如果存在,将附加到目标。

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

2-shell命令行依赖于顺序!!

为了测试这一点,我们需要一个简单的命令,它将在两个输出上发送一些信息:

$ 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

(当然,您应该没有名为/tnt的目录;)。好吧,我们成功了!!

那么,让我们看看:

$ 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

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

如果要对标准输出、错误输出或两者进行一些后置过滤:

$ 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 --->

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

嗯,关于重定向有一些小技巧,可以在两个输出上执行不同的操作:

$ ( 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

注意:&9描述符会自发出现,因为)9>&2。

附录:nota!在新版本的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

最后,对于这种级联输出格式:

$ ((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

附录:nota!两种方式都有相同的新语法:

$ 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通过特定的过滤器,STDERR到另一个,最后合并的两个输出通过第三个命令过滤器。

2b-改用|&

语法命令|&。。。可以用作命令2>&1|…的别名。。。。关于命令行顺序的规则也适用。更多详细信息,请参见bash中运算符|&的含义是什么?

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

这是关于覆盖:

虽然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

文件每次都会被覆盖,现在:

$ 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

通过>|:

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

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

取消设置此选项和/或查询(如果已设置)。

$ 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-最后一个技巧和更多。。。

对于重定向给定命令的两个输出,我们看到正确的语法可以是:

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

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

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

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

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

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

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-如果您对更多信息感兴趣

您可以点击以下按钮来阅读精细手册:

man -Len -Pless\ +/^REDIRECTION bash

在bash控制台中;-)

重定向输入输入重定向导致文件名为将要打开以读取文件的单词展开的结果描述符n或标准输入(文件描述符0),如果n是未指定。重定向输入的一般格式为:[n] <单词重定向输出输出重定向导致文件name是将要打开以供书写的单词展开后的结果文件描述符n或标准输出(文件描述符1),如果n未指定。如果文件不存在,则创建该文件;如果它它被截断为零大小。重定向输出的一般格式为:[n] >单词移动文件描述符重定向运算符,[n] <数字(&D)-将文件描述符数字移动到文件描述符n,或如果未指定n,则为标准输入(文件描述符0)。数字在复制到n之后是闭合的。类似地,重定向运算符[n] >数字(&D)-将文件描述符数字移动到文件描述符n,或如果未指定n,则为标准输出(文件描述符1)。

Ref:

man bash

键入/^REDIRECT以定位到重定向部分,并了解更多信息。。。

这里有一个在线版本:3.6重定向

PS:

很多时候,人类是学习Linux的强大工具。

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

例如,当您需要为所有输出分页时,这对于“more”很有用。有些程序喜欢将使用信息打印到stderr中。

帮助你记住

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

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

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