【问题标题】:Execute bash commands in the same process in python在python的同一进程中执行bash命令
【发布时间】:2017-05-03 21:05:43
【问题描述】:

我需要在 python 脚本上运行一个大型构建脚本(bash 命令)。我将它作为一个大字符串接收,并且每一行都由 \n 分隔。所以,我需要分别执行每一行。

起初,我尝试使用subprocess.Popen() 来执行它们。但问题是:在每一行之后,进程都会终止并且所有的环境变量都丢失了。

问题不是等待一个命令完成再执行另一个命令,我需要它们都在同一个 shell 上执行。

目前我发现的唯一解决方案是将所有这些命令保存为 sh 文件(例如 build.sh)并在 python 上执行。

我不想使用这种方法,因为我想对每次执行有更多的控制权。

有没有办法在同一个进程上,一个一个地执行这些命令?

任何其他解决方案也不错。

【问题讨论】:

  • 您可以使用subprocess.Popen() 启动一个shell,然后将命令提供给它的标准输入。
  • @jasonharper 你的意思是从 Popen 获取输出并直接添加到另一个 Popen 作为标准输入?但是环境变量呢?我怎样才能保留它们?
  • 只有一个Popen,可能运行“/bin/sh”。一个接一个地给它你的命令;相同的 shell 仍在运行,因此它将保持其环境变量。

标签: python python-2.7 subprocess


【解决方案1】:

你想要的肯定有点奇怪,但使用管道是可能的。

from subprocess import PIPE, Popen

p = Popen(['bash'], stdin=PIPE, stdout=PIPE)
p.stdin.write('echo hello world\n')
print(p.stdout.readline())
# Check a return code
p.stdin.write('echo $?\n')
if p.stdout.readline().strip() ⩵ '0':
    print("Command succeeded")
p.stdin.write('echo bye world\n')
# Close input and wait for bash to exit
stdout, stderr = p.communicate()
print(stdout)

【讨论】:

  • 您可能需要flush stdout 以确保其正常工作并强制bash 无缓冲运行,否则您将死锁;即使那样,它也会很脆弱。您可能需要使用select 模块和/或线程来确保没有死锁,或者使用第三方pexpect 模块进行更多可定制的控制。
【解决方案2】:

当调用一个shell时,操作系统会启动一个新进程,除非你在python中有一个shell解释器。

在同一个过程中唯一的可能是直接用python模拟所有步骤。

更好的方法是接受限制,自己调用外部进程并等待脚本终止受控。例子是例如这里:python to wait for shell command to complete

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多