bash script
というファイルがありますVAR_A
私も地元env variable
の名前があります。VAR_A
呼び出しbash script
コマンド:
echo ${VAR_A}
スクリプトの変数を別の名前に変更することはできませんが、スクリプトがコマンドを呼び出す方法は変更できますecho
。
スクリプトに提供されているコマンドの代わりにecho
ローカルコマンドを印刷するようにコマンドを変更するにはどうすればよいですか?env variable
UPDATE FOR CLARITY:
状態:
ユーザーに.bashrc
ログイン時に設定された既存のファイルがあります。
VAR_A="someValue"
export VAR_A
これにより、ユーザーは次のことができます。
~]$ echo ${VAR_A}
someValue
Bashスクリプト用のいくつかの設定ファイルがあります
VAR_A="someOtherValue"
Bashスクリプトがあります。
#!/bin/bash
. ../configuration # imports config file with some values
# do stuff
echo ${VAR_A}
端末(ログインしたユーザーとしてbashシェル)でスクリプトを実行すると、次のものが印刷されます。
~]$ ./run_script.sh
someOtherStuff
印刷するには、次のものが必要です。
~]$ ./run_script.sh
someStuff
答え1
シェル変数は各シェルの環境変数で初期化されるため、この問題を解決することはできません。
シェルが起動すると、有効な名前のシェル変数として受け取られる各環境変数に対して、シェルはそのシェル変数に適切な値を指定します。たとえば、スクリプトが次のように起動した場合:
env VAR_A=xxx your-script
(そしてshe-bangがあります#!/bin/bash -
)がenv
実行され、対応するbashコマンドに/bin/bash
渡され、その変数に値が割り当てられます。VAR_A=xxx
bash
$VAR_A
xxx
Bourne シェルと C シェルでシェル変数に新しい値を割り当てても、後でシェルで実行されるコマンドに渡される環境変数には影響しません。これを達成するには、export
またはを使用する必要があります。setenv
Bourne シェルでは、unset
変数を使用するとシェル変数と環境変数が削除されます。
存在する:
env VAR=xxx sh -c 'VAR=yyy; other-command'
(sh
現代のPOSIXシェルではなくBourneシェル)または:
env VAR=xxx csh -c 'set VAR = yyy; other-command'
other-command
VAR=xxx
その環境でこれを受け取るには、代わりにVAR=yyy
次のように書く必要があります。
env VAR=xxx sh -c 'VAR=yyy; export VAR; other-command'
または
env VAR=yyy csh -c 'setenv VAR yyy; other-command'
その環境で受信されますother-command
。VAR=yyy
しかし、(POSIXと他のすべての現代のBourne様シェルが明らかになったksh
ように)、この問題が発生しました。bash
起動時に最新のシェル製本その環境変数にシェル変数を追加します。
これは、変数をエクスポートしなくても、スクリプトが変数の1つを設定するだけで環境を破壊する可能性があることを意味します。一部のシェルは、シェル変数にマップできない環境変数も削除します。したがって、シェルマッピング可能変数名のみを環境変数名として使用することをお勧めします。
これが慣例に従って、すべての大文字変数が環境変数用に予約されなければならない主な理由です。
この問題を解決するには、スクリプトによって実行されるコマンドがスクリプトを解釈するシェルと同じ環境を受け取るようにするには、何らかの方法でその環境を保存する必要があります。以下を追加するだけです。
my_saved_env=$(export -p)
スクリプトの先頭に次のコマンドを実行します。
(eval "$my_saved_env"; exec my-other-command and its args)
シェルbosh
とmksh
シェル、地元の関数の変数は環境変数を破壊しません(環境変数を破壊しない限り)。ただし、一部の特殊変数(たとえば、実行可能な照会のためのfor、...)をexport
使用するシェル組み込み機能は、次のものを使用します。HOME
cd
PATH
シェル(ローカル)変数、環境変数ではありません。
$ env VAR=env mksh -c 'f() { local VAR=local; echo "$VAR"; printenv VAR; }; f'
local
env
答え2
VAR_A
次の行を追加して変数を読み取り専用にすることができます。
readonly VAR_A
スクリプトの上部にあります。これにより、VAR_A
次の値が発生します。予約する地域環境によって異なります。
readonly: readonly [-aAf] [name[=value] ...] or readonly -p
Mark shell variables as unchangeable. Mark each NAME as read-only; the values of these NAMEs may not be changed by subsequent assignment. If VALUE is supplied, assign VALUE before marking as read-only. Options: -a refer to indexed array variables -A refer to associative array variables -f refer to shell functions -p display a list of all readonly variables and functions An argument of `--' disables further option processing. Exit Status: Returns success unless an invalid option is given or NAME is invalid.
次の例を見ると明確になります。
$ export FOO="somevalue" # environment variable FOO set to somevalue
$ cat test # test script
echo $FOO # print the value of FOO
readonly FOO # set FOO to local
FOO="something" # attempt to modify FOO
echo $FOO # print the value of FOO -- you would see the value that was inherited from the environment
$ bash test
somevalue
test: line 3: FOO: readonly variable
something
答え3
印刷したい場合地元のVariableはVAR_A
ローカルスコープで呼び出す必要があります。それ以外の場合は、グローバル変数の値を印刷しますVAR_A
。
#! /bin/bash
VAR_A="I'm global"
function lexical() {
local VAR_A="I'm lexical"
echo $VAR_A
}
echo -n "Global VAR_A: "
echo $VAR_A
echo -n "Lexical VAR_A: "
lexical
走る:
$ ./test.sh
Global VAR_A: I'm global
Lexical VAR_A: I'm lexical
local
次のページでbashの詳細を読むことができますman
。
local [option] [name[=value] ...]
For each argument, a local variable named name is created, and
assigned value. The option can be any of the options accepted
by declare. When local is used within a function, it causes the
variable name to have a visible scope restricted to that func‐
tion and its children. With no operands, local writes a list of
local variables to the standard output. It is an error to use
local when not within a function. The return status is 0 unless
local is used outside a function, an invalid name is supplied,
or name is a readonly variable.
答え4
VAR_A
何が起こっているのか設定ファイルVAR_A
が.bashrc
。
したがって、回避策自体は次のようになります。設定ファイルをインポートする前に、VAR_A
次のように内容を保存してください。
VAR_A_sav=${VAR_A} # assuming that VAR_A_sav does NOT exist in configuration
. ../configuration # that is, you must choose a name not existing in config.
VAR_A=${VAR_A_sav}