次のコマンドはダッシュで機能しますが、「無効なファイル記述子」のため、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 シェルはこの例と同様に動作しますbash
。zsh
pdksh
yash
dash