【问题标题】:How to run a terminal with clean environment from Python如何从 Python 运行具有干净环境的终端
【发布时间】:2017-02-16 22:41:08
【问题描述】:

我需要从我的 Python 脚本运行终端并在干净的环境中执行命令,就像我刚刚打开终端模拟器并在那里输入命令一样。但是我的脚本中有一些导出的变量在此终端中不可用。可以有任意数量的变量(其中一些甚至可以使用 bash 'export' 命令在脚本之外设置),所以我不能在运行终端之前手动删除它们。

我尝试了声称重置默认环境的通用解决方案,但它不起作用。代码如下所示:

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”。

有什么办法可以解决这个问题吗?

【问题讨论】:

    标签: python linux bash


    【解决方案1】:

    调用subprocess.Popen时使用env参数:

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

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

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

    【讨论】:

    • 我尝试了这个解决方案,但由于某种原因,如果我添加env={},终端根本无法打开,可能是因为在这种情况下删除了一些重要变量。
    • 如果您无法识别成功运行命令所需的环境变量,请在运行脚本后立即将环境变量存储在某个缓存中(例如env_cache = os.environ.copy()),然后稍后使用此缓存作为envPopen 的参数。如果你想删除环境。即使在执行脚本之前外壳中​​的更改,您也不能,因为您没有跟踪它们。
    • 话虽如此,尝试更改您的命令以执行 env -i after bash -c (因此在命令本身内) - 我有一种感觉 bash -c 正在挑选从配置文件和其他文件中添加您的环境变量,并且 $X 实际上是在其中一个文件中定义的。
    • 是的,我尝试了gnome-terminal -x bash -c env -i "echo $X; bash --noprofile --norc",但在这种情况下,终端会立即显示并消失,并且没有任何反应。我尝试touch 文件而不是echo,但它不起作用
    • 不,我的意思是将你的命令设置为:gnome-terminal -x "env -i bash --noprofile --norc" 或类似的东西(我不明白你为什么首先需要 gnome-terminal,我会运行你的命令: env -i bash --noprofile --norc)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 2021-11-24
    相关资源
    最近更新 更多