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

Ale*_*lis 4 unix linux bash shell file-descriptor

在Mark Sobell的"Linux命令,编辑器和Shell编程实用指南"第二版中,他写道(第432页):

<&token复制输入文件描述符; >&复制输出文件描述符.

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

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

exec n <&m

并在同一页面上也有一个例子:

# File descriptor 3 duplicates standard input
# File descriptor 4 duplicates standard output
exec 3<&0 4<&1
Run Code Online (Sandbox Code Playgroud)

如果> &&重复输出文件描述符,那么我们不应该说

exec 4>&1
Run Code Online (Sandbox Code Playgroud)

复制标准输出?

Gre*_*ice 8

这个例子在实践中是正确的.本书的原始解释是对POSIX标准所说内容的准确描述,但是我方便的POSIX类shell(bash而且dash,我认为只有Linux上常见的那些)并不那么挑剔.

POSIX标准关于输入和输出描述符的书的内容相同,并继续说:n<&word"如果数字word不表示文件描述符已经打开输入,则会产生重定向错误".因此,如果您想要小心POSIX兼容性,则应避免这种用法.

bash的文档也说同样的事情有关<&>&,但没有一个错误的诺言.哪个好,因为它实际上没有给出错误.相反,经验n<&mn>&m似乎是可以互换的.<&和之间唯一的区别>&是,如果你不在左边的fd编号,<&默认为0(stdin)和>&1(stdout).

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

$ sh -c 'exec 4<&1; echo foo >&4' >bar; cat bar
foo
Run Code Online (Sandbox Code Playgroud)

它确实如此,并且使用dash或者bash(或bash --posix)使用shell.

在引擎盖下,这是有道理的,因为<&和>&几乎肯定只是调用dup2(),它不关心fds是否为读取或写入或追加或什么打开.

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