2017-02-16 34 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”被打印出来。

是否有可能解决这个问题的任何解决方案?

回答

1

调用subprocess.Popen时使用env说法:

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

这将在清洁的环境中运行它作为可能的,但是很多也许需要的环境变量将丢失。在启动脚本时,您可能需要缓存os.environ,然后使用该缓存填充env参数,以获得与启动脚本时相同的环境变量。

更新(为了清楚起见):请记住,当前环境总是被复制到任何子进程(并且子进程无法访问/更改其父母的环境),因此上述基本上将当前环境将其空白(给出空白环境的子流程副本),如果子流程无法建立新环境,则永远不会知道脚本环境中的变量。部分缓解这种情况的一种方法是实际让bash(或者您从子进程调用的任何shell)加载配置文件和其他用户脚本,但它仍然不会获得全局环境。

+0

我试过这个解决方案,但由于某些原因,如果我加上'ENV = {}'终端根本不打开所有,可能是因为一些重要的变量是这种情况下将其擦除。 –

+0

如果您无法确定成功运行命令所需的环境变量,只要您运行脚本,将您的环境变量存储在某个缓存中(例如'env_cache = os.environ.copy()'),然后使用此缓存后来成为'Popen'的'env'参数。如果你想擦除env。即使在执行脚本之前,shell也会发生变化,因为您没有跟踪它们。 – zwer

+0

这就是说,试着改变你的命令来在*'bash -c之后执行'env -i' *(所以在命令本身中) - 我有一种感觉,'bash -c'从配置文件中获取你的环境变量和其他文件,其中'$ X'实际上是在其中一个文件中定义的。 – zwer