在 zsh 中移动文件描述符

Gre*_*bet 3 zsh file-descriptors

ls 3>&2 2>&1 1>&3-in的构造zshksh/bash或更受限制的 shell 的行为方式不一致,例如dash根本不支持移动文件描述符。它不会在标准错误时发出目录内容或抱怨无效的文件描述符编号,它不会打印任何内容。移动文件描述符是什么意思/做zsh什么?到目前为止,我只在 OS X 上测试了各种 shell(使用通过自制软件安装的最新版本)。

首先我们设置一个临时文件夹

$ mkdir /tmp/foo
$ cd /tmp/foo
$ touch a
$ touch b
Run Code Online (Sandbox Code Playgroud)

然后我们ls 3>&2 2>&1 1>&3-使用bashand运行ksh,它们都支持移动文件描述符。

$ bash -c 'ls 3>&2 2>&1 1>&3-'
a       b

$ bash --version | head -n 1
GNU bash, version 4.4.5(1)-release (x86_64-apple-darwin15.6.0)
Run Code Online (Sandbox Code Playgroud)

ksh 行为相似

$ ksh -c 'ls 3>&2 2>&1 1>&3-'
a       b

$ ksh --version
version         sh (AT&T Research) 93u+ 2012-08-01
Run Code Online (Sandbox Code Playgroud)

dash是一个不支持此语法的 shell 示例。它解释1>&3-为格式错误的重复。

$ dash -c 'ls 3>&2 2>&1 1>&3-'
Run Code Online (Sandbox Code Playgroud)

破折号:1:语法错误:错误的 fd 编号

zsh,奇怪的是,什么都不打印。

$ echo -n '<'; zsh -c 'ls 3>&2 2>&1 1>&3-'; echo '>'
<>

$  zsh --version
zsh 5.2 (x86_64-apple-darwin15.4.0)
Run Code Online (Sandbox Code Playgroud)

是否zsh以与bash和不同的顺序执行基础重复和关闭ksh?它在实现此功能时是否存在错误?

cuo*_*glm 5

zsh不支持移动文件描述符语法,如bashksh。所以1>&3-意味着将标准输出和标准错误都重定向到名为 的文件3-

$ echo -n '<'; zsh -c 'ls 3>&2 2>&1 1>&3-'; echo '>'
<>
$ ls
3- a b
Run Code Online (Sandbox Code Playgroud)

为了达到相同的移动文件描述符的行为像bashksh在任何POSIX外壳:

sh -c 'ls 3>&2 2>&1 3>&1 3>&-'
Run Code Online (Sandbox Code Playgroud)

这就是1>&3-bashksh内部确实,复制文件描述符3到文件描述符1然后关闭文件描述符3。