2012-02-09 7 views
21

bashスクリプトファイルconfig.shがあるとします。これは、他のスクリプトによってソース化されることを意図しており、定義された変数は、上位レベルのスクリプトのカスタマイズとして使用されます。bash:スクリプトをソース化しないファイルローカル変数を定義する

config.shに一時変数があり、その名前が上位レベルスクリプトの変数と競合すると、上位レベルのスクリプトが破損するという問題があります。

config.sh:

TMP1=abc 
CONFIG_INPUT_DIR="$TMP1"/in 
CONFIG_OUTPUT_DIR="$TMP1"/out 

上位スクリプト:

TMP1=def 
source config.sh 
echo $TMP1 

最後echoプリントabcdefありません。

ソリューション1つの

私の現在のソリューションは、競合することはほとんど不可能にするために、一時的な変数名にランダムな文字列を追加することです。例えば:

加えて、完璧ではないことが、痛みがあり、読み、コードはハードになり
TMP1_vFc9Uiew=abc 
CONFIG_INPUT_DIR="$TMP1_vFc9Uiew"/in 
CONFIG_OUTPUT_DIR="$TMP1_vFc9Uiew"/out 
unset TMP1_vFc9Uiew 

。いくつかの検索後localキーワード

を使用して2

ソリューションは、私がlocalキーワードを知るようになりました。 しかし、単にTMP1localと宣言すると、bashはconfig.sh: line 1: local: can only be used in a functionという文句を言います。

は、だから私のもう一つの解決策は、関数として全体configスクリプトを囲むことである。

​​

メンテナンス性と可読性の前のソリューションよりも優れているが、1

を競合するだけでなく、解決するためにいくつかの可能性があります

質問

矛盾することなく、より堅牢でスマートなソリューションを知りたいと思います。

ありがとうございました。

答えて

4

私がkeychainユーティリティから学んだトリックは、プログラムからエクスポートする変数だけを含むsource対応ファイルを作成するための1つのプログラムを使用しています。あなたが設定した後、あなたのプログラムから出力を調達したいecho変数にスクリプトを修正することができます:

$ echo $FOO 

$ source <(echo FOO=bar) 
$ echo $FOO 
bar 
$ 

私は大きなスクリプトをシミュレートするecho FOO=barを使用。あなたのプログラムはおそらくより関わっています。重要なのは、単に設定するのではなく、設定したい変数と値を出力するようにプログラムを変更する必要があることです。これにより、公開する変数と別のシェルプロセスを犠牲にして非公開にする変数を決めることができます。あなたの値を保持するためにconfig.shで、変数と使用機能を避けることができ

+0

'ssh-agent'は' -c'と '-s'オプションを使って同様の手法を使います。 – jjlin

+0

@jjlin:ありがとう!私は 'キーチェーン'が私が最初に見た場所ではないと思ったが、ドキュメントを見つけたのは最初だった。 :)おかしい、それは 'ssh-agent'のマンページにオープンしています。 – sarnold

+0

@sarnold:ありがとう、ありがとう!私はこのテクニックを試してみます。 – niboshi

0

一意のファイル名を作成する2つの通常の方法は、一意のファイル名を作成すること、またはPIDをファイル名に埋め込むことを保証するmktemp関数を使用することです。 PIDは変数 '$$'に配置されます。

+0

問題は、一意のファイル名が、ユニークな_variable names_を構築されていません。 (または、より良いのは、いくつかのスコープメカニズムです。) – sarnold

+0

Gotcha。 ...私は '$ CONFIG_INPUT_DIR'の使用によって混乱しました...構文的には、変数です、意味的にはディレクトリです。 –

6

get_dirname() { echo "abc"; } 
CONFIG_INPUT_DIR="$(get_dirname)/in" 
CONFIG_OUTPUT_DIR="$(get_dirname)/out" 
unset -f get_dirname 

あなたはまだ機能のための名前の衝突を懸念している場合、これは本当にあなたを助けていません。

4

"ssh-agentの" 方法:

config.sh

#!/bin/bash 
TMP=abc 
printf "CONFIG_INPUT_DIR=%s/in" "$TMP" 
printf "CONFIG_OUTPUT_DIR=%s/out" "$TMP" 

メインプログラム:

TMP1=def 
eval $(config.sh) 
echo $TMP1 
関連する問題