【问题标题】:Linux shell source command equivalent in python [duplicate]python中等效的Linux shell源命令[重复]
【发布时间】:2013-03-07 16:20:55
【问题描述】:

将 shell 脚本转换为 python 并尝试找到执行以下操作的最佳方法。我需要它,因为它包含我需要阅读的环境变量。

if [ -e "/etc/rc.platform" ];
then
    . "/etc/rc.platform"
fi

我已经转换了 'if' 但不确定如何处理 . "/etc/rc.platform" 作为源是一个 shell 命令。到目前为止,我有以下内容

if os.path.isfile("/etc/rc.platform"):
    print "exists" <just to verify the if if working>
    <what goes here to replace "source /etc/rc.platform"?>

我查看了 subprocess 和 execfile 没有成功。

python 脚本需要访问 rc.platform 设置的环境变量

【问题讨论】:

  • 您必须解析/etc/rc.platform,提取环境变量名称和值,并相应地更新os.environ
  • @crazyeewulf - 这不仅仅是关于环境变量,还可能有脚本可以导出的 bash 函数。你打算如何从 python 脚本中使用它们,除非你以某种方式尝试为所有被调用的脚本重用相同的 shell。
  • 我建议也将/etc/rc.platform 移植到Python,因为.import 非常相似。
  • 如果你想用python重写脚本,那么你很可能想用python重写/etc/rc.platform。如果只是进行变量赋值,则可以将其设为配置文件。在一般情况下,您尝试做的事情很困难。
  • @Tuxdude 对于一般情况,您是正确的。但是 OP 在问题中提到“我需要这个,因为它包含我需要读取的环境变量”。所以我预计 OP 可能不关心此文件中的环境变量以外的任何内容。

标签: python shell


【解决方案1】:

一个有点老套的解决方案是解析env 输出:

newenv = {}
for line in os.popen('. /etc/rc.platform >&/dev/null; env'):
    try:
        k,v = line.strip().split('=',1)
    except:
        continue  # bad line format, skip it
    newenv[k] = v
os.environ.update(newenv)

编辑:固定拆分参数,感谢@l4mpi

【讨论】:

    【解决方案2】:

    (这是他评论中描述的解决方案 crayzeewulf 的演示。)

    如果/etc/rc.platform 仅包含环境变量,您可以读取它们并将它们设置为 Python 进程的环境变量。

    鉴于此文件:

    $ cat /etc/rc.platform
    FOO=bar
    BAZ=123
    

    读取和设置环境变量:

    >>> import os
    >>> with open('/etc/rc.platform') as f:
    ...     for line in f:
    ...         k, v = line.split('=')
    ...         os.environ[k] = v.strip()
    ... 
    >>> os.environ['FOO']
    'bar'
    >>> os.environ['BAZ']
    '123'
    

    【讨论】:

    • 如果变量在其声明中引用了其他变量,这将不起作用,例如X="$Y/foo"。此外,该脚本可以使用其他 shell 命令(如 awk、grep 等)或内置 shell 变量,这些显然不会被评估。
    • 好点。我想这里的共识是,除了我用作示例的最简单的情况外,没有简单的方法可以使其工作。
    • 我曾经需要类似的东西,结果生成了一个子shell,获取脚本,然后解析env的输出......也许我会在晚饭后写一个答案。
    【解决方案3】:

    返回的工作量太大。打算保留一个小的 shell 脚本来获取我们需要的所有环境变量,而忘记将它们读入 python。

    【讨论】:

      【解决方案4】:

      试试这个:

      if os.path.exists ("/etc/rc.platform"):
          os.system("/etc/rc.platform")
      

      【讨论】:

      • 这不会和OP引用的shell脚本效果一样。 os.system 在子shell 中运行命令,因此,父进程将看不到/etc/rc.platform 添加/修改的任何环境变量。
      • 您不能在不知道如何解释 bash 语言的 python 进程中获取 sh 或 bash 脚本。因此,您需要一个子shell 来运行 bash 并解释脚本。由于它是在子shell中完成的,python进程将无法获取新的env值。
      【解决方案5】:

      由于source是内置的shell,所以在调用subprocess.call时需要设置shell=True

      >>> import os
      >>> import subprocess
      >>> if os.path.isfile("/etc/rc.platform"):
      ...     subprocess.call("source /etc/rc.platform", shell=True)
      

      我不确定你想在这里做什么,但我还是想提一下:/etc/rc.platform 可能会导出一些 shell 函数供rc.d 中的其他脚本使用。由于这些是 shell 函数,它们将仅导出到 subprocess.call() 调用的 shell 实例,如果您调用另一个 subprocess.call(),这些函数将不可用,因为您正在生成一个新的 shell 来调用新脚本。

      【讨论】:

      • 如果您在子shell 中运行脚本,这将无济于事,因为所有环境变量设置都将被丢弃。
      • @grep - 我知道,它不仅与环境变量有关,甚至由/etc/rc/platform 导出的 bash 函数也无法用于 python 脚本,并且任何新的 shell 开始调用其他来自say /etc/rc.d 的相关脚本
      猜你喜欢
      • 1970-01-01
      • 2014-08-05
      • 1970-01-01
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 2015-01-29
      • 2013-12-25
      相关资源
      最近更新 更多