Bash
帶有重定向的bash命令替換:錯誤的文件描述符
以下命令在破折號中有效,但在 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
當我用 subshell 替換命令替換時,它似乎在 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
版本:
$ bash --version GNU bash, version 4.4.12(1)-release (x86_64-unknown-linux-gnu)
不知道如何獲得破折號版本。我係統上的手冊頁日期為 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
AT&T
ksh
和 Bourne shell 的行為類似於bash
;zsh
,pdksh
,在這種情況下的yash
行為。dash