Bourne shell中“2<& 1”重定向有什么作用?

时间:2012-02-17 19:39:13

标签: bash shell redirect sh

Bourne shell中的

2>&1重定向将输出发送到文件描述符2(默认情况下为标准错误)并将其发送到文件描述符1(默认为标准输出)。

2<&1重定向的作用是什么?

它是否将stderr发送给stdin?

我的理论是它将stdin发送到stderr(例如与1>&2相同)但实验上并非如此:

$ perl -e 'print "OUT\n"; print STDERR "ERR\n"; \
  while (<>) { print "IN WAS $_\n";}'           \
  > out3 2<&1
df
$ cat out3
ERR
OUT
IN WAS df

请注意,标准输出AND标准错误都转到文件out3,其中重定向了stdout。

3 个答案:

答案 0 :(得分:6)

<&运算符复制“输入”文件描述符。根据IEEE Std 1003.1-2001(也就是单一Unix规范v3,POSIX的后继者),如果1不是为输入打开的文件描述符,则说2<&1是错误的。但是,似乎bash是惰性的,并不关心文件描述符是打开输入还是输出。

因此,2<&12>&1只执行系统调用dup2(1, 2),将文件描述符1复制到文件描述符2.

您可以通过运行这样的命令来检查,因为重定向是从左到右执行的:

sleep 99999 1>/dev/null 2<&1

然后在另一个窗口中,在lsof进程上运行sleep。您将看到文件描述符1和2都指向/dev/null。示例(在我的Mac上):

:; ps axww | grep sleep
 8871 s001  R+     0:00.01 grep sleep
 8869 s003  S+     0:00.01 sleep 99999
:; lsof -p 8869 | tail -2
sleep   8869 mayoff    1w   CHR    3,2       0t0       316 /dev/null
sleep   8869 mayoff    2w   CHR    3,2       0t0       316 /dev/null

答案 1 :(得分:4)

查看Bash源代码中的解析器代码,似乎2>&1的处理方式与2<&1相同。

<强> parse.y

|   NUMBER LESS_AND NUMBER
        {
          redir.dest = $3;
          $$ = make_redirection ($1, r_duplicating_input, redir);
        }
...
|   NUMBER GREATER_AND NUMBER
        {
          redir.dest = $3;
          $$ = make_redirection ($1, r_duplicating_output, redir);
        }

查看重定向源redir.c,常量r_duplicating_inputr_duplicating_output似乎以同样的方式处理。与make_redirection中的make_cmd.c函数相同。

使用一个简单的程序进行测试,将“yay”打印到stdout,将“nay”打印到stderr,我可以确认您的测试结果:

$ ./a.out > out 2>&1
$ cat out
nay
yay
$ ./a.out > out 2<&1
$ cat out
nay
yay
$ ./a.out > out 1>&2
yay
nay
$ cat out
$ ./a.out > out 1<&2
yay
nay
$ cat out
$

答案 2 :(得分:0)

来自 REDIRECTION 下的man bash

   Duplicating File Descriptors
       The redirection operator

              [n]<&word

       is used to duplicate input  file  descriptors.   If  word
       expands  to  one  or  more  digits,  the  file descriptor
       denoted by n is made to be a copy of that  file  descrip‐
       tor.   If  the  digits  in  word  do  not  specify a file
       descriptor open for input, a  redirection  error  occurs.
       If  word evaluates to -, file descriptor n is closed.  If
       n is not specified, the standard input  (file  descriptor
       0) is used.

因此,在 2&lt;&amp; 1 的情况下,2 stderr )似乎是{{1}的副本}(标准输出)。我已经用1使 stdout 作为 stderr 的副本进行了相反的测试。

所以在测试程序中:

1<&2

在命令行上运行时, hello 输出到 stderr 而不是 stdout

#!/bin/bash
echo hello 1<&2