“>&0”有用途吗(重定向到标准输入)?

问题描述 投票:0回答:3

在 bash 中你可以这样做:

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

当我执行最后一个操作时,我的终端仍然像其他两个一样打印

test
,但很难知道为什么。首先,为什么这会起作用?其次,重定向到 stdin 有什么好的用途吗?

bash unix
3个回答
10
投票

更准确地说,

>&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
重定向根本没有任何效果。


这个有什么用处吗?

这没有任何常见用途,但如果有人调用您的脚本重定向

stdout
stderr
,并且无论您出于什么原因,您都可以将其用作肮脏的黑客,以获取打印到终端的方法。无法改变这一点:

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

但我不建议实际这样做。


7
投票

由于历史原因,终端上的标准文件描述符是开放式读/写而不是只读(具体来说,它打开一次并

dup()
其他人)。这对于想要获取管道输入但也从用户读取输入(来自
stdout
,或更常见的是
stderr
)的程序有时很有用,尽管在这种情况下使用
/dev/tty
更可靠。有些系统不仅将其应用于 tty:*BSD 双向打开套接字对(“管道”),并且某些系统实用程序(我记得
ufsdump
是一个示例)依赖于此。

重定向 to

stdin
(即仅打开以进行写入)通常没有用,因为大多数程序希望它打开以进行读取(或有时是读/写,如上所述)。


0
投票

是的,

>&0
有一个很好的用途。如果我想将输入和输出重定向到同一设备(例如串行端口),我可以以读写模式打开 stdin 并将 stdout 重定向到它:

rz <>/dev/ttyUSB0 >&0

它不仅可以节省我的打字时间,而且如果我在脚本中执行此操作,我会让 shellcheck 满意。

© www.soinside.com 2019 - 2024. All rights reserved.