stderr
和stdout
合并到stdout
流中以进行进一步的操作,可以在命令末尾附加以下内容:2>&1
因此,如果我想在
head
的输出上使用g++
,则可以执行以下操作: 我总是很难记住这一点,而且我经常不得不去查找它,这主要是因为我不完全了解该特殊技巧的语法。
有人可以分解并逐个字符地解释
2>&1
是什么意思吗?#1 楼
文件描述符1是标准输出(stdout
)。文件描述符2是标准错误(
stderr
)。这是记住此构造的一种方法(尽管并不完全准确):首先, 2>1
可能是将stderr
重定向到stdout
的好方法。但是,它实际上将被解释为“将stderr
重定向到名为1
的文件”。 &
指示紧随其后的是文件描述符而不是文件名。因此,构造变为:2>&1
。将
>&
视为重定向合并运算符。评论
但是不应该是&2>&1吗?
– dokaspar
2013年9月4日在6:12
@Dominik:不,&在重定向的上下文中仅解释为“文件描述符”。写入命令&2>&被解析为命令&和2>&1,即“在后台运行命令,然后运行命令2并将其标准输出重定向到其标准输出”。
–亚当·罗森菲尔德
2014年1月28日,0:02
他们为什么选择这种神秘的东西?只是好奇。
– ComaToast
2014年5月17日4:00
但是,如何将stderr重定向到名为“&1”的文件?
–马丁·菲克斯曼(MartínFixman)
2014年11月4日在17:07
@马丁:2>'&1'
–user1247058
16-3-14在10:46
#2 楼
echo test > afile.txt
将标准输出重定向到
afile.txt
。这与执行echo test 1> afile.txt
一样,要重定向stderr,请执行以下操作:将流重定向到另一个文件描述符的语法-0是stdin,1是stdout,2是stderr。
您可以执行以下操作将stdout重定向到stderr:
echo test 2> afile.txt
反之亦然:
echo test 1>&2 # or echo test >&2
因此,简而言之...
>&
将stderr重定向到(未指定)文件,附加2>
会将stderr重定向到标准输出。评论
java ... 2&1 >> data.log对我来说有什么用,我看到我的一位同事做到了吗?
–唐法
2011年7月26日19:53
@Harry看起来像不是bash的外壳或错字.. cmd 2>&1 >> somefile.log会将stdout / stderr附加到文件中-与上面的基本相同,并附加>>文件
– dbr
11年7月27日在0:38
@dbr cmd 2>&1 >> file不会将stderr重定向到该文件,但是cmd >>文件2>&1可以。顺序很重要。在第一种情况下,将stderr重定向到shell的stdout(如果以交互方式输入命令,则可能是tty),然后将stdout定向到该文件。在第二种情况下,将stdout定向到文件,然后将stderr定向到同一位置。
–威廉·珀塞尔(William Pursell)
13年7月19日在13:15
我喜欢上面的答案,但可能会更清晰。 “ 2>&1”将stderr重定向到stdout的目标。因此,如果您有类似“ ls -l >> directoryContents 2>&1”的内容,结果将是一个名为directoryContents的文件,并将工作目录的内容附加到该文件中。如果执行中有任何错误:错误消息也将在出现时附加到directoryContents文件中。
–马克斯·韦斯特
15年4月17日在17:36
0(或1,2)>&0(或1,2)是否像控制输出的选项一样? echo test> test.log 2>&1是否与echo test 2>&1> test.log相同?
–Simin Jie
18 Jun 1'在12:58
#3 楼
有关重定向的一些技巧对此的某些语法特殊性可能具有重要的行为。有关重定向,
STDERR
,STDOUT
和参数排序的一些示例。### 1-覆盖还是追加? ###
符号
>
表示平均重定向。 br /> >
表示如果存在,除了发送之外还会附加到目标。在任何情况下,如果文件不存在,则会创建该文件。 -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
(期望您没有名为的目录
noclobber
,当然;)。好吧,我们有了它!所以,让我们来看一下:
$ 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
最后一个命令行将
>>
转储到控制台,这似乎并不是预期的行为...但是。如果要对标准输出,错误输出或这两者进行一些后期过滤:
$ 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
注释:由于
/tnt
,STDERR
描述符会自发出现。附录:nota!使用新版本的bash(
&9
),有一个新功能和更性感的语法可以执行以下操作:$ 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
最后是这种级联输出格式: />附录:nota!两种方式的语法都相同:### 3-关于
) 9>&2
选项和>4.0
语法的一句话### 那是关于覆盖: br />
$ ((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
每次都覆盖该文件,现在:
$ 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
传递:设置。$ 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
### 4-最后的技巧等等... ###
对于重定向给定命令的两个输出,我们看到正确的语法可能是:
$ 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
对于这种特殊情况,有一个快捷语法:
STDERR
...或noclobber
$ 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 noclobber
也是正确的语法:$ 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
### 4b-现在,我会让您考虑:
$ ls -ld /tmp /tnt >/dev/null 2>&1
### 4c-如果您对更多信息感兴趣
您可以阅读在bash控制台中按以下命令进行手动操作:
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
;-)
评论
进一步阅读:如果您喜欢这样做,您可能会喜欢:重定向滥用如何产生奇怪的行为
– F. Hauri
2013年12月10日21:14
进一步阅读||:将两个输出都存储到单独变量中的函数
– F. Hauri
15年1月18日在12:37
#4 楼
我发现了有关重定向的出色文章:有关重定向的所有内容将标准输出和标准错误都重定向到文件中
$ command&> file
这种单一代码使用
&>
运算符将两个输出流-stdout和stderr-从命令重定向到文件。这是Bash快速将两个流都重定向到同一目标的快捷方式。这是Bash重定向两个流后文件描述符表的外观:
您可以看到,stdout和stderr现在都指向
file
。因此,写入stdout和stderr的所有内容都会写入file
。有几种方法可以将两个流重定向到相同的目的地。您可以一个接一个地重定向每个流:
$命令>文件2>&1
这是重定向两个流的更常见的方法流到文件。首先将stdout重定向到文件,然后将stderr复制为与stdout相同。因此,两个流最终都指向
file
。当Bash看到多个重定向时,它将从左到右对其进行处理。让我们看一下步骤,看看如何发生。在运行任何命令之前,Bash的文件描述符表如下所示:
现在Bash处理第一个重定向>文件。我们之前已经看到过,它使stdout指向文件:
下一个Bash看到了第二个重定向2>&1。我们之前从未见过这种重定向。这将文件描述符2复制为文件描述符1的副本,我们得到:
两个流都已重定向到文件。 >但是请注意这里!编写
命令>文件2>&1
与编写不同:
$命令2>&1>文件
重定向的顺序在Bash中很重要!此命令仅将标准输出重定向到文件。 stderr仍将打印到终端。要了解为什么会发生这种情况,让我们再次执行这些步骤。因此,在运行命令之前,文件描述符表如下所示:
现在Bash处理从左到右的重定向。它首先看到2>&1,因此将stderr复制到stdout。文件描述符表变为:
现在Bash看到了第二个重定向
>file
,它将stdout重定向到文件: /> 您看到这里发生了什么吗? Stdout现在指向文件,但是stderr仍然指向终端!写入stderr的所有内容仍会打印到屏幕上!因此,请非常小心重定向的顺序!
还要注意,在Bash中,编写
$ command&> file
与以下命令完全相同:
$命令>&file
评论
如果“命令”以数字结尾,则后两个是不同的,因为这被视为>&的可选文件描述符
– M.M
17年1月23日在12:09
非常好的绘图和解释!您能否解释“重复”的真正含义?您提到:“此[2>&1]将文件描述符2复制为文件描述符1的副本”。听起来好像stderr被复制到stdout。但是如果是这样,我是否也应该通过/ dev / tty0看到err?
–HCSF
19年7月22日在2:35
这是一个很好的视觉解释。如果我成为提出这个问题的人,我会将其标记为已接受的答案。
– MaXi32
10月18日,3:43
#5 楼
数字指的是文件描述符(fd)。零是
stdin
一个是
stdout
两个是
stderr
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工具,因此除非将其重定向到文件或其他内容,否则您将看不到它。
#6 楼
该构造将标准错误流(stderr
)发送到标准输出(stdout
)的当前位置-此货币问题似乎已被其他答案忽略。您可以将任何输出句柄重定向到另一个通过使用此方法,但最常用于将
stdout
和stderr
流引导到单个流中进行处理。一些示例是:
# 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
请注意,最后一个不会将
stderr
定向到outfile2
-它会在遇到参数时将其重定向到stdout
(outfile1
),然后将stdout
重定向到outfile2
。 评论
尽管最后一个示例更加清楚:foo> outfile2 2> outfile1
– Michael Cramer
09年5月4日,0:15
显然,是的,但是不会显示重定向的“位置”性质。该示例是人为设计的,因为通常不要单行执行此操作-当不同方负责重定向的不同部分时,该方法将变得非常有用。例如,当脚本执行一小段重定向,而您又执行另一段重定向时。
– paxdiablo
09年5月4日,0:19
我只是意识到,最后一个示例也解决了我对此的长期困扰:some_program 2>&1> / dev / null不能这样工作:some_program> / dev / null 2>&1。
–snapfractalpop
2012年12月20日13:58
您对最后一个示例的评论值得用金色表示:-)我从没想过这些重定向参数是有位置的……我想知道这一点很重要。
– Nils-o-mat
18年4月18日在9:04
#7 楼
2>&1
是POSIX shell构造。以下是逐个标记的细分:2
:“标准错误”输出文件描述符。>&
:复制输出文件描述符运算符(变体)输出重定向运算符>
)。给定[x]>&[y]
,将使x
表示的文件描述符成为输出文件描述符y
的副本。1
“标准输出”输出文件描述符。将文件描述符2>&1
复制到位置1
,因此在执行环境中写入2
的任何输出(“标准错误”)都将移至最初由2
描述的同一文件(“标准输出”)。 />进一步说明:文件描述符:“每个进程的唯一非负整数,用于标识打开的文件以用于文件访问。”输出/错误:请参考Shell文档的“重定向”部分中的以下说明:打开文件由从零开始的十进制数字表示。可能的最大值是实现定义的;但是,所有实现应至少支持0到9(含),以供应用程序使用。这些数字称为“文件描述符”。值0、1和2具有特殊含义和常规用法,并且由某些重定向操作隐含;这些值可能会与其他值无关。它们分别称为标准输入,标准输出和标准误差。程序通常从标准输入中获取输入,然后将输出写入标准输出中。错误消息通常写在标准错误上。重定向运算符可以以一个或多个数字开头(不允许插入字符)来指定文件描述符号。
#8 楼
2是控制台标准错误。1是控制台标准输出。
这是标准Unix,Windows也遵循POSIX。
例如运行
perl test.pl 2>&1
标准错误将重定向到标准输出,因此您可以同时看到两个输出:
perl test.pl > debug.log 2>&1
执行后,您可以在debug.log中看到所有输出,包括错误。
perl test.pl 1>out.log 2>err.log
然后标准输出进入out.log,并且err.log的标准错误。
我建议您尝试理解这些内容。
评论
第二个示例是错误的:由于将顺序优先级STDERR重定向到STDOUT,因此只有默认的STDOUT才会被写入debug.log(不是STDERR),请参见我的答案(第2段)!为了确保两者都重定向到同一文件,您必须反转重定向指令:perl test.pl> debug.log 2>&1
– F. Hauri
2015年2月10日在16:04
#9 楼
回答您的问题:它接受任何错误输出(通常发送到stderr)并将其写入标准输出(stdout)。这很有用,例如当您需要对所有输出进行分页时使用“更多”。有些程序喜欢将使用情况信息打印到stderr中。
为了帮助您记住
1 =标准输出(其中程序打印正常输出)
2 =标准错误(程序会打印错误)
“ 2>&1”只是将发送到stderr的所有内容都指向stdout。
我还建议阅读这篇有关错误重定向的文章,其中该主题已详细介绍。
#10 楼
如果您是初学者,请阅读以下内容:更新:
在Linux或Unix系统中,程序将输出发送到两个位置:标准输出(stdout)和标准错误(stderr) )。您可以将这些输出重定向到任何文件。
如果执行此操作,则不会被打印在控制台中。所有输出(stdout)都将重定向到输出文件。
如果您尝试打印不退出的任何文件的内容,则输出将是一个错误,例如,如果您打印当前目录中不存在的test.txt
ls -a > output.txt
输出将是
cat: test.txt :No such file or directory
但是error.txt文件将为空,因为我们将标准输出重定向到了不是stderr的文件。
,所以我们需要文件描述符(文件描述符只不过是代表打开的文件的正整数。您可以说描述符是文件的唯一ID)来告诉Shell我们要发送到文件的输出类型。 Unix / Linux系统1用于stdout,2用于stderr。
因此,如果现在执行此操作,则
cat test.txt > error.txt
意味着您正在将标准输出(stdout)发送到output.txt。 ,如果执行此操作,则
ls -a 1> output.txt
表示您正在将标准错误(stderr)发送到error.txt。 cat test.txt 2> error.txt
用于引用文件描述符1(stdout)的值。可以做到这一点&1
标准输出(stdout)和标准错误(stderr)都将重定向到output.txt。感谢Ondrej K.指出
评论
仅链接答案是有问题的。链接可能会失效,导致答案无用。您应该始终在答案本身中包含足够的细节。
– Ondrej K.
4月1日17:51
#11 楼
从程序员的角度来看,它的含义恰恰是:为什么...dup2(1, 2);
...与...
command >file 2>&1
不同第一个将两个流都发送到
2>&1
,第二个将错误发送到file
,普通输出到stdout
。#12 楼
人们,永远记住paxdiablo关于重定向目标当前位置的提示...这很重要。我对
2>&1
运算符的个人记忆是:将
&
理解为'and'
或'add'
(字符是安培字符,对吗?)因此变成:'将
2
(stderr)重定向到已经/当前1
(stdout)所在的位置并添加两个流都相同。相同的助记符也可用于其他常用的重定向
1>&2
:考虑
&
的意思是and
或add
...(您了解与号的想法,是吗?)它变成:'将
1
(stdout)重定向到2
(stderr)已经/当前所在的位置,并同时添加两个流'。并且总是请记住:您必须从右到左(而不是从左到右)“从头到尾”读取重定向链。
#13 楼
重定向输入
输入重定向导致打开其名称
是由于单词扩展而产生的文件,以读取文件
描述符n或标准输入(文件描述符0)如果未指定n。
重定向输入的常规格式为:
[n]<word
重定向输出
输出的重定向导致打开其名称为
的单词的文件打开以写入
文件描述符n或标准输出(文件描述符1)未指定n
。如果文件不存在,则创建该文件;如果确实存在,则将其截断为零大小。
重定向输出的常规格式为:
[n]>word
移动文件描述符
重定向运算符
[n]<&digit-
将文件描述符数字移动到文件描述符n或
标准输入(文件描述符0)如果未指定n。
将数字复制到n后将其关闭。
同样,重定向运算符
[n]>&digit-
将文件描述符数字移动到文件描述符n,如果未指定n,则将其移动到标准输出(文件描述符1)。
Ref:
man bash
键入
/^REDIRECT
定位到redirection
部分,并了解更多信息... 在线版本在这里:3.6重定向
PS:
很多时候,
man
是学习Linux的强大工具。#14 楼
如果系统上不存在/foo
,而/tmp
不存在... $ ls -l /tmp /foo
将打印
/tmp
的内容并为/foo
打印错误消息$ ls -l /tmp /foo > /dev/null
会将
/tmp
的内容发送到/dev/null
并打印/foo
的错误消息$ ls -l /tmp /foo 1> /dev/null
将执行完全相同的操作(请注意1)
$ ls -l /tmp /foo 2> /dev/null
将打印
/tmp
的内容并将错误消息发送到/dev/null
$ ls -l /tmp /foo 1> /dev/null 2> /dev/null
将将清单和错误消息都发送到
/dev/null
$ ls -l /tmp /foo > /dev/null 2> &1
是速记
#15 楼
这就像将错误传递到标准输出或终端一样。,即
cmd
不是命令:$cmd 2>filename
cat filename
command not found
错误被发送到以下文件:
2>&1
标准错误被发送到终端。
#16 楼
unix_commands 2>&1
用于将错误打印到终端。
以下说明了该过程
产生错误时,它们将被写入标准错误流
&2
所引用的标准错误存储器地址2
“缓冲区”。产生输出时,会将其写入到标准输出存储器地址
&1
“缓冲区”中,标准输出流1
引用。因此,请使用unix_commands
标准错误流2
,并将>
流(错误)重定向到标准输出内存地址&1
,以便将它们流式传输到终端并打印。 #17 楼
输入为0,标准输出为1,标准错误为2。提示:
somecmd >1.txt 2>&1
是正确的,而somecmd 2>&1 >1.txt
是完全错误的,没有任何作用!#18 楼
请注意,1>&2
不能与2>&1
互换使用。想象一下您的命令取决于管道,例如:
docker logs 1b3e97c49e39 2>&1 | grep "some log"
stderr
和stdout
都将发生夹持,因为stderr
已基本合并到stdout
中。 ,如果尝试这样做:docker logs 1b3e97c49e39 1>&2 | grep "some log"
,根本不会真正进行任何搜索,因为Unix管道通过连接
stdout | stdin
来连接进程,并且在第二种情况下stdout
被重定向到stderr
,而Unix管道对此没有兴趣。 >
评论
@dbr我不认为这只是猛击-我相信这是一个波恩壳的东西;因此是sh,bash,ksh,灰,破折号等。这是重定向段的一部分,该段描述了POSIX兼容的shell,或简称POSIX shell。例如,ksh是POSIX shell。参见:pubs.opengroup.org/onlinepubs/009695399/utilities/…
此构造也可在Windows上使用。
通常做2>&1比2> / dev / null ;-)
我以为我会提到|&是2>&1 |的简写。如果您使用的是zsh。我不能说这是否适用于其他类似bourne的shell或仅zsh功能。