在 zsh 中移动文件描述符

在 zsh 中移动文件描述符

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

首先我们建立一个临时文件夹

$ mkdir /tmp/foo
$ cd /tmp/foo
$ touch a
$ touch b

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

$ 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)

ksh行为类似

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

$ ksh --version
version         sh (AT&T Research) 93u+ 2012-08-01

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

$ dash -c 'ls 3>&2 2>&1 1>&3-'

破折号: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)

zsh执行底层复制和关闭的顺序是否与和bash不同ksh?该功能的实现过程中是否存在错误?

答案1

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

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

bash为了在任何 POSIX shell 中实现与和相同的移动文件描述符行为ksh

sh -c 'ls 3>&2 2>&1 3>&1 3>&-'

这就是and1>&3-内部所做的事情,将文件描述符 3 复制到文件描述符 1,然后关闭文件描述符 3。bashksh

相关内容