exec n<&m vsexec n>&m -- 基于 Sobell 的 Linux 书籍



Mark Sobell的 Linux命令、编辑器和Shell编程实用指南,第二版他写道(p. 432):

& lt;和令牌复制输入文件描述符;祝辞,重复输出文件描述符。

这似乎与同一页上的另一个语句不一致:

使用以下格式打开或将文件描述符n重定向为a文件描述符m的副本:

exec n<和m>

和一个示例也在同一页上:

# File descriptor 3 duplicates standard input
# File descriptor 4 duplicates standard output
exec 3<&0 4<&1

如果祝辞,复制一个输出文件描述符那么我们不应该说

exec 4>&1

复制标准输出?

这个例子在实践中是正确的。这本书最初的解释是对POSIX标准的准确描述,但是我手边的类POSIX shell (bashdash,我相信在Linux上常见的两个shell)并没有那么挑剔。

POSIX标准与书中关于输入和输出描述符的规定相同,并继续说:对于n<&word,"如果word中的数字不代表已经为输入打开的文件描述符,将导致重定向错误"。所以如果你想要小心POSIX兼容性,你应该避免这种用法。

bash文档也对<&>&说了同样的话,但没有承诺会出现错误。这很好,因为它不会给出错误。相反,根据经验,n<&mn>&m似乎是可以互换的。<&>&之间的唯一区别是,如果您在左侧留下fd数字,<&默认为0 (stdin), >&默认为1 (stdout)。

例如,让我们启动一个shell,让fd 1指向文件bar,然后完全尝试exec 4<&1示例,尝试写入结果fd 4,看看它是否有效:

$ sh -c 'exec 4<&1; echo foo >&4' >bar; cat bar
foo

它可以,这适用于使用dashbash(或bash --posix)的shell。

在幕后,这是有意义的,因为<&和>,几乎可以肯定的是,我们只是在调用dup2(),它并不关心FDS是否为读、写、追加或其他什么而打开。

[EDIT:在评论中讨论后添加了对POSIX的引用]

如果stdout是tty,则可以安全地克隆它以进行读写。如果stdout是一个文件,那么它可能无法工作。我认为这个例子应该是4>&1。我同意Greg的观点,即既可以读也可以写克隆描述符,但是用<&请求重定向应该是用可读的源描述符完成的,而期望标准输出是可读的是没有意义的。(虽然我承认我没有这种说法的参考资料。)

一个例子可以使它更清楚。使用下面的脚本:

#!/bin/bash
exec 3<&0
exec 4<&1
read -p "Reading from fd 3: " <&3
echo From fd 3: $REPLY >&2
REPLY=
read -p "Reading from fd 4: " <&4
echo From fd 4: $REPLY >&2
echo To fd 3 >&3
echo To fd 4 >&4

我得到以下输出(在终端输入"Reading from"行上的:之后的内容):

$ ./5878384b.sh
Reading from fd 3: foo
From fd 3: foo
Reading from fd 4: bar
From fd 4: bar
To fd 3
To fd 4
$ ./5878384b.sh < /dev/null
From fd 3:
Reading from fd 4: foo
From fd 4: foo
./5878384b.sh: line 12: echo: write error: Bad file descriptor
To fd 4
$ ./5878384b.sh > /dev/null
Reading from fd 3: foo
From fd 3: foo
./5878384b.sh: line 9: read: read error: 0: Bad file descriptor
From fd 4:
To fd 3

注意文件描述符和IO流(如stderr和stdout)之间的区别。

重定向操作符只是通过不同的文件描述符(IO流处理机制)重定向IO流;它们不做任何IO流的拷贝或复制(这就是tee(1)的作用)。

参见:文件描述符101

另一个显示n<&m和n>&m可互换的测试是"使用'n<&-'或'n>&-'样式关闭文件描述符,即使它不匹配文件描述符打开时的读/写模式"(http://www.gnu.org/s/hello/manual/autoconf/File-Descriptors.html)。

相关内容

  • 没有找到相关文章

最新更新