特定の変数を「インポートする」方法

特定の変数を「インポートする」方法

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}]}
}

フォーラムへようこそ!

関連情報