リダイレクト後、$ 拡張は期待どおりに実行されません。

リダイレクト後、$ 拡張は期待どおりに実行されません。

子プロセスで変数と算術拡張を実行するようですbashzsh

a)、または同じリダイレクト演算子に従います<>>><<<

b) それらが属する命令は、組み込みの命令や機能ではない。

bash -c 'i=0; /bin/echo > $((i=7)).txt; echo $i'
0
zsh -c 'i=0; /bin/echo > $((i=7)).txt; echo $i'
0

ksh -c 'i=0; /bin/echo > $((i=7)).txt; echo $i'
7

kshbash上記は、or以外のシェルと同じですzsh

これは算術拡張とは何の関係もありません。同様に、同じことが起こります。

unset i; /bin/echo >${i:=7}.txt; echo $i

または7以外のシェルでのみ印刷されます。bashzsh

bashしかし、それが十分に悪くないように、そして間の動作は理解できる方法で一貫性がありませんzsh

bash -c 'i=0; command echo > $((i++)).txt; echo $i'
1
zsh -c 'i=0; command echo > $((i++)).txt; echo $i'
0

bash -c 'i=0; i=$i /usr/bin/printenv i > $((++i)).bash; echo $i; cat *.bash'
0
0
zsh -c 'i=0; i=$i /usr/bin/printenv i > $((++i)).zsh; echo $i; cat *.zsh'
0
1

だから私の質問は次のとおりです。標準は何を言いますか?これは許されますか?

KEY=val cmd変数の割り当てに関する「現在の実行環境に影響を与える可能性があるかどうか」など、多くの情報が見つかりましたが、$リダイレクト、拡張、および外部コマンド間の相互作用については見つかりませんでした。

また、-expansionsの一部として実行された変数の割り当てにも適用される可能性はほとんどありません。なぜなら、$外部か組み込みかどうかにかかわらず、ls $((i=2+3))すべてのシェルでにi設定されるからです。5ls

ベストアンサー1

これは指定されていないため、各シェルは詳細を記録せずに必要な操作を実行できます。 (歴史的な観点からは、他のシェルは異なることをするため指定されていません。)技術的に、シェルはコインを投げることができます。実際には、別の環境で実行されているものと実行されていないものの詳細は、場合によっては実行される最適化によって異なります。コマンドが組み込まれているかどうかによって、リダイレクトがto / fromかどうか/dev/nullによって異なります。set -e有効かどうか、コマンドがリストの最後のコマンドであるかどうかに応じてトラップがアクティブになります。

~からSUSv4(POSIX.1-2008) 「シェルとユーティリティ」 - §2.9.1「簡単なコマンド」:

コマンド名が特殊な組み込みユーティリティまたは関数でない場合は、コマンド実行環境に変数割り当てをエクスポートする必要があり、手順4で実行された拡張の副作用を除いて、現在の実行環境に影響を与えないでください。この場合、指定されていません。

  • ステップ4の後続の拡張に割り当てが表示されますか?

  • これらの拡張の副作用として実行された変数の割り当ては、ステップ4の後続の拡張、または現在のシェル実行環境、またはその両方で確認できます。

明確に言えば、「ステップ4」には、パラメータ拡張(例:)${i:=7}と算術拡張(例$((i=7)):)が含まれます。 「現在の実行環境に影響を与えてはいけない」変数の拡張は、コマンドの前にあるものですi=7 ls。したがって、とりわけ、この段落では、パラメータ拡張または変数拡張が変数値を変更する場合、コマンドが返された後にこれが影響を与えるかどうかは指定されていないと述べています。

実際、シェルは通常、サブシェルからリダイレクトを分岐して実行し、外部コマンドにリダイレクトを適用します。ただし、サブシェルを作成する前または後にリダイレクトをターゲットにするかどうかは異なります。

おすすめ記事