web-dev-qa-db-ja.com

すべてのサブシェルで使用できるように環境変数をエクスポートし、変更できるようにしますか?

私が持っていると仮定します

export MY_VAR=0

~/.bashrc

私はgnome端末を開いており、この端末で$MY_VAR値を200に変更します。だから、私がするなら

echo $MY_VAR

このターミナルでは、200が表示されます。

今、私は私のgnomeターミナルで別のタブを開いて、

echo $MY_VAR

...そして200の代わりに、私は0を持っています。

端末が環境変数を変更するときに200の値を保持し、この変更(200に設定)を後続のすべてのサブシェルなどで利用できるようにするにはどうすればよいですか?これは可能ですか?

環境のcopyがサブシェルに伝播するため、これは機能します。

$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200

しかし、それはコピーであるため、少なくとも環境を変更することによってではなく、親シェルまでその値を取得することはできません。

Gnomeターミナルの新しいタブのように、親とは別に開始された「兄弟」シェルによって共有されるグローバル変数のように機能するものを作成するということです。

ほとんどの場合、答えは「環境変数はそのように機能しないため、できません」です。ただし、別の答えがあります。つまり、いつでも何かをハックできます。 1つのアプローチは、変数の値を~/.myvarのようにファイルに書き込み、それを~/.bashrcに含めることです。次に、新しいシェルはそれぞれ、そのファイルから読み取られた値でstartになります。

さらに一歩進んで— ~/.myvarMYVAR=200の形式にしてから、Prompt_COMMAND=source ~/.myvarを設定すると、新しいプロンプトが表示されるたびに値が再読み取りされます。それはまだquite共有グローバル変数ではありませんが、そのように機能し始めています。ただし、プロンプトが返されるまでアクティブになりません。これは、実行しようとしていることに応じて、深刻な制限になる可能性があります。

そしてもちろん、次は自動的にwrite~/.myvarに変更されます。これはもう少し複雑になります。実際には、環境変数はシェル間通信メカニズムであることが意図されていなかったため、ここで停止します。それを行う別の方法を見つける方が良いです。

23
mattdm

export MY_VAR=0~/.bashrcがあるとします。

それはあなたの間違いです。環境変数は~/.profileで定義する必要があります。これは、ログイン時に読み取られます。~/.bashrcは、シェルを起動するたびに読み取られます。内部シェルを起動すると、MY_VARが上書きされます。これを行わなかった場合、環境変数は下方向に伝播します。

~/.bashrc~/.profileの詳細については、my previouspostsonthis を参照してください。 トピック

upward伝播(サブシェルから変更された値を親シェルに自動的に反映する)は不可能であり、完全に停止することに注意してください。

魚の殻はこれを行うことができます:

set -U MY_VAR 0

http://fishshell.com/docs/current/commands.html#set を参照)

別のシェルからfishコマンドを実行するには、fish -c、例: :

fish -c "set -u MY_VAR 0"
4

環境変数を使用しないでください。ファイルを使用します。

ファイルの更新/読み取り時にプロセスが互いに干渉しないようにするには、ロックされていないファイルを$ 1で更新することだけを目的としたロックファイルと小さなフロントエンドアップデータスクリプトを使用します。ロックファイルは、基本的には特定のファイル(/var/run/yourscript.lck)が存在するかどうかをチェックすることで実装され、存在する場合はしばらくの間ファイルが消えるまで待機し、存在しない場合は失敗します。また、ファイルの更新が完了したら、ロックファイルを削除する必要があります。

ファイルがビジーなためにスクリプトがファイルを更新できない状況を処理できるように準備してください。

3
LawrenceC

私がこの質問をググったところ、サブシェルの外から状態(つまり、シェル変数)を更新する問題を解決しようとしていました。たとえば、パイプラインの内部などで変数を割り当てることができます–そして、割り当ては親に透過的に表示されます。

もちろん、パイプラインの個々の部分は親シェルからforkされ、したがって copy-on-書き込み 親のメモリのビュー。しかし、「 共有メモリ -- IPCs のようなものに基づいて、スリムで透過的なソリューションが可能になると思いました。

そして、このデザインの implementation さえ見つけました...しかし、それはPerlにあります。

とにかくこの解決策を可能な解決策として追加します。

1
ulidtko