Bash

帶有重定向的bash命令替換:錯誤的文件描述符

  • October 5, 2017

以下命令在破折號中有效,但在 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

當我用 subshel​​l 替換命令替換時,它似乎在 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&Tksh和 Bourne shell 的行為類似於bashzsh, pdksh,在這種情況下的yash行為。dash

引用自:https://unix.stackexchange.com/questions/396250