本文介绍: 要将 stderrstdout 组合stdout 流中,我们将其附加到命令中:例如,查看编译 g++ main.cpp 的前几个错误:2>&1 的具体含义是什么?

问:

要将 stderrstdout 组合stdout 流中,我们将其附加到命令中:

2>&1

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

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

2>&1 的具体含义是什么?

答1:

huntsbot.com程序员副业首选,一站式外包任务远程工作创意产品分享订阅平台

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

起初,2>1 可能看起来像是将 stderr 重定向stdout 的好方法。但是,它实际上会被解释为“将 stderr 重定向到名为 1 的文件”。

& 表示后面和前面的是文件描述符,而不是文件名。因此,我们使用2>&1。将 >& 视为重定向合并运算符

但是不应该是&2>&1吗?

@Dominik:不,& 在重定向上下文中仅被解释为表示“文件描述符”。写入command &2>&被解析command &和2>&1,即“在后台运行command然后运行命令2并将其stdout重定向到它的stdout”。

他们为什么选择这种神秘的东西?只是好奇。

但是如何stderr 重定向到名为 '&1' 的文件

@马丁:2>'&1'

答2:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

要将标准输出重定向到 file.txt

echo test > file.txt

这相当于:

echo test 1> file.txt

要将 stderr 重定向到 file.txt

echo test 2> file.txt

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

0 是标准输入

是标准输出

是标准错误

将标准输出重定向到标准错误

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

要将标准错误重定向到标准输出

echo test 2>&1

因此,在 2>&1 中:

2> 将 stderr 重定向到一个(未指定的)文件

&1 将标准错误重定向到标准输出。

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作创意产品订阅服务huntsbot.com

这对你有意义吗,java ... 2&1 >> data.log,我看到我的一位同事这样做了?

@Harry 看起来像是不是 bash 的外壳,或者是拼写错误.. cmd 2>&1 >> somefile.log 会将 stdout/stderr 附加到文件中 - 它与上面基本相同,附加 >> file

@dbr cmd 2>&1 >>file 不会将 stderr 重定向到文件,但 cmd >> file 2>&1 会。订单很重要。在第一种情况下,stderr 被重定向到 shell 的 stdout(如果命令交互式输入的,可能是 tty),然后 stdout 被定向到文件。第二种情况,stdout被定向到文件,然后stderr被定向到同一个地方。

我喜欢上面的答案,但它可能会更清楚一点。 "2>&1" 将标准错误重定向到标准输出的目标。因此,如果您有类似 "ls -l >> directoryContents 2>&1" 的内容结果将是一个名为 directoryContents 的文件,其中将附加工作目录内容。如果执行中有任何错误:错误消息也将在发生时附加到 directoryContents 文件中。

0(or 1,2)>&0(or 1,2) 是否类似于控制输出的选项echo test >test.log 2>&1 与 echo test 2>&1 >test.log 相同吗?

答3:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

关于重定向的一些技巧

关于这一点的一些语法特殊性可能具有重要的行为。有一些关于重定向、STDERR、STDOUT 和参数 ordering 的小示例

1 – 覆盖或附加?

符号 > 表示 重定向。

表示发送一个完整的文件,如果存在覆盖目标(请参阅后面 #3 的 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

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

$ 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使用 |& 代替

语法 command |& … 可用作 command 2>&1 | … 的 别名。关于命令行顺序的相同规则适用。 What is the meaning of operator |& in bash? 上的更多详细信息

那是关于覆盖

虽然 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 控制台中;-)

进一步阅读:如果您喜欢这篇文章,您可以欣赏:How redirection abuse could give strange behaviours

进一步阅读 ||:A function to store both output into separated variables

@fabs 如果你喜欢这个,也许你会喜欢 Open new window for input/output 和/或 Redirections from script himself

答4:

huntsbot.com程序员副业首选,一站式外包任务、远程工作创意产品分享订阅平台。

发现这篇关于重定向的精彩帖子:All about redirections

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

命令 &> 文件

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

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

https://i.stack.imgur.com/huKF2.png

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

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

$ 命令>文件 2>&1

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

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

https://i.stack.imgur.com/1gsdY.png

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

https://i.stack.imgur.com/Ls39g.png

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

https://i.stack.imgur.com/KnuSt.png

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

不过这里要小心!写作

命令>文件2>&1

不等于写:

$ 命令 2>&1 > 文件

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

https://i.stack.imgur.com/OYgDd.png

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

https://i.stack.imgur.com/Jef1c.png

现在 Bash 看到第二个重定向 >file,并将 stdout 重定向到文件:

