“2<&1”是什么意思在 Bourne shell 中重定向做什么?
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
请注意,标准输出和标准错误都发送到文件 out3,其中 stdout被重定向。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
<&
运算符复制“输入”文件描述符。根据 IEEE Std 1003.1-2001(又名单一 Unix 规范 v3,POSIX 的后继者),如果 1 不是打开输入的文件描述符,则2<&1
应该是错误的。但是,bash 似乎很懒,并且不关心文件描述符是否打开以供输入或输出。因此
2<&1
和2>&1
都只是执行系统调用dup2(1, 2)
,该调用复制文件描述符1 到文件描述符 2。您可以通过运行这样的命令进行检查,因为重定向是从左到右执行的:
然后在另一个窗口中,在
sleep
上运行lsof
过程。您将看到文件描述符 1 和 2 都指向/dev/null
。示例(在我的 Mac 上):The
<&
operator duplicates an “input” file descriptor. According to IEEE Std 1003.1-2001 (aka Single Unix Specification v3, the successor to POSIX), it's supposed to be an error to say2<&1
if 1 is not a file descriptor open for input. However, it appears thatbash
is lazy and doesn't care if the file descriptor is open for input or for output.So both
2<&1
and2>&1
simply perform the system calldup2(1, 2)
, which copies file descriptor 1 to file descriptor 2.You can check by running a command like this, since redirections are performed left-to-right:
Then in another window, run
lsof
on thesleep
process. You'll see that both file descriptors 1 and 2 point to/dev/null
. Example (on my Mac):查看 Bash 源代码中的解析器代码,似乎
2>&1
的处理方式与2<&1
相同。parse.y
查看重定向源
redir.c
,常量r_duplicating_input
和r_duplicating_output
似乎被处理为同样的方式。与make_cmd.c
中的make_redirection
函数相同。使用一个简单的程序进行测试,该程序将“yay”打印到stdout,将“nay”打印到stderr,我可以确认您的测试结果:
Looking at the parser code in the source for Bash, it seems that
2>&1
is treated in the same way as2<&1
.parse.y
Looking through the redirection source
redir.c
, the constantsr_duplicating_input
andr_duplicating_output
seem to be treated in the same way. Same as in themake_redirection
function inmake_cmd.c
.Testing with a simple program that prints "yay" to stdout and "nay" to stderr, I can confirm your test results:
来自 REDIRECTION 下的
man bash
:因此,在 2<&1 的情况下,似乎
2
( stderr)被制作为1
(stdout)的副本。我用1<&2
的另一种方式对其进行了测试,使 stdout 成为 stderr 的副本。因此,在测试程序中:
在命令行上运行时, hello 输出到 stderr 而不是 stdout
From
man bash
under REDIRECTION:So in the case of 2<&1, it seems that
2
(stderr) is made to be a copy of1
(stdout). I've tested it with the other way around1<&2
makes stdout to be a copy of stderr.So in a test program:
When run on command line, hello is output to stderr not stdout