web-dev-qa-db-ja.com

グローバル環境変数を設定するbashスクリプトを作成する方法は?

最近、環境変数を設定するスクリプトを作成しました。見てみましょう。

#!/bin/bash

echo "Pass a path:"
read path
echo $path

defaultPath=/home/$(whoami)/Desktop

if [ -n "$path" ]; then
    export my_var=$path
else
    echo "Path is empty! Exporting default path ..."
    export my_var=$defaultPath
fi

echo "Exported path: $my_var"

うまくいきますが、問題はmy_varはローカルでのみ使用可能です。つまり、スクリプトを実行したコンソールウィンドウで使用できます。

どこでも見ることができるglobal環境変数をエクスポートできるようにするスクリプトを書く方法は?

38
Katie

すべてのシェルには独自の環境があります。すべてのコンソールウィンドウに魔法のように表示されるUniversal環境はありません。あるシェルで作成された環境変数は、別のシェルではアクセスできません。

さらに制限されています。 1つのシェルがサブシェルを生成する場合、そのサブシェルは親の環境変数にアクセスできますが、そのサブシェルが環境変数を作成する場合、親シェルではアクセスできません。

すべてのシェルが同じ変数セットにアクセスする必要がある場合は、それらを設定するstartupファイルを作成できます。これは、BASHで$HOME/.bash_profileおよび$HOME/.bashrcファイルを介して行われ、$HOME/.profileが存在しない場合は$HOME/.bash_profileを介して行われます)。他のシェルには、独自のスタートアップファイルのセットがあります。 1つはログインに使用され、もう1つはログインなしで生成されたシェルに使用されます。使用されているスタートアップスクリプトと実行される順序を正確に知るには、マンページを参照してください)。

共有メモリの使用を試すことはできますが、プロセスの実行中にのみ機能すると考えています。共有メモリの一部を設定する方法を見つけたとしても、そのコマンドが終了するとすぐに消えてしまいます。 (名前付きパイプ以外の共有メモリはほとんど使用しませんでした)。そうしないと、1つのシェルで環境変数を設定し、別のシェルが自動的にそれを取得する方法が実際にありません。 名前付きパイプ を使用するか、その環境変数をファイルに書き込み、他のシェルがそれを取得できるようにすることができます。

誰かが私の知らないうちに1つのシェルの環境を変更できる場合に発生する可能性のある問題を想像してください。

37
David W.

"."(ドットスペース)を前に付けてシェルスクリプトを実行するだけです。

これにより、スクリプトは元のシェルの命令を実行します。したがって、スクリプトが終了した後も変数はまだ存在しています

例:

cat setmyvar.sh
export myvar=exists

. ./setmyvar.sh

echo $myvar
exists
91
JDembinski

David W.の回答の2番目の段落から次のように抽出されました。 」

ユーザーが親シェルに新しい環境変数へのアクセスを許可する必要がある場合は、親シェルで次のコマンドを発行するだけです。

source <your_subshell_script>

またはショートカットを使用して

. <your_subshell_script>
2
Jonathan L

/home/$USER/.profileにある.profileに変数を追加する必要があります

Yoはこのコマンドでそれを行うことができます:

echo 'TEST="hi"' >> $HOME/.profile

または、たとえばemacsを使用してファイルを編集します。すべてのユーザーにこの変数を設定する場合は、/ etc/profile(root)を編集する必要があります

2
MarcD

~/.bin/SOURCED/lazyシステムのフラットファイルとしてデータを保存およびロードするスクリプト。

[ ! -d ~/.megadata ] && mkdir ~/.megadata

function save_data {
[ -z "$1" -o -z "$2" ] && echo 'save_data [:id:] [:data:]' && return
local overwrite=${3-false}
[ "$overwrite" = 'true' ] && echo "$2" > ~/.megadata/$1 && return
[ ! -f ~/.megadata/$1 ]   && echo "$2" > ~/.megadata/$1 || echo ID TAKEN set third param to true to overwrite
}

save_data computer engine
cat ~/.megadata/computer
save_data computer engine
save_data computer megaengine true

