コマンド置換サブシェルの bash 変数の可視性

コマンド置換サブシェルの bash 変数の可視性

Linuxシェルスクリプトブックを読んで、次の警告が見つかりました。

「コマンド置換は、組み込みコマンドを実行するためのサブシェルであることを生成します。サブシェルは、スクリプトを実行するシェルによって生成された別のサブシェルです。したがって、スクリプトによって生成されたすべての変数はサブシェルコマンドには使用できません」

現在、bashシェルのCLIから変数を作成し、サブシェルに移動して画面に印刷できることを確認しました。はい、できません。上記の引用に基づいているようです。しかし、コマンドの置き換えで次のスクリプトを実行しました。

#!/bin/bash
var=5.5555
ans=$(echo $var)
echo $ans

結果:

5.5555

私が理解したのは、サブシェルが「見る」ことができないため、varの値を印刷してはいけません。なぜこれが起こるのですか?

答え1

声明:

したがって、スクリプトによって生成されたすべての変数はsubshel​​lコマンドでは使用できません。

偽です。親シェルで定義されている変数の範囲は、スクリプト全体(コマンド置換によって生成されたサブシェルを含む)です。

ランニング:

#!/bin/bash
var=5.5555
ans1=$(echo $var)
ans2=$(var=6; echo $var)
echo $ans1
echo $ans2

結果は次のとおりです。

5.5555
6

$varサブシェルで解決済み:

  • ローカル変数を指定しない場合、3 つのグローバル変数の値が使用されます。
  • ローカル変数が指定された場合は、その値を使用します。

また見てください例21-2

答え2

引用された主張は事実ではありません。サブシェルが実行される前に変数が事前置換されていることも正しくありません。

以下を使用して直接確認できます。可変間接:

$ x=hello
$ echo Result is $(y=x ; echo ${!y} ; echo world)
Result is hello world

変数は変数から読み取られるxので(以前は値を拡張せずに)サブシェルで直接使用できます。${!y}名前保管場所y- サブシェルの作成時には存在しません。


本のこの詩の良い解釈は、「変数」の値を永久に変更できないため、使用できないことを意味します。新しい変数(たとえばy)を作成するか、既存の変数に代替値を割り当てるかにかかわらず、サブシェルによって実行されたすべての変数の割り当ては、後で親シェルで使用することはできません。サブシェルがに割り当てられている場合、x新しい値はサブシェル内で適用されますが、後でその値を読み取ると元の値が提供されます。

$ x=world
$ echo $(x=hello ; echo $x)
hello
$ echo $x
world

少なくともあなたが引用した詩では、そう言う方法はあまり明確ではありません。本全体がこのような場合は、より良い本を見つけることができます(またはここで質問を読んでください)。

関連情報