pythonスクリプトを作成して、シミュレーションコードを実行するディレクトリでスクリプトを実行することにより、適切な環境変数を作成することを望んでいました。これらのenv変数をmac osターミナルに保持するためのスクリプトです。
これは本当ですか?
そして
それは役に立つことだと思われます。なぜ一般にできないのですか?
あなたはPythonからそれを行うことはできませんが、いくつかの巧妙なbashトリックは同様のことをすることができます。基本的な理由は次のとおりです。環境変数はプロセスごとのメモリ空間に存在します。 fork()で新しいプロセスが作成されると、そのプロセスは親の環境変数を継承します。次のようにシェルで環境変数(bashなど)を設定すると:
export VAR="foo"
あなたがしているのは、プロセス空間の変数VARを「foo」に設定するようにbashに指示することです。プログラムを実行すると、bashはfork()を使用してからexec()を使用してプログラムを実行するため、bashから実行するものはすべてbash環境変数を継承します。
ここで、現在のディレクトリにある「.data」というファイルのコンテンツを使用して環境変数DATAを設定するbashコマンドを作成するとします。まず、ファイルからデータを取得するコマンドが必要です。
cat .data
それはデータを印刷します。次に、bashコマンドを作成して、そのデータを環境変数に設定します。
export DATA=`cat .data`
このコマンドは、.dataの内容を取得し、環境変数DATAに入れます。これで、エイリアスコマンド内にそれを配置すると、環境変数を設定するbashコマンドができます。
alias set-data="export DATA=`cat .data`"
そのエイリアスコマンドをホームディレクトリの.bashrcまたは.bash_profileファイル内に配置して、起動した新しいbashシェルでそのコマンドを使用できるようにすることができます。
回避策の1つは、export
コマンドを出力し、親シェルにこれを評価させることです。
thescript.py
:
import pipes
import random
r = random.randint(1,100)
print("export BLAHBLAH=%s" % (pipes.quote(str(r))))
..およびbashエイリアス(ほとんどのシェルで同じことができます。tcshでさえも!):
alias setblahblahenv="eval $(python thescript.py)"
使用法:
$ echo $BLAHBLAH
$ setblahblahenv
$ echo $BLAHBLAH
72
次のような複数のコマンドを含む、任意のシェルコードを出力できます。
export BLAHBLAH=23 SECONDENVVAR='something else' && echo 'everything worked'
動的に作成された出力(pipes.quote
モジュールはこれに適しています)
pythonスクリプト(または他のスクリプトまたはプログラム)内で環境変数を設定しても、親シェルには影響しません。
説明を編集:あなたの質問への答えはイエスです、それは本当です。ただし、シェルスクリプト内からエクスポートし、ドット呼び出しを使用してソースを作成できます。
fooexport.shで
export FOO="bar"
コマンドプロンプトで
$ . ./fooexport.sh
$ echo $FOO
bar
私がやりたいのは、シェルスクリプトで/ usr/bin/envを使用して、同様の状況にいるときにコマンドラインを「ラップ」することです。
#!/bin/bash
/usr/bin/env NAME1="VALUE1" NAME2="VALUE2" ${*}
このスクリプトを「myappenv」と呼びましょう。 $ PATHにある$ HOME/binディレクトリに配置します。
これで、「myappenv」を次のように追加するだけで、その環境を使用してコマンドを呼び出すことができます。
myappenv dosometask -xyz
他の投稿されたソリューションも動作しますが、これは私の個人的な好みです。 1つの利点は、環境が一時的であるため、シェルで作業している場合、呼び出すコマンドのみが変更された環境の影響を受けることです。
新しいコメントに基づいて修正されたバージョン
#!/bin/bash
/usr/bin/env G4WORKDIR=$PWD ${*}
これもすべてエイリアスでラップできます。他の環境も準備する傾向があるので、ラッパースクリプトアプローチを好みます。これにより、メンテナンスが容易になります。
一般的には不可能です。 pythonのために作成された新しいプロセスは、その親プロセスの環境に影響を与えることはできません。親も子に影響を与えることはできません。
おそらく、MacOSの.bashrc
、.profile
または同等の「ログイン時に実行」または「すべての新しいターミナルセッションで実行」スクリプトで設定できます。
python希望する環境でシミュレーションプログラムを開始することもできます。subprocess.Popenにenv
パラメーターを使用してください( http://docs.python。 org/library/subprocess.html ))
import subprocess, os
os.chdir('/home/you/desired/directory')
subprocess.Popen(['desired_program_cmd', 'args', ...], env=dict(SOMEVAR='a_value') )
または、python .sh
拡張子を持つファイルにこのようなシェルスクリプトを書き出すことができます:
export SOMEVAR=a_value
cd /home/you/desired/directory
./desired_program_cmd
そしてchmod +x
それをどこからでも実行します。
Bensonが回答したとおりですが、最善のハックアラウンドは、引数を保持するための単純なbash関数を作成することです。
upsert-env-var (){ eval $(python upsert_env_var.py $*); }
引数を指定してpythonスクリプトで何でもできます。変数を追加するには、次のようなものを使用します。
var = sys.argv[1]
val = sys.argv[2]
if os.environ.get(var, None):
print "export %s=%s:%s" % (var, val, os.environ[var])
else:
print "export %s=%s" % (var, val)
使用法:
upsert-env-var VAR VAL