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-
和bash
,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)
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
不支持移动文件描述符语法,如bash
或ksh
。因此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。bash
ksh