les*_*ana 4 bash io-redirection dash command-substitution
以下命令在 dash 中有效,但在 bash 中失败并显示“错误的文件描述符”。
$ dash -c 'out=$(echo "to fd3" >&3; echo "to stdout") 3>&1; echo "out: $out"'
to fd3
out: to stdout
$ bash -c 'out=$(echo "to fd3" >&3; echo "to stdout") 3>&1; echo "out: $out"'
bash: 3: Bad file descriptor
out: to stdout
Run Code Online (Sandbox Code Playgroud)
当我用子外壳替换命令替换时,它似乎可以在 dash 和 bash 中工作。
$ dash -c '(echo "to fd3" >&3; echo "to stdout") 3>&1'
to fd3
to stdout
$ bash -c '(echo "to fd3" >&3; echo "to stdout") 3>&1'
to fd3
to stdout
Run Code Online (Sandbox Code Playgroud)
版本:
$ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-unknown-linux-gnu)
Run Code Online (Sandbox Code Playgroud)
不知道如何获得破折号版本。我系统上的手册页日期为 2003 年 1 月 19 日。
研究:
我查找了 bash 和 dash 如何执行命令。这就是我发现的。
对于 bash:https : //www.gnu.org/software/bash/manual/bashref.html#Shell-Operation
对于破折号:http : //man7.org/linux/man-pages/man1/dash.1.html(“简单命令”部分)
据我所知,两者都在重定向之前进行扩展。命令替换是一种扩展。所以在命令替换中没有设置文件描述符 3 是有道理的。
为什么它在破折号中工作?为什么它在 bash 中不起作用?这是破折号中的错误吗?还是重击?它是一个有效的构造吗?
当没有 command 时,POSIX 未指定是在赋值扩展之前还是之后执行重定向,因此两者都是有效的,您不能依赖其中任何一个。所以便携,你需要:
{ out=$(echo "to fd3" >&3; echo "to stdout"); } 3>&1
Run Code Online (Sandbox Code Playgroud)
AT&Tksh和 Bourne shell 的行为类似于bash; zsh, pdksh,在这种情况下yash表现得像dash。