ExpansionとSubstitutionは、シェルプログラミング言語の同じコンテキストで交換可能のようです。たとえば、 Bashリファレンスマニュアル 、 Bash Hackers Wiki などの一部のドキュメントでは、 'expansion'という単語を使用して 'シェルパラメータexpansion '。ただし、他のいくつかのドキュメントでは、「置換」という単語を好むようです。 Advanced Bash-Scripting Guide パラメーターsubstituionを使用します。
シェルプログラミングの用語に関して、「拡張」と「置換」の間に違いはありますか?
Substitutionは、意味が重複しているため、このコンテキストではexpansionとほぼ同義です。 GNU Manual セクションでは、全体的な拡張の一部と見なされる置換がありますが、どちらももう一方の完全なサブカテゴリではありません。
expansionは識別子の値を抽出しています。たとえば、_this=that
_の場合、this
を展開すると、that
が得られます。置換を伴わない拡張は、使用される値がすでに存在し、単に取得する必要があるという点で事前に決定されています。算術展開」)。
substitutionは、明示的な入出力操作の結果として値を作成します。たとえば、this=$(foo bar)
の場合、this
は_foo bar
_を実行し、その出力をキャプチャした結果です。1 置換の結果の値は完全に予測可能かもしれませんが、置換が行われるまで実際には存在しないため、通常の展開で取得される値とは異なります-生成されます。
置換には、commandとprocessの2つのフレーバーがあり、これらは一種の対称的です。
_# Command substitution
foo=$(ls)
# Process substitution
wc <(ls)
_
最初の「コマンド」はls
であり、2番目の「プロセス」も同様です。置き換えられているのは、実際にはパイプの終わりであると言えます。プロセス置換はリダイレクトと重複しています。ただし、これはおそらく技術的には少し制限が多すぎるため、脚注に移動します...
foo bar
_は、内部シェル関数である可能性があります。この場合、プロセス間IOはありません。 Shellビルトインの存在は、この違いをあまり明確に覆い隠しません。コンテンツに関しては、入力と出力は同じになります。set -- arg arg2
echo ${2+"$1"}
#OUTPUT
arg
shift
echo ${2+"$1"}
#OUTPUT
#there doesn't seem to be anything here
違いは一般的に小さすぎて注目に値しないと思います-そしてこれらの用語はしばしば同じ意味で使用されます。ただし、上記の2つのケースを見ると、最初の例では、substitute$1
for $2
であることがわかります。 $2
の展開の結果として。 $2
を展開できないとすぐに、置換はありません。
goldilocksは、Etherealの置換の存在について良い点を示しています。シュレディンガーの猫のようなものだと思います。それは私に何かを思い出させた。この形式のPOSIX指定のパラメーター展開に慣れていない場合もありますが、上記の形式とは逆の方法で機能します。
${var:?if $var is unset or null its \
parent Shell dies and this message is output to stderr}
今度は同じ動作が必要ですが、set
値が必要です。 POSIXは、その動作を正確に指定していません。しかし、1つか2つのトリックで、それは簡単に管理されます。
N= #N is null
var="any value should fail"
${var:+${N:?we substitute our \$Null var when \$var is expanded}}
#OUTPUT
sh: line 3: N: we substitute our $Null var when $var is expanded
だが:
N= #N is null
var=
${var:+${N:?is never substituted}}
#OUTPUT
#there doesn't seem to be anything here