【问题标题】:How to get the environment variable set by a bash script from inside a python script?如何从 python 脚本中获取由 bash 脚本设置的环境变量?
【发布时间】:2013-10-26 01:58:05
【问题描述】:

我确实有一个 setenv.sh 脚本,它在其他几个脚本的开头被调用,其中大多数是 bash 脚本。显然这个脚本确实设置了一些环境变量,这些变量是这些脚本以后使用的。

现在,问题是我想在一些 python 脚本中实现相同的行为,我发现如果你运行 setenv,python 脚本的环境不会更新。

因为我不想创建另一个脚本,它首先调用setenv.sh 和其他这个 myscript.py --- 我正在寻找一种方法来说服 python 加载这些变量(解析 seteve.h 不是选项...因为它更复杂)。

【问题讨论】:

  • 您需要提供更多详细信息,或者更好地显示 shell 脚本。你是如何设置变量的? setenv.sh 的运行情况如何?然后你是如何运行其他脚本的?
  • 我使用os.system() 调用 setenv 但根据我阅读的内容,没关系,因为其他方法也会启动一个新进程,该进程将拥有父进程 (py) env 的副本.这意味着当孩子结束时,我将丢失 env 更改。当我从 bash 脚本执行此操作时,它会起作用(只要他们使用 export = AAA=AAAVALUE)。
  • 您不能通过执行外部脚本来影响 Python 进程的环境。该脚本只能影响它自己的环境,而不是生成它的 Python 进程的环境。
  • @chepner ...我的问题是关于从中获取这些变量...我的价值观。一种丑陋的方法是执行“setenv.sh & echo VAR1”并解析输出......非常丑陋,尤其是如果您要加载大约 10-15 个变量。

标签: python bash environment-variables


【解决方案1】:

这是一个可以做到这一点的小库:

https://github.com/aneilbaboo/shellvars-py

【讨论】:

    【解决方案2】:

    最简单的解决方案显然是你不想要的,那就是为每个 python 脚本创建一个新的脚本文件。

    但是,您可以通过调用 python 脚本本身来做大致等效的操作。当然,您需要在第二次调用时通知它不要这样做,否则您将得到无限(尾)递归。

    下面的小“模块”(您可以直接导入,但您应该在启动时立即执行,然后再执行其他操作)将检查环境变量 SETENV 是否已设置,如果已设置,它将在获取SETENV 命名的文件后重新发出python 命令(尽其所能,因此如果它不仅仅是一个简单的脚本执行,它可能会出错)。它缺乏大量的错误检查,不应该被认为是生产就绪的;而是概念验证:

    # file env_set.py
    import os
    import sys
    
    if sys.argv[0] and "SETENV" in os.environ:
      setenv = os.environ["SETENV"]
      del os.environ["SETENV"]
      os.execvp("bash", ["bash", "-c",
            "source " + setenv + "; exec python " + sys.argv[0] + ' "${@}"',
            "--"] + sys.argv[1:])
    

    还有一个小测试:

    # file test_env_set.py
    import env_set
    
    import os
    import sys
    for name in sys.argv[1:]:
      if name in os.environ:
        print(name + "=" + os.environ[name])
      else:
        print("Undefined: " + name)
    
    # file setenv.sh
    export the_answer=42
    
    $ python test_env_set.py SETENV the_answer
    Undefined: SETENV
    Undefined: the_answer
    $ SETENV=setenv.sh python test_env_set.py SETENV the_answer
    Undefined: SETENV
    the_answer=42
    

    【讨论】:

      【解决方案3】:

      也许尝试在导出之前和之后运行env,然后比较结果。像这样的

      $ pwd
      /tmp/test
      $ cat setenv.sh
      #!/bin/bash
      export test=1234
      $ cat test.sh
      #!/bin/bash
      source /tmp/test/setenv.sh
      echo $test
      $ ./test.sh
      1234
      $ python test.py
      test=1234
      $ cat test.py
      #/usr/bin/env python
      import os, subprocess
      p=subprocess.Popen('env',stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
      oldEnv=p.communicate()[0]
      p=subprocess.Popen('source /tmp/test/setenv.sh ; env',stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
      newEnv=p.communicate()[0]
      for newStr in newEnv.split('\n'):
          flag = True
          for oldStr in oldEnv.split('\n'):
              if newStr == oldStr:
                  #not exported by setenv.sh
                  flag = False
                  break
          if flag:
              #exported by setenv.sh
              print newStr
      

      【讨论】:

      • 这显然会起作用......丑陋但它应该起作用。我会先测试一下。谢谢!
      • 谢谢。我不得不接受另一个答案,因为它更容易,但你的也很好。
      • 不用担心,stackoverflow 上还有一些体面的人,他们不仅是为了声誉。我们提出问题并回答答案只是因为我们可以:-)
      猜你喜欢
      • 2011-03-05
      • 2016-10-07
      • 2012-01-19
      • 2013-11-15
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多