从python程序执行概要文件装入shell脚本

从python程序执行概要文件装入shell脚本,python,shell,Python,Shell,我正在努力从Python程序执行shell脚本。实际问题是,该脚本是一个加载配置文件脚本,并以以下方式手动运行: /路径/到/文件 程序不能作为sh脚本运行,因为调用程序正在加载一些配置文件,因此必须作为运行/路径/到/文件 请指导我如何在Python脚本中集成相同的内容?我正在使用subprocess.Popen命令来运行脚本,正如前面所说,它工作的唯一方法是以的形式运行/path/to/file,因此没有给出正确的结果。在不知道脚本需要来源的确切原因的情况下,这有点推测性 根本问题是: 假

我正在努力从Python程序执行shell脚本。实际问题是,该脚本是一个加载配置文件脚本,并以以下方式手动运行:

/路径/到/文件
程序不能作为
sh
脚本运行,因为调用程序正在加载一些配置文件,因此必须作为
运行/路径/到/文件


请指导我如何在Python脚本中集成相同的内容?我正在使用
subprocess.Popen
命令来运行脚本,正如前面所说,它工作的唯一方法是以
的形式运行/path/to/file
,因此没有给出正确的结果。

在不知道脚本需要来源的确切原因的情况下,这有点推测性

根本问题是:

假设您的源文件执行以下操作:

export fnord="value"
with open('/path/to/file') as shell_source:
     lines = shell_source.readlines()
for line in lines:
    if line.strip().startswith('export '):
        var, value = line[7:].strip().split('=', 1)
        if value.startswith('"'):
            value = value.strip('"')
        elif value.startswith("'"):
            value = value.strip("'")
     os.environ[var] = value
r = subprocess.run('. /path/to/file; printf "%s\n" "$somevariable"',
    shell=True, capture_output=True, text=True)
os.environ['somevariable'] = r.stdout.split('\n')[-2]
这不能(有效地)在子shell中运行(就像正常执行的脚本那样),因为当脚本终止时,环境变量及其值将丢失。解决方案是
从已经运行的shell中获取这个代码片段;然后,该值将保留在该shell的环境中,直到该shell终止

但是Python不是shell,并且除了用Python重新实现shell之外,Python没有执行任意shell脚本代码的通用方法。您可以通过以下方式重新实现shell功能的一小部分

export fnord="value"
with open('/path/to/file') as shell_source:
     lines = shell_source.readlines()
for line in lines:
    if line.strip().startswith('export '):
        var, value = line[7:].strip().split('=', 1)
        if value.startswith('"'):
            value = value.strip('"')
        elif value.startswith("'"):
            value = value.strip("'")
     os.environ[var] = value
r = subprocess.run('. /path/to/file; printf "%s\n" "$somevariable"',
    shell=True, capture_output=True, text=True)
os.environ['somevariable'] = r.stdout.split('\n')[-2]
对文件中允许的shell脚本语法有一些非常严格的限制(不要说天真的假设)。但是,如果文件中包含的不是一系列变量赋值,或者赋值中使用的不是简单的带引号的字符串,该怎么办?(甚至
export
也可能存在,也可能不存在。它的意义在于使变量对当前shell的子进程可见;这可能不是想要的或必需的?而且
export variable=value
不可移植;正确的Bourne shell脚本语法将使用
variable=value;export variable
或。)

如果您知道您的Python脚本需要从shell脚本中得到什么,可以执行以下操作

export fnord="value"
with open('/path/to/file') as shell_source:
     lines = shell_source.readlines()
for line in lines:
    if line.strip().startswith('export '):
        var, value = line[7:].strip().split('=', 1)
        if value.startswith('"'):
            value = value.strip('"')
        elif value.startswith("'"):
            value = value.strip("'")
     os.environ[var] = value
r = subprocess.run('. /path/to/file; printf "%s\n" "$somevariable"',
    shell=True, capture_output=True, text=True)
os.environ['somevariable'] = r.stdout.split('\n')[-2]

要在子shell中获取整个脚本的源代码,然后将实际需要的部分打印到标准输出,并从Python脚本中捕获该部分(如果最终需要完成此任务,则将其分配给环境变量)。

如果要求作为shell脚本运行,实际上,没有一种明智的方法可以直接从Python运行脚本。源代码脚本的要求意味着它希望与shell交互。(您名义上可以运行shell并从中获取脚本的源代码,但是一旦shell退出,效果就会消失,因此您可以完全排除Python。)相关:您需要了解
是什么/路径/到/文件
表示。首先阅读
help source
。如果可以的话,您希望避免
Popen
。见例。