2つのbashスクリプトがあるとしましょう。
プロバイダ.sh、いくつかのプロセスを実行して「露出」する必要がありますMAP
が、A
次のいずれも実行しないでくださいB
。
#!/bin/bash
declare -A MAP
A=hello
B=world
MAP[hello]=world
消費者.sh、実行され、Provider.sh
の使用が必要ですMAP
。
#!/bin/bash
source ./Provider.sh
echo ${MAP[hello]} # >>> world
環境を最大限に整理するために、Provider.sh
可視性をできるだけ低くしたいと思いましたConsumer.sh
。 MAPだけを「ソース」にするにはどうすればよいですか?
答え1
関数を使用して変数の範囲を決定できます。例:
## Provider.sh
# Global vars
declare -A map
# Wrap the rest of Provider.sh in a function
provider() {
# Local vars only available in this function
declare a=hello b=world c d
# Global vars are available
map[hello]=world
}
provider "$@" # Execute function, pass on any positional parameters
# Remove function
unset -f provider
$ cat Consumer.sh
. ./Provider.sh
echo "${map[hello]}"
echo "$a"
$ bash -x Consumer.sh
+ . ./Provider.sh
++ declare -A map
++ provider
++ declare a=hello b=world c d
++ map[hello]=world
++ unset -f provider
+ echo world
world
+ echo ''
答え2
関数を使用し、変数をローカルまたはグローバルにすることができます。
#!/bin/bash
foo() {
declare -gA MAP # make global
local A=hello # make local
local B=world # make local
MAP[hello]=world
}
foo
それから:
#!/bin/bash
source ./Provider.sh
[[ -z "$A" ]] && echo "Variable A not defined"
[[ -z "$B" ]] && echo "Variable B not defined"
echo ${MAP[hello]}
出力:
Variable A not defined
Variable B not defined
world
答え3
私はシェルスクリプトの一部だけを得る方法がないと思います。すべてを取得するか、何も取得しないように選択できます。
ただし、grep
ファイルから目的の行だけを抽出して新しいファイルに書き込んでから、その新しいファイルをインポートすることができます。もちろん、コードに複雑な機能があると、この方法は機能しません。
とにかく、このコードを複数のスクリプトに分割して必要なものだけを取得することをお勧めします。 1つのスクリプトしか使用しない場合は、コードを複数の関数に配置し、複数の場所からコードを取得して必要な関数のみを呼び出すこともできます。
答え4
2つのファイルがあると仮定すると、source
コマンドラインに両方のコマンドを提供し、プロバイダが消費者が後で使用できるように変数を設定したいとします。 (ああ、消費者が生産者をソースにすることがわかりました。したがって、彼らは同じ名前空間を共有し、消費者は呼び出す名前空間を汚染しません。
いくつかのbash_aliasesと.bashrc
。
機能するためにインポートする必要があるbashファイルがある場合は、そのファイルに通知を追加しますshebang
。
#!/bin/echo "You have to source this file (${BASH_SOURCE}), not run it"
# -*-mode:sh;sh-shell:bash;fill-column:84-*-
/bin/bash/bin/echo
ではなく/bin/bashが使用されるため、実行時に最初の行のみが表示されます。
${BASH_SOURCE}
ユーザーにファイルの場所を尋ねるメッセージも表示されます。
2行目は、# -*-mode:sh;sh-shell:bash;fill-column:84-*-
Emacsにファイルの編集中にファイルを強調表示してインデントする方法を理解するように指示します。
guestが提供する2つの機能は素晴らしいですが、別のファイルに入れておくだけでファイルを実行すると、この機能は有効になりません。
だからここに訪問者のコードをもたらしましたが、あなたが欲しいと思うものを達成するために少し変更しました。また、取得したいファイルに入れておくのが条件です。
#!/bin/echo "You have to source this file (${BASH_SOURCE}), not run it"
# -*-mode:sh;sh-shell:bash;fill-column:84-*-
# define producer and consumer functions
declare -A MAP # you might want to use a different name
# because this is going to be in your global namespace
function provider() {
local A=hello
local B=world
MAP[hello]=world
}
## However maybe what you are wanting is a setter function instead?
function providerSetter() {
MAP[${1}] = ${2}
}
function consumer()
echo ${MAP[hello]}
}
## Again, you might want a getter function
function consumerGetter()
echo ${MAP[${1}]}
}
## you can put defaults into the second functions, i.e.,
function providerSetter2() {
MAP[${1:-hello}] = ${2:-world}
}
function consumerGetter2()
echo ${MAP[${1:-hello}]}
}
フォーラムへようこそ!