bash - 在shell , 什么是" 2>&1 ”?

  显示原文与译文双语对照的内容
0 0

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

2>&1

所以,如果我想用"头部"G++的输出,我可以这样做:

g++ lots_of_errors 2>&1 | head

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

我总是很难记住这个,我经常去查找它,这主要是因为我没有完全理解这个技巧的语法。 有人能把它分解并用字符解释" 2> & 1"意味着什么?

时间:原作者:18个回答

0 0

1 是标准标准。2是标准标准。

下面是记住这里构造( altough这不是完全准确的)的一种方法: 首先,2>1 看起来像是一个将stderr重定向到stdout的好方法。 但是,它实际上将被解释为"将stderr重定向到名为 1的文件"。 & 表示以下内容是一个文件描述符,而不是文件名。 所以构造变成:2>&1

原作者:
0 0
echo test> afile.txt

将stdout重定向到 afile.txt 。这与操作相同。

echo test 1> afile.txt

要重定向 stderr,你需要。

echo test 2> afile.txt

>& 是将流重定向到另一个文件描述符的语法- 0是标准。 1 是标准标准。2是标准标准。

可以将stdout重定向到 stderr 。

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

或者反之亦然:

echo test 2>&1

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

原作者:
0 0

关于重定向的一些技巧

某些语法特殊性可能有重要的行为。 有一些样品重定向、STDERRSTDOUT订购和参数。

1 - Overwritting或者附加?

Symbole > 意味着重定向 。

  • > 表示发送为完整完整的文件,如果存在( 看到 noclobber bash特性 #3 之后),覆盖目标。
  • >> - 除了以外的- - 还将附加到目标。

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

2 - 壳 命令行的顺序依赖于 !

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

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

注意,这个段落中的最后一个 命令行 与前面的paraghaph完全一样,在这里我编写的似乎不是 ( 所以,这可能是一个预期的行为)的预期行为。

有一个重定向的小技巧,做不同的操作在两个 ouputs :

$ ( 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 而自发出现。

附录:背板与新版本的 ( >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

和finaly用于这样的级联输出格式:

$ ((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 到另一个,最后两个输出合并通过第三个命令筛选。

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

这是关于 overwritting :

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

文件每次都是 overwritted,现在:

$ 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 

注:如果 2>&1 存在, 1>&2 syntaxe是正确的:

$ 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

控制台控制台中;- )

原作者:
0 0
  • 2 是stderr的默认文件描述符。
  • 1 是输出的默认文件描述符。
  • >& 是"折叠上一个( 第一个) 文件描述符到即将到来的( 第二个) 文件描述符的外壳语法。"
原作者:
0 0

,构造发送标准错误流( stderr ) 目前的标准输出( stdout ) 位置——这汇率问题似乎忽视了其他的答案。

通过使用这里方法,可以将任何输出句柄重定向到另一个输出句柄,但最常用的方法是将 stdoutstderr 流用于单个流,以便处理。

下面是一些示例:

# 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 ) 和 重定向 stdoutoutfile2

这允许一些相当复杂的技巧。

原作者:
0 0

这些数字指向文件描述符( 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. */

说我已经编写了使用non-standard文件描述符进行自定义日志记录的工具,这样你就不会看到它,除非你把它重定向到一个文件或者其他东西。

原作者:
0 0

2 是控制台标准错误。

1 是控制台标准输入。

这是标准的Unix,Windows 也遵循 POSIX 。 比如 当你运行时

perl test.pl 2>&1 

标准错误被重定向到标准输出,这样你就可以同时看到两个输出。

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

执行之后,你可以看到来自 debug.log.的所有文件

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

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

我建议你试着理解这些。

原作者:
...