【问题标题】:Bash source in a python scriptPython 脚本中的 Bash 源代码
【发布时间】:2015-05-27 07:34:42
【问题描述】:

我正在编写一个包装 python 脚本,在运行其他一些工具之前需要 source ./config。排除我的脚本提供的额外功能,它基本上是这样做的:

$ source ./config
$ ./a-tool.sh --args
$ ./another-tool.py --arg1 --arg2

翻译成python,我可以做一些事情来调用这两个脚本:

subprocess.call(['./a-tool.sh', '--args'])
subprocess.call(['./another-tool.py', '--arg1', '--arg2'])

但我无法弄清楚如何首先使用工具的修改环境source。我读过Emulating Bash 'source' in Python,但它建议一些黑客修改运行脚本的环境,这不是我想要的。

编辑:

澄清一下,我的脚本目前是一个 bash 脚本,它执行一系列检查、解析一些参数,并根据结果运行一个或多个如上所述的工具。 source 行并不总是需要,并且并不总是相同的。但是,使用时,以下所有工具都需要在同一环境中运行(即bash进程)。在 bash 中,这很容易。但是,我想用 python 重写脚本,因为其他一些功能对我来说更容易在 python 中编写和维护。它纯粹是基于偏好的语言选择,与实际功能无关。根据@abarnert 的回答,我想我可以做类似的事情

subprocess.call(['source', '.config', ';', './a-tool.sh', ...])

这看起来并不容易调试,所以我更喜欢这样的东西:

bash = subprocess.run('bash')
bash.execute('source ./config')
bash.execute('a-tool.sh --args')

有没有办法在python中做到这一点?

【问题讨论】:

  • 有没有想过只写一个 bash 脚本然后执行你的 python 脚本?
  • 是的,这就是我开始的地方。但是还有很多其他的东西可以让完全用 python 编写更容易。例如。 source 仅在特定条件下实际运行。如果我找不到答案,我会将整个脚本留在 bash 中,但它很乱!

标签: python bash


【解决方案1】:

我同意 cmets 中的@Leon:切换谁执行什么的角色。

#!/bin/bash
source /my/conf.sh
python /my/script-1.py
python /my/script-2.py

来源的 bash 配置可以导出 ENV 变量,然后您可以从 python 中使用 os.environ[] 读取它们。

这是,AFAIK,接受的方法解决这些问题。

【讨论】:

    【解决方案2】:

    所有source 所做的只是在当前bash 解释器的上下文中运行脚本。

    Python 解释器不是 bash 解释器,所以你问的没有任何意义。*

    通常,所有source 用于影响环境变量,这就是those "hacks" you linked 正在做的事情。这并不是真正的黑客行为。它假设脚本除了设置环境变量之外没有任何影响——但这应该是一个很好的假设;如果不是,那么它所做的任何其他事情都是您在 Python 中无法做到的。

    或者,您可以创建一个bash 子进程,并将其用于source 脚​​本,然后运行其他程序,而不是将每个程序作为 Python 的子进程直接运行。 (无论是动态构建脚本,还是提供非 tty 标准输入。)这是唯一真正安全的方法来执行源脚本可能做的所有事情(因为它是实际获取脚本的唯一方法)。

    或者,作为一个稍微不同的技巧,将每个命令连接到您想要source 的脚本的末尾,并将其作为单独的bash 子进程运行。这通常会起作用,只要没有孩子试图改变他们父母环境或类似环境中的东西。


    *它可能bash作为父级......但它可能很容易没有......而且,即使它有,它仍然不会做你想要的,除非您唯一要做的就是影响环境变量。

    【讨论】:

    • 我认为你提到的第一个替代方案是我真正想要做的,即在同一个 bash 进程中运行所有命令。我无法控制 ./config 文件,所以我不想依赖它有任何特定的行为。
    【解决方案3】:

    我认为你实际上做不到。因为在 bash 中使用source somefile 时,somefile 将在与主脚本相同的进程中执行。因此,如果您将一些export 语句放在somefile 中,则环境变量将在主脚本中可用。

    但是,在您的情况下,python 将创建一个新进程(作为与当前 python 脚本对应的进程的子进程)并执行source 操作。之后,该过程将结束并被销毁。是的,source 操作已成功完成,但在子进程中。父进程中的环境变量在子进程中可用,反之则不行。

    您应该点击您在问题中提供的链接。在那个进程中,环境变量是在当前进程中创建的,即运行你的python脚本的进程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-01
      • 2022-06-29
      • 2013-04-07
      • 2018-03-10
      • 1970-01-01
      • 2018-11-30
      相关资源
      最近更新 更多