web-dev-qa-db-ja.com

マスターpidに関連するグローバルのようなシェル間で環境変数を共有する方法は?

したがって、シェル間で環境変数を共有する必要があります。また、変数の変更は、グローバル変数のように、すべてのシェルですぐに認識されるようにする必要があります。しかし、それらはマスターPIDに関連付けられている必要があるため、2つのシェルスクリプトを実行できます。それぞれが同じグローバル変数名を持つマスターであり、その子はマスターPIDに関連する変数のみを変更します。

スクリプトにはbashを使用しています。

私の現在の研究はこれらです:

モジュール
私はそのためにモジュールプロジェクトを使用できると読みました: http://modules.sourceforge.net/ ですが、それを実行しようとして大きな問題を抱えています。例がないようです。また、「モジュール」はあまりに一般的な単語であり、他の多くのものと混ざり合うためグーグルで検索するのが非常に困難です...数週間後、私の手はまだ空です...

シンプルなテキストソースファイル
また、同時書き込みを避けるために、flockを使用して、ソーススクリプトファイルとして変数を格納/更新/読み取るための単純なテキストファイルを使用する必要があることも読みました。しかし、2つのシェルで同時に変数を同時に変更するなど、それに関連する問題があります。

または
「グローバル」変数がシェルによって読み取られた後、別の読み取りが行われるまでその値が保持されることを知っています。そして、別のシェルが平均的にそれを変えるかもしれません…
非常に高速な外部アプリケーションがそのようなストレージを提供でき、環境変数をグローバルとして使用しようとしないでしょうか?しかし、私の推測では、SQLソリューションは遅すぎるでしょう…

8
Aquarius Power

export -pを使用して環境をファイルに書き込み、.(includeコマンド)を使用して他のインスタンスで定期的に環境を読み取ることができます。しかし、お気づきのように、同時変更がある場合、結果はきれいではありません。

変更をすぐに反映させる場合は、export組み込み関数のラッパーを使用して、変更を他のシェルにも反映させる必要があります。 Linuxでは、flockユーティリティを使用できます。

global_export () {
  {
    flock 0
    . /path/to/env
    [ $# -eq 0 ] || export "$@"
    export -p >/path/to/env
  } </path/to/env
}

エクスポートされた変数に新しい値を割り当てるときは常にglobal_exportを呼び出す必要があることに注意してください。

これはかなり不器用です。問題を解決するためのより良い方法がある可能性があります。最も明白な方法は、それらの環境変数を使用するコマンドが代わりに構成ファイルを読み取るようにすることです。

fishシェルでは、niversally scoped variablesを使用します。

set -U var value

もちろん、これは同じユーザーが実行するfishシェル全体でのみ機能します。

master pidに関連付ける場合は、変数名に含めます。

set -U m${masterpid}var value
2

Gilesの回答からflockを使用するだけでなく、次のようなことも行います。

シグナルハンドラーを登録してファイルをリロードします。

reload_env() {
 flock -s 3
 . /path/to/env
 flock -u 3
}
trap reload_env USR1

ファイルを書き出し、SIGUSR1をすべてのシェルに送信してファイルをリロードするよう通知する関数:

export_env() {
 flock 3
 export -p >/path/to/env
 flock -u 3
 fuser -k -USR1 /path/to/env
}

ファイルを開きますが、何もしません。これは、fuserがこのシェルに信号を送信できるようにするためのものです。

exec 3>>/path/to/env

順序は多少重要です。少なくともexec ...部分はtrap ...部分の後にある必要があります。それ以外の場合は、ファイルを開いて、シグナルハンドラを登録する前にfuser呼び出しによってシグナルを受け取ることができます。

注:コードは完全にテストされていませんが、原則はそのままです
注2:このコード例はbashを対象としています。

2
Patrick

Ksh93がオプションの場合、共有ストレージとの間で変数値を取得/保存するゲッターおよびセッターの統制関数を使用して、必要な機能を実装する方法が確実にあります。

詳細は https://stackoverflow.com/questions/13726293/environment-variables-to-be-used-across-multiple-korn-ksh93-Shell-scripts-get を参照してください

他の点では有用なfishユニバーサル変数機能とは異なり、実装にアクセスできるため、値の共有をプロセスのグループに制限することができます。変数の名前。

1
jlliagre

このため、名前付きパイプを紹介します。これが 1つのきちんとした例 です。

名前付きパイプは、次のコマンドで作成されます。

mkfifo pipe_name

次の方法で簡単に書き込むことができます。

echo "This text goes to the pipe" > pipe_name

一方、パイプから次のように読み取ることができます。

read line < pipe_name;
echo $line

通信するシェルの数に基づいて、いくつかのパイプを作成できます。パイプの良いところは、単なる変数ではないということです。プロセス間で実際にanyデータを渡すことができます。ファイル全体、テキスト行など、必要に応じて渡すことができます。これを念頭に置いて、スクリプトを大幅に簡略化できると思います。変数がデータの場所またはファイルを指し、他のスクリプトがそれを読み取りまたは取得する必要がある場合、変数を必要とせずにデータ/ファイルを直接渡すことができると想像できます。

1
Bichoy

コメントを考慮して、基本的なIPCが必要です。私はファイルに書き込むだけです(原子性の名前を変更して))

varf=$(mktemp ./myvars.XXXXXX)
echo myvar=newval > $varf
mv -T -- $varf ./myvars

そして、読者に定期的に./myvarsを提供してもらいます。

IPCは、たとえばPythonとマルチプロセッシングモジュールを使用すると、はるかに簡単になります。

0
Gabriel

このプロジェクトもあります ScriptEchoColor

DBテキストファイルを自動的に作成および管理できます。最初の実行スクリプトではBDファイルが作成され、他のスクリプトは変数値を操作する独自のDBとしてそのファイルにシンボリックリンクするため、両方が情報を交換できます。

examples folder にあるこれらのファイルを使用した簡単な共有の例:secExplShareEnvVarsA.sh、secExplShareEnvVarsB.sh

そして、同期された(安全で一貫性のある読み取り/書き込み)共有DBアクセスもあります:secExplSyncedShareEnvVarsA.sh、secExplSyncedShareEnvVarsB.sh

0
Aquarius Power