通过Python脚本设置Shell环境变量

18

我有一些需要环境变量的仪器,我希望能够从Python代码中自动地设置它们。因此,我尝试了几种方法来实现这个目标,但都没有成功。

  1. 我在我的Python脚本中插入了以下代码:

     import os
     os.system("export ENV_VAR=/some_path")
    
  2. 我创建了一个bash脚本(env.sh),并从Python中运行它:

  3.  #!/bin/bash
     export ENV_VAR=some_path
    
     #call it from python
     os.system("source env.sh")
    
  4. 我还尝试了os.putenv()os.environ*["ENV_VAR"] = "some_path"

是否可能使用Python设置(导出)环境变量,即不直接导出到shell?


这个“instrument”是从Python脚本内部启动的吗? - mike.dld
是的,正因为这个原因,我也需要更改我的 PATH 环境变量。 - Sergey Asryan
所有进程都有一个环境块,无论它们是用哪种语言编写的 - 您不需要一个 shell。当您使用 fork() 时,环境块会从父进程复制到子进程 - 在任何其他时间都不会复制。 - cdarke
4个回答

32

设置环境变量只对当前进程及其启动的任何子进程生效。因此,使用 os.system 仅会将其设置为运行以执行提供的命令的 shell。当该命令完成后,shell 就会消失,环境变量也随之消失。使用 os.putenvos.environ 设置它们有类似的效果;环境变量被设置为 Python 进程及其所有子进程。

我假设您正在尝试将这些变量设置为从中启动脚本的 shell 中,或者全局有效。这是行不通的,因为 shell(或其他进程)不是您在其中设置变量的 Python 脚本的子进程。

您可以尝试在 shell 脚本中设置变量,这样如果您使用 source 命令(使其在当前 shell 实例中运行,而不是在子 shell 中运行),则在脚本结束后它们将保持设置状态。


我该如何在Python中重新创建export FOO=bar作为一个shell命令? - Neil McGuigan

13
只要你从同一个进程启动“instrument”(我猜是一个脚本),它就应该可以工作:
In [1]: os.putenv("VARIABLE", "123")

In [2]: os.system("echo $VARIABLE")
123

您不能更改不同进程或父进程的环境变量。


9
一个 shell 函数可以完成这个任务。你需要打印出你的 export 语句,并执行 eval 命令。
set_shell_env() {
    output=$(python print_export_env.py $*)
    eval $output
}

8
这个问题的唯一好答案!其他人只是试图教育询问者。没有人问对错...我们只是想在Python中设置环境变量...有什么难以理解的?! - rubmz
1
除了应该是"$@"而不是$*之外,一切都很好 - 现在参数在空格上被分割并扩展为全局。同样,是eval "$output"而不是eval $output - Charles Duffy
4
这就是我喜欢这个网站的原因。完全不安全的答案,但却完美地起作用。 - Sam H.

0

根据您执行仪器的方式,您可能能够更改环境,特别是对于子进程而不影响父进程。请参阅文档中关于os.spawn*esubprocess.Popen的说明,它们接受表示子进程环境的单独参数。例如,在subprocess模块文档中提供了两种用法:替换 os.spawn 家族

Environment example:

os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接