web-dev-qa-db-ja.com

リダイレクトを伴うbashコマンドの置換:不正なファイル記述子

次のコマンドはダッシュで機能しますが、「Bad file descriptor」で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

コマンドsubstitionをサブシェルに置き換えると、ダッシュとバッシュで動作するようです。

$ 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で動作しないのですか?ダッシュのバグですか?またはバッシュ?それはまったく有効な構成ですか?

3
lesmana

リダイレクトが割り当て展開の前または後に実行されるかどうかは コマンドがない場合はPOSIXで指定されていない なので、どちらも有効であり、どちらにも依存できません。したがって、移植性が必要です:

{ out=$(echo "to fd3" >&3; echo "to stdout"); } 3>&1

AT&T kshとBourne Shellはbash;のように動作します。 zshpdkshyashは、このインスタンスではdashのように動作します。

5