私の問題は、スクリプトの作成を開始したときに複数の変数スコープの問題に遭遇し、ほとんどすべての変数をエクスポートする悪い習慣が生じたことです。
今私のコードはかなり大きくなってきたので、クリーンアップを検討しています。残念ながら、変数の範囲の理解は完全ではありません。トピックについて数ページを読んだ後も同様です。
私が知っていること(正しいことを願っています):
1-変数をエクスポートして、サブシェルプロセスでその内容を使用できるようにします。
export myvar="content"
2 - このように括弧内で行われた操作は、エクスポートを削除すると影響を受けます(私の知る限り、これはサブシェルを宣言/使用する唯一の方法です)。
$(grep "content" <<< $myvar)
3 - 範囲を設定せずに宣言された変数はグローバル変数です。
myvar="content"
4-ローカル変数を宣言していないので、関数に問題が発生するかどうか心配する必要はありません。
local myvar="i don't use this"
質問:
1 - 私のコードが明確な初心者の雰囲気を出さないという事実を除いて、役に立たないエクスポートを削除し続けるのに意味がありますか?
2-これを続けると、影響を受けてコードが破損する可能性があることを知っておくべき他のことはありますか?それとも私の知識が間違っているか不完全ですか?
3-よく書かれた(そして完全な)変数範囲参照がわかっている場合は、リンクを共有してください。
ベストアンサー1
二重評価を使用しない限り、エクスポートされたexport
変数に影響を与えずにすべてのエクスポートを削除できます。 2つの評価とは、次のことを意味します。
var1=var2
export "${var1}=var3"
echo "$var2"
var3
代わりに、以下を使用してください。
set -a
...スクリプトの上部にあります。後で定義されるすべての変数は自動的に適用されます。これには、以前編集していなかった変数もexported
含まれます。export
または、set -a
スクリプトの一部を使用してset +a
設定を解除することもできます。これは関数としても機能します。
ただし、サブシェルはとにかく変数の値を自動的に継承するため、次のようになります。
var1=value
( echo "$(echo "$var1")" )
value
export
この場合、違いはありません。
ただし、スクリプトが編集した値を解釈する別のスクリプトまたは別の実行可能ファイルを呼び出してその呼び出しを停止すると、そのexport
環境export
でその値を使用できなくなります。次の例は、$PS1
対話型シェルプロンプトの内容を定義するシェル変数を使用して、export
ed変数に対する変更が子プロセスにどのように影響するかを示しています。
export PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i
###OUTPUT###
this is another executable
> exit
exit
しかし...
PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i
###OUTPUT###
sh-4.3$ exit
exit
しかし、プロセスを呼び出すときに明示的に環境変数を宣言すると...
PS1="$(printf "this is another executable\n > ")"
{
echo exit | PS1=$PS1 sh -i
echo exit | sh -i
}
###OUTPUT###
this is another executable
> exit
exit
sh-4.3$ exit
exit