私はパラメータ拡張で遊んだ。以下は私のコードです。
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
一時的に設定してexport
sを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