【问题标题】:Read Bash variables into a Python script将 Bash 变量读入 Python 脚本
【发布时间】:2013-06-30 09:06:33
【问题描述】:

我正在运行一个 bash 脚本 (test.sh),它会加载到环境变量中(来自 env.sh)。这很好,但我试图看到 python 可以加载已经在 bash 脚本中的变量。

是的,我知道只传递我需要的特定变量作为参数可能会更容易,但我很好奇是否可以获取 bash 变量。

test.sh

#!/bin/bash
source env.sh

echo $test1

python pythontest.py

env.sh

#!/bin/bash

test1="hello"

pythontest.py

?
print test1 (that is what I want)

【问题讨论】:

    标签: python bash scripting environment-variables


    【解决方案1】:

    您需要在 bash 中导出变量,否则它们将是 bash 的本地变量:

    export test1
    

    然后,在python中

    import os
    print os.environ["test1"]
    

    【讨论】:

    • 我很好奇,有没有一种简单的方法可以导出所有变量?
    • @TallPaul os.environ 字典已经包含程序可以看到的所有变量。
    • set -a; source env.sh; set +a-a 选项指示 bash 导出每个新变量,直到您使用 +a 将其关闭。
    • 除了使用'export',你也可以在你的命令前面设置它——在这种情况下,它只适用于你的命令:'test1=wibble python myscript' - 注意:有'python' 前面没有分号 - 这是故意的。
    【解决方案2】:

    假设设置的环境变量是永久的,我认为它们不是。你可以使用os.environ

    os.environ["something"]
    

    【讨论】:

    • ource 命令之前添加set -a(在单独的行上)。这就是说,从现在开始,任何变量集都应该自动导出。
    • @TallPaul,正如 AMADANON Inc. 所说。但是您可以为当前环境设置变量from python
    【解决方案3】:

    还有另一种使用subprocess 的方法,它不依赖于设置环境。不过,还有一些代码。

    对于如下所示的 shell 脚本:

    #!/bin/sh
    myvar="here is my variable in the shell script"
    
    function print_myvar() {
        echo $myvar
    }
    

    您可以检索变量的值,甚至可以在 shell 脚本中调用函数,如以下 Python 代码:

    import subprocess
    
    def get_var(varname):
        CMD = 'echo $(source myscript.sh; echo $%s)' % varname
        p = subprocess.Popen(CMD, stdout=subprocess.PIPE, shell=True, executable='/bin/bash')
        return p.stdout.readlines()[0].strip()
    
    def call_func(funcname):
        CMD = 'echo $(source myscript.sh; echo $(%s))' % funcname
        p = subprocess.Popen(CMD, stdout=subprocess.PIPE, shell=True, executable='/bin/bash')
        return p.stdout.readlines()[0].strip()
    
    print get_var('myvar')
    print call_func('print_myvar')
    

    注意shell=True都要设置,以便处理CMD中的shell命令按原样处理,设置executable='bin/bash'使用进程替换,默认/bin/sh不支持.

    【讨论】:

    • 有点我有 20 个环境,我需要获取 20 个文件来获取所有这些。你能帮助从一个来源而不是每次运行中编写 get_var 吗?这怎么可能?
    • @IvanShelonik 我猜您可以将CMD 变量中给出的bash 代码逐行更改为echo 多个变量并运行相同的代码。您还需要按如下方式更改return 语句:list(map(strip, p.stdout.readlines())) 以便返回检索到的变量列表。
    【解决方案4】:

    如果您尝试获取文件,那么您缺少的是set -a。例如,要获取 env.sh,您可以运行:

    set -a; source env.sh; set +a.
    

    你需要这个的原因是 bash 的变量是 bash 的本地变量,除非它们被导出。 -a 选项指示 bash 导出所有新变量(直到您使用 +a 将其关闭)。通过在source 之前使用set -asource 导入的所有变量也将被导出,从而可用于 python。

    信用:此命令来自@chepner 作为this answer 上的评论发布的评论。

    【讨论】:

      【解决方案5】:

      另外两个选项,可能对您的具体情况有所帮助,也可能无济于事:

      选项 1:

      如果 env.sh 仅包含常规 NAME=value,则让 python 读取它(作为文本文件)。

      这仅适用于您控制 env.sh 的格式,并且 env.sh 不包含任何真正的 shell 命令,并且您控制包含的 shell 脚本的情况。

      选项 2:

      在 shell 脚本中,一旦设置了所有必要的变量,要么将它们保存到文件中,要么将它们作为标准输入通过管道传输到你的 python 脚本:

      #!/bin/bash
      source env.sh
      
      echo $test1
      
      set | python pythontest.py
      

      #!/bin/bash
      source env.sh
      
      echo $test1
      
      set > /tmp/$$_env
      python pythontest.py --environment=/tmp/$$_env
      

      然后您可以读取文件(或标准输入),并将其解析为例如一本字典。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多