function get_data {
[ -z "$1" -o -f $1 ] && echo 'get_data [:id:]' && return


[ -f ~/.megadata/$1 ]   && cat ~/.megadata/$1 || echo ID NOT FOUND
:
}

get_data computer
get_data computer
1
Arcabard

シェルスクリプトで環境変数を動的に設定および参照する必要がある場合は、回避策があります。行う価値があるかどうかを自分で判断しますが、ここではそれです。

この戦略には、環境変数を設定およびエクスポートするコードを持つ「ロード」スクリプトを動的に書き込む「セット」スクリプトが含まれます。次に、変数を参照する必要がある他のスクリプトによって、「load」スクリプトが定期的に実行されます。ところで、変数の代わりにファイルを読み書きすることで、同じ戦略を実行できます。

ここに簡単な例があります...

Set_Load_PROCESSING_SIGNAL.sh

#!/bin/bash
PROCESSING_SIGNAL_SCRIPT=./Load_PROCESSING_SIGNAL.sh
echo "#!/bin/bash" > $PROCESSING_SIGNAL_SCRIPT
echo "export PROCESSING_SIGNAL=$1" >> $PROCESSING_SIGNAL_SCRIPT
chmod ug+rwx $PROCESSING_SIGNAL_SCRIPT

Load_PROCESSING_SIGNAL.sh(上記の実行時に動的に作成されます)

#!/bin/bash
export PROCESSING_SIGNAL=1

Test_PROCESSING_SIGNAL.shでこれをテストできます

#!/bin/bash
PROCESSING_SIGNAL_SCRIPT=./Load_PROCESSING_SIGNAL.sh
N=1
LIM=100
while [ $N -le $LIM ]
do
# DO WHATEVER LOOP PROCESSING IS NEEDED
echo "N = $N"
sleep 5
N=$(( $N + 1 ))

# CHECK PROCESSING_SIGNAL
source $PROCESSING_SIGNAL_SCRIPT
if [[ $PROCESSING_SIGNAL -eq 0 ]]; then
# Write log info indicating that the signal to stop processing was detected
# Write out all relevent info
# Send an alert email of this too
# Then exit
echo "Detected PROCESSING_SIGNAL for all stop. Exiting..."
exit 1
fi
done
1
wxwizard

実際、UNIXにはグローバル環境はありません。

各プロセスには元々親から継承された環境がありますが、最初の作成後はプロセスに対してローカルです。

デバッガを使用してプロセスを掘り下げない限り、変更できるのは自分だけです。

1
perh

環境変数は、プロセスの実行を常に「ローカル」にして、エクスポートコマンドでサブプロセスの環境変数を設定できます。 .bashrcを見て、bashシェルの開始時に環境変数を設定できます。プロセスは別のプロセスの環境変数を変更(またはアクセス?)できないため、あなたがしようとしていることは不可能のようです。

1

環境の初期化に使用される〜/ .bashrcまたは〜/ .bash_profileファイルを更新できます。

1
Jin Kim

一時ファイルに書き込み、〜/ .myglobalvarと言ってどこからでも読み取ります

echo "$myglobal" > ~/.myglobalvar
1
Sergio Abreu

シェルの読み込み動作を見てください(通常は.XXXshrcまたは.profileを参照しているマンページで説明されています)。一部の構成ファイルは、対話型シェルのログイン時にロードされ、一部はシェルを実行するたびにロードされます。後者に変数を配置すると、必要な動作になる可能性があります。常にその別個のシェルを使用して変数を設定します(たとえば、bash)。

1
count0

実際、私はこれを達成する方法を見つけました(私の場合は、bashスクリプトを使用していくつかのセキュリティ資格情報を設定することでした)

スクリプト内からbashを呼び出すだけで、生成されたシェルにエクスポート値が設定されます

export API_USERNAME=abc
export API_PASSWORD=bbbb
bash

~/.app-x-setup.shを使用してファイルを呼び出すと、これらの環境値が設定されたインタラクティブなシェルが表示されます

1
Dinis Cruz