リダイレクトを使用した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

コマンド置換をサブシェルに置き換えると、ダッシュと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がコマンドを実行する方法を確認しました。これが私が見つけたものです。

バッシュの場合:https://www.gnu.org/software/bash/manual/bashref.html#Shell-Operation

ダッシュの場合:http://man7.org/linux/man-pages/man1/dash.1.html(「簡単なコマンド」セクション)

私が理解しているように、両方ともリダイレクトする前に拡張されます。コマンドの置換は拡張です。したがって、ファイルディスクリプタ3がコマンド置換に設定されていないのは妥当です。

ダッシュで動作するのはなぜですか?なぜbashでは動作しないのですか?これはダッシュバグですか?それともバッシュ?それはまったく有効な構造ですか?

ベストアンサー1

割り当て拡張の前後にリダイレクトが実行されるかどうかコマンドがなければ、POSIXは指定されません。したがって、どちらも有効であり、どちらにも依存することはできません。したがって、移植性のためには以下が必要です。

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

AT&Tkshおよび Bourne シェルはこの例と同様に動作しますbashzshpdkshyashdash

おすすめ記事