https://i.stack.imgur.com/LR04L.png

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

另请注意,在 Bash 中,写作

命令 &> 文件

与以下内容完全相同:

$ 命令>&文件

如果“command”以数字结尾,则最后两个不同,因为它被视为 >& 的可选文件描述符

非常漂亮的绘图解释!您能否详细说明重复”的真正含义?您提到过,“这个 [2>&1] 将文件描述符 2 复制为文件描述符 1 的副本”。听起来标准错误被复制到标准输出。但如果是这种情况,我是否也应该通过 /dev/tty0 看到错误?

这是一个非常好的视觉解释。如果我成为提出这个问题的人,我会将其标记为已接受的答案

答5:

huntsbot.com – 高效赚钱,自由工作

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

零是标准输入

一个是标准输出

二是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 工具,因此除非将其重定向到文件或其他内容,否则您看不到它。

只使用您自己的“非标准文件描述符”可以吗?你怎么知道没有打开的文件具有相同的 FD?

答6:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

构造将标准错误流 (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

更清楚,是的,但这不会显示重定向的“位置”性质。该示例是人为设计的,因为在一行中执行此操作通常没有用 - 当不同的各方负责重定向的不同部分时,该方法变得非常有用。例如,当一个脚本做了一个重定向,而你用另一个位运行它。

我刚刚意识到,最后一个示例解决了我长期以来的困惑,即为什么some_program 2>&1 > /dev/null 不能像这样工作:some_program > /dev/null 2>&1。

您对最后一个示例评论值得它用金色的字母表示:-) 我从没想过这些重定向参数位置的……我认为了解这一点非常重要。

答7:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入分类筛选,希望这些产品与实践经验能给您带来灵感。

如果您是初学者阅读this,我发现这非常有用

更新:在 Linux 或 Unix 系统中,程序将输出发送到两个位置:标准输出 (stdout) 和标准错误 (stderr)。您可以将这些输出重定向到任何文件。 如果您这样做 ls -a > output.txt 控制台中不会打印任何内容,所有输出 (stdout) 都会重定向到输出文件。

如果您尝试打印任何未退出文件的内容,则意味着输出将是一个错误,例如您打印当前目录中不存在的 test.txt cat test.txt > error.txt 输出将是

cat: test.txt :No such file or directory

但是 error.txt 文件将是空的,因为我们将标准输出重定向到一个文件而不是标准错误。 所以我们需要文件描述符(文件描述符只不过是一个正整数,代表一个打开的文件。你可以说描述符是文件的唯一 id)来告诉 shell 我们将哪种类型的输出发送到文件.在 Unix /Linux 系统中 1 用于标准输出,2 用于标准错误。 所以现在如果你这样做 ls -a 1> output.txt 意味着你正在将标准输出 (stdout) 发送到 output.txt。 如果您这样做 cat test.txt 2> error.txt 意味着您将标准错误 (stderr) 发送到 error.txt 。 &1 用于引用文件描述符 1 (stdout) 的值。 现在到点 2>&1 的意思是“将 stderr 重定向到我们正在重定向 stdout 的同一位置” 现在您可以执行此操作了 cat maybefile.txt > output.txt 2>&1 标准输出 (stdout) 和标准错误 (stderr) 都将重定向到 output.txt。

感谢Ondrej K.指出

+1 表示“&1 用于引用文件描述符 1 (stdout) 的值。”。我一直想知道为什么不只是2>1

答8:

HuntsBot周刊–不定时分享成功产品案例学习他们如何成功建立自己的副业–huntsbot.com

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

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

&:Duplicate an Output File Descriptor 运算符(Output Redirection 运算符 > 的变体)。给定 [x]>&[y],由 x 表示的文件描述符是输出文件描述符 y 的副本。

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

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

进一步说明

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

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

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

答9:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

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< /i>(不是 STDERR)见 my answer(第 #2 段)!为了确保 both 被重定向到同一个文件,您必须反转重定向指令:perl test.pl > debug.log 2>&1

答10:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入分类筛选,希望这些产品与实践经验能给您带来灵感。

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

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

为了帮助你记住

= 标准输出(程序打印正常输出)

2 = 标准错误(程序打印错误)

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

我还建议阅读this post on error redirecting,其中详细介绍了该主题

答11:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

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

dup2(1, 2);

请参阅 man page

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

command >file 2>&1

……不等于……

command 2>&1 >file

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

原文链接https://www.huntsbot.com/qa/4lLw/in-the-shell-what-does-21-mean?lang=zh_CN&from=csdn

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求

原文地址:https://blog.csdn.net/kalman2019/article/details/128439907

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_13499.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注