我正在努力从python程序执行shell脚本。实际的问题是该脚本是负载配置文件脚本,并以:
手动运行。 / path / to / file
该程序不能作为sh脚本运行,因为调用程序正在加载一些配置文件,因此必须以./path/to/file运行
[请指导如何将其集成到我的python脚本中。我正在使用subprocess.Popen命令来运行脚本,并且如上所述,它的唯一工作方式是运行为。 / path / to / file,因此无法给出正确的结果。
在不知道需要脚本来源的确切原因的情况下,这有点推测。
根本问题是:How do I get a source command to take effect outside the shell script?
假设您的源文件具有类似功能
export fnord="value"
这不能(有用地)在子shell中运行(就像正常执行的脚本一样),因为脚本终止时环境变量及其值将丢失。解决方案是从已经运行的shell中将该代码段source
(也称为.
);那么该值将保留在该shell的环境中,直到that shell终止。
但是Python不是外壳程序,并且没有通用的方法来执行任意外壳程序脚本代码,除非在Python中重新实现外壳程序。您可以使用[
重新实现外壳功能的一小部分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
对文件中允许的shell脚本语法有一些非常严格的限制(不用说天真的假设)。但是,如果文件包含一系列变量赋值之外的其他内容,或者该赋值中使用了除平凡的带引号的字符串之外的其他值,该怎么办? (甚至export
可能存在或不存在。其含义是使变量对当前Shell的子进程可见;也许是不需要或不需要的吗?而且export variable=value
不是可移植的;正确的Bourne Shell脚本语法会使用variable=value; export variable
或one of the many variations。)
如果您知道shell脚本究竟需要什么Python脚本,则可以执行类似的操作
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]
将整个脚本放在子外壳中,然后将实际需要的部分打印到标准输出,并从Python脚本中捕获(如果最终需要完成,则将其分配给环境变量)。