2017-02-16 9 views
2

私はPythonスクリプトからターミナルを実行し、きれいな環境でコマンドを実行する必要があります。ターミナルエミュレータを開いてそこにコマンドを入力したようです。しかし私は、この端末では使用できないように、スクリプトにエクスポートされた変数をいくつか持っています。任意の数の変数があります(そのうちのいくつかはbashの 'export'コマンドを使用してスクリプト外に設定されることもあります)。そのため、ターミナルを実行する前に手動で削除することはできません。Pythonからきれいな環境でターミナルを実行するには

私は、デフォルトの環境をリセットすると主張されている一般的な解決策を試しましたが、うまくいかなかった。コードは次のようになります。

import subprocess 
import os 

os.environ['X'] = 'Y' 

cmd = 'gnome-terminal -x env -i bash -c "echo $X; bash --noprofile --norc"' 
subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True) 

出力には "Y"が出力されます。

$ export X=Y 
$ gnome-terminal -x env -i bash -c "echo $X; bash --noprofile --norc" 

新しい端末が開かれ、「Y」が印刷されます。ターミナルのみを使用して同じことを実行しようとすると、結果は同じです。

問題を解決する方法はありますか? subprocess.Popenを呼び出すとき

答えて

1

env引数を使用します。

subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True, env={}) 

しかしこれは多分必要な環境変数の多くは失われます、できるだけクリーンな環境でそれを実行します。スクリプトを開始するときにos.environをキャッシュし、そのキャッシュでenv引数を設定して、スクリプトを開始した時と同じ環境変数を取得することができます。

更新:(現在の環境は常にサブプロセスにコピーされます(サブプロセスは親の環境にアクセス/変更できません)。それを空白(空の環境のサブプロセスコピーを与える)にし、サブプロセスが新しい環境を確立できない場合は、スクリプトの環境から変数を決して知らないでしょう。部分的に軽減する1つの方法は、実際にbash(またはあなたのサブプロセスから呼び出すシェル)にプロファイルと他のユーザースクリプトを読み込ませることですが、それでも地球環境は得られません。

+0

私は 'env = {}'を追加して何らかの理由で端末を開けませんでした。何らかの重要な変数がこのケースを消去したからでしょう。 –

+0

コマンドを正常に実行するために必要な環境変数を特定できない場合は、スクリプトを実行するとすぐに環境変数をいくつかのキャッシュ(たとえば、 'env_cache = os.environ.copy()')に格納してから、後で 'Popen'の' env'引数として使用します。 envを消去したい場合。あなたのスクリプトを実行する前であってもシェルの変更は、あなたがそれらのトラックを持っていないのでできません。 – zwer

+0

それは言われているように、 'env -i' *を*' bash -c'の後に実行するようにコマンドを変更しようとする(コマンド自体の中で) - 私は 'bash -c'があなたの環境変数をプロファイル'$ X'は実際にそれらのいずれかで定義されていることを示します。 – zwer

関連する問題