次のコマンドはダッシュで機能しますが、「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で動作しないのですか?ダッシュのバグですか?またはバッシュ?それはまったく有効な構成ですか?
リダイレクトが割り当て展開の前または後に実行されるかどうかは コマンドがない場合はPOSIXで指定されていない なので、どちらも有効であり、どちらにも依存できません。したがって、移植性が必要です:
{ out=$(echo "to fd3" >&3; echo "to stdout"); } 3>&1
AT&T ksh
とBourne Shellはbash
;のように動作します。 zsh
、pdksh
、yash
は、このインスタンスではdash
のように動作します。