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。
答案 0 :(得分:6)
<&
运算符复制“输入”文件描述符。根据IEEE Std 1003.1-2001(也就是单一Unix规范v3,POSIX的后继者),如果1不是为输入打开的文件描述符,则说2<&1
是错误的。但是,似乎bash
是惰性的,并不关心文件描述符是打开输入还是输出。
因此,2<&1
和2>&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_input
和r_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