2つのシェルスクリプトfile1.shとfile2.shがあります
file1.sh
#!/usr/bin/env bash
export var1="/data/share"
export var2='password'
echo "Hello"
file2.sh
#!/usr/bin/env bash
source file1.sh
echo $var1
echo $var2
File2.shを実行すると、次の出力が表示されます
Hello
/data/share
password
しかし、私の期待される出力は
/data/share
password
file1.shは、file2.shで参照されると実行されます。 file1.shを実行せずにfile2.shに変数のみをインポートするにはどうすればよいですか?
ソースと実行時で異なる動作をしたいbashスクリプトがある場合(つまり、コードを実行せずにアクセスしたいスクリプトにデータ項目がある場合)に使用するオプションは3つあります。時間)。コメントはそれらにある程度触れました。
調達の時期を決定し、適切なタイミングで「ソーシング」を終了する
スクリプトを2つのセクションに分割し、ソースが提供されたときにスクリプトを終了してから、1秒未満になる
スクリプトの上部セクションを定義(関数/変数の割り当て/など)で作成しますが、直接のコード実行は行いません。
実行可能コードセクションが始まる直前に、スクリプトが読み込まれていることを検出した場合にスクリプトを終了するロジックを配置します。次のコードセグメントはこれを行います。
file1.sh
#!/usr/bin/env bash
export var1="/data/share"
export var2='password'
# --- End Definitions Section ---
# check if we are being sourced by another script or Shell
[[ "${#BASH_SOURCE[@]}" -gt "1" ]] && { return 0; }
# --- Begin Code Execution Section ---
echo "Hello"
echo $var1
echo $var2
file2.sh
#!/usr/bin/env bash
source file1.sh
echo "$var1"
echo "$var2"
実行中の./file2.shの出力
$ ./file2.sh
/data/share
password
これは通常、複雑な状況でのみ使用され、この特定の例では過剰です。取得したいファイルに関数を作成し、その関数で呼び出し元が利用できるものを決定します。この場合は、エクスポートされた2つの変数です。通常、私は連想配列がある場合にこのモードを使用します。これがなければ、手渡しするのはほとんど不可能です。また、tmpファイルは呼び出し元が削除する必要があります。この場合、私はしませんでした:
file1.sh
#!/usr/bin/env bash
export var1="/data/share"
export var2='password'
exportCfg() {
tmpF=$(mktemp)
declare -p var1 var2 > "$tmpF"
echo "$tmpF"
}
if [ "$1" == "export" ]; then
exportCfg;
exit 0;
fi
echo "Hello"
echo $var1
echo $var2
file2.sh
#!/usr/bin/env bash
source $(./file1.sh export)
echo "$var1"
echo "$var2"
File2.shの実行からの出力は上記と同じです
私がこれを処理する最後の一般的な方法は、定義のみを保持するライブラリファイルを使用することであり、ソースまたは直接実行されたときに実行されるコードはありません。これは単にコードを分割することの問題です。私は頻繁に使用される関数を含むbash 'libs'のグループを持っています。プロジェクトごとに、通常、構成データ(定数)を格納するための小さなソース可能なライブラリーをセットアップします。データに配列が含まれている場合は、オプション2のバージョンも使用します。
変数がすべて同じ方法でエクスポートされる場合(export foo = bar)、次にbashプロセス置換機能を使用してすべての変数を簡単に調達できます。
source <(grep '^export .*=' file1.sh)
マニュアルページの抜粋:
プロセスの置換プロセスの置換は、名前付きパイプ(FIFO)または/ dev/fd方式でオープンファイルに名前を付けることをサポートするシステムでサポートされています。 <(リスト)または>(リスト)の形式を取ります。プロセスリストは、入力または出力がFIFOまたは/ dev/fd内のファイルに接続された状態で実行されます。このファイルの名前は、次の結果として現在のコマンドに引数として渡されます。 >(list)フォームが使用されている場合、ファイルへの書き込みはリストの入力を提供します。<(list)フォームが使用されている場合、引数として渡されたファイルを読み取り、listの出力を取得する必要があります。