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

She*_*hep 11 unix bash

在bash中你可以这样做:

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

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

je4*_*e4d 9

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

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

10156115.sh:

#!/bin/bash
bash -c 'ls -l /proc/$$/fd' >&0
Run Code Online (Sandbox Code Playgroud)

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

$ touch stdin
$ ./10156115.sh < stdin > stdout 2> stderr
Run Code Online (Sandbox Code Playgroud)

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

ls: write error: Bad file descriptor
Run Code Online (Sandbox Code Playgroud)

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

$ ls -l /proc/$$/fd
lrwx------ 0 -> /dev/pts/14
lrwx------ 1 -> /dev/pts/14
lrwx------ 2 -> /dev/pts/14
lrwx------ 255 -> /dev/pts/14
Run Code Online (Sandbox Code Playgroud)

通常,所有三个实际上都是开放读取和写入,因此>&0如果单独使用普通shell ,重定向根本没有任何影响.


这有什么用途吗?

有没有这样任何共同的用途,但如果任何人调用脚本重定向你可以使用它作为一个肮脏的黑客获得的方式打印到终端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
Run Code Online (Sandbox Code Playgroud)

但我不建议实际这样做.


gee*_*aur 5

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

重定向 stdin(即,仅将其打开以进行写入)通常不是很有用,因为大多数程序期望它可以打开以进行读取(或者有时读/写,如上所述).