有'>& 0'的用途(重定向到标准输入)?

时间:2012-04-14 18:19:42

标签: bash unix

在bash中你可以这样做:

  • echo test >&1(重定向到stdout,虽然它已经到了那里)
  • echo test >&2(重定向到stderr)
  • echo test >&0(重定向到标准输入)

当我做最后一个时,我的终端仍然会像其他两个一样打印test,但很难知道原因。首先,为什么这个有用呢?其次,重定向到stdin有什么好的用途吗?

2 个答案:

答案 0 :(得分:9)

更准确地说,>&0做的是重复文件描述符0作为文件描述符1.如果程序的stdin只是打开读取,那么当程序尝试写入stdout(文件描述符1)时,它会出错,因为文件描述符1也只能打开阅读。

您可以通过编写一个检查自己的文件描述符的小shell脚本来证明这一点:

10156115.sh:

#!/bin/bash
bash -c 'ls -l /proc/$$/fd' >&0

然后用可识别的stdin,stdout和stderr调用它:

$ touch stdin
$ ./10156115.sh < stdin > stdout 2> stderr

结果是您在stderr中获得了以下内容:

ls: write error: Bad file descriptor

但是,默认情况下,所有三个都是终端:(简化输出)

$ ls -l /proc/$$/fd
lrwx------ 0 -> /dev/pts/14
lrwx------ 1 -> /dev/pts/14
lrwx------ 2 -> /dev/pts/14
lrwx------ 255 -> /dev/pts/14

通常情况下,所有三个实际上都是开放式读取和写入,因此如果单独使用普通shell,>&0重定向根本不起作用。


这有什么用途吗?

没有任何常见的用途,但如果您调用脚本重定向stdoutstderr,则可以将其用作脏黑客来获取打印到终端的方法,并且无论出于何种原因你都无法改变:

if [ ! -t /dev/fd/1 -a ! -t /dev/fd/2 -a -t /dev/fd/0 ]; then
    echo "My message that I really, really want to go to a terminal" >&0
fi

但我不建议实际这样做。

答案 1 :(得分:5)

由于历史原因,终端上的标准文件描述符是开放式读/写而不是只读(具体来说,它打开一次,dup()编辑给其他人。对于想要接受管道输入但同时读取用户输入的程序(来自stdout,或更常见的stderr),这偶尔会有用,尽管在这种情况下使用/dev/tty更可靠。有些系统不仅仅将这个应用于ttys:* BSD双向打开套接字对(“管道”),而一些系统实用程序(我记得ufsdump就是一个例子)依赖于此。

重定向到 stdin(也就是说,仅将其打开以进行写入)通常不会有用,因为大多数程序都希望它可以打开以进行读取(或者有时是读/写,如上所述。)