パラメータ拡張

パラメータ拡張

私はパラメータ拡張で遊んだ。以下は私のコードです。

a="one"
sh -c 'echo $a'

b="two"
sh -c "echo $b"

c="three" sh -c 'echo $c'
echo $c

このスクリプトを実行したときの出力は次のとおりです。

$sh test.sh

two
three

$

$aの場合、一重引用符は置換を抑制します。ちょうどecho $aを出力してはいけませんか?新しい行を印刷していますが、これは$aの値が空であることを意味しますか? $c の場合、「echo $c」は機能せず、新しい行は印刷されませんが、次の行の echo $c は期待どおりに動作します。これがどのように機能するのか少し混乱しています。

答え1

sh -c 'echo $a'これは、新しいシェルを開いてecho $a入力するのと同じです。子シェルには変数がないためa(親シェルで変数を設定していないexport)、空白行が印刷されます。

そして

b="two"
sh -c "echo $b"

"echo $b"文字列は現在のシェルによって拡張され、拡張された値はパラメータ文字列としてサブシェルに渡されます。まるで新しいシェルを開きますecho two

var=val command一時的に設定してexportsをvar=val呼び出すだけですcommand

c="three" sh -c 'echo $c'

ほとんど(サブシェルは実際には存在しません)

( export c="three"; sh -c 'echo $c' )

親シェルのc変数は影響を受けません。

答え2

子プロセスの変数を表示するには、そのexport変数を確認する必要があります。このように:

   $ export a=7
   $ sh -c 'echo $a'
   7

あなたの場合、子プロセス(aおよびb)は親シェルの変数を見ることができません。

一重引用符を使用して文字列を生成すると、どの置換も機能しません。変数やそのようなものは置き換えることはできません\n。それはまさにまたは$aになります\n。したがって、最初のケースの文字列はまさに「echo $a」です。sh -c 'echo $a'作る新しいプロセスであり、プロセスには親プロセスがなく、空の文字列である$a独自のuninitializedがあります。$aそれはただ実行されます'echo $a'

2番目のケースでは二重引用符を使用します。置換が機能し、文字列は次のようになります。"echo two" 今後子プロセスを実行します。だから、それは単なる実行ですsh -c 'echo two'

3番目のケースでは、エクスポートされた$c変数になります。これは、「このコマンドに対してのみ変数をエクスポート」を意味する特殊な構文です。したがって、正しく実行すると、新しいシェルが環境変数としてsh -c 'echo $c'含まれます。またはシェルを起動したときと$c同じです。$PATH$HOME

関連情報