C++ プログラムを複数回実行する bash スクリプトを作成しています。私はgetenv()
andを使用putenv()
して、C++ プログラムで環境変数を作成、取得、および更新しています。C++ プログラムの終了後、bash スクリプトはこれらの変数を取得し、いくつかの基本的なロジックを実行する必要があります。問題は、C++ プログラムが終了すると、環境変数が消えることです。プログラムの終了後にこれらの変数を永続的に保存して、bash スクリプトが使用できるようにする方法はありますか? そうでない場合、bash スクリプトと C++ プログラムの間で変数を共有する最良の方法は何ですか? 私が考えることができる唯一の解決策は、出力をファイルに書き込むことです。このデータをコンソールに出力したくありません。どんな助けでも大歓迎です。
6 に答える
各プロセスには、環境変数の独自のコピーがあり、新しいプロセスの起動時に親プロセスからコピーすることによって初期化されます。プロセスで環境変数を変更しても、親プロセスはこれを認識しません。
子から親に情報を返すには、別の種類の通信チャネルを設定する必要があります。ディスク上のファイル、パイプ、または(親の機能によっては、bash
これらすべてを実行できない場合があります)共有メモリまたはその他の IPC メカニズムの可能性があります。親プログラムは、子から受け取った情報に基づいて、独自の環境変数を変更する責任があります。
私は個人的に、16ビットDOSアセンブラーで、前のプロセスへのポインターをそれ自体を指すまでトレースすることによってのみこれを行うことができました。つまり、COMMAND.COMの最初のインスタンスに到達し、その手動で環境。
プログラムが標準出力を介して変数を文字列として返した場合、次のようになります。
FOO=23; BAR=45;
次に、bash は次のように呼び出すことができます。
eval `./your_program`
$FOO と $BAR が bash にアクセスできるようになります。
これをテストするには、次を試してください。
eval `echo "FOO=23; BAR=45;"`
echo "$FOO $BAR"
もちろん、このメソッドでは、プログラムは呼び出しプロセスの環境変数を変更しませんが (これは不可能です)、bash によって評価される文字列を返すだけで、評価によって変数が設定されます。
プログラムが信頼できないソースからの入力を処理する場合は、このメソッドを使用しないでください。誰かがあなたのプログラムをだまして "rm -rf /" を標準出力に出力させたら、あなたは破滅するでしょう。
プロセスの存続期間を生き残る環境変数を設定することはできないため、最も簡単な解決策は、提案したように出力ファイルに書き込むか、Bash から渡された特定のファイルハンドルに書き込むことです。
C++:
int main (int argc, char* argv[])
{
// missing error handling
int fd = atoi(argv[1]);
const char* env = "BLAH=SMURF";
write(5, env, strlen(env));
return 0;
}
バッシュ:
# discard stdout and stderr, redirect 5 to stdout so that it can be captured
# and tell the process that it should write to 5 (the first 5)
VARIABLES=`./command 5 2>&1 1>/dev/null 5>&1`
これはおそらくクラックポットのアイデアですが、うまくいくはずです:)
私が知る限り、「標準」の GNU/Linux 環境では、次の 3 つの方法で環境変数を設定できます。
- のようなコマンド ライン ユーティリティを使用して
export
~/.profile
またはfor のようなファイルの編集、またはfor system~/.bashrc
の下の同等のファイルの編集/etc
- このようなコマンドに一時的な値を与える
CXX=g++ CUSTOM_VERSION=2.5 command
最後のものは通常ビルドをカスタマイズするために使用され、システムに害を及ぼさず、システム設定、値、またはファイルに干渉せず、コマンドの実行後にすべてが正常に戻るため、優れています。特定の変数セットを一時的に変更したい場合に最適な方法です。
プログラムが親で環境変数を設定する方法はありません。または、まあ、正当な方法はありません。でのプロセスへのハッキングptrace
はカウントされません。:-)
あなたがすべきことは、標準出力に環境変数を出力することです。シェルスクリプトにそれらを読み取らせて設定させます。環境変数だけを出力する場合、呼び出しは非常に簡単です。
`program`
バックティックは、プログラムの出力をキャプチャします。次に、バックティックを出力に置き換えます。シェル変数を設定するコマンドになります。その後、シェルスクリプトで次のことを必ず実行してください。
export VAR1
export VAR2
シェルから起動されたプログラムに渡される環境にエクスポート コマンドを移動するには、エクスポート コマンドが必要です。