我正在尝试编写一个脚本,它必须对一些bash命令进行大量调用,解析并处理输出,最后给出一些输出。
我使用的是subprocess.Popen和subprocess.call
如果我理解正确这些方法产生一个bah进程,运行命令,获取输出然后终止进程。
有没有办法让bash进程在后台连续运行,然后python调用可以直接进入该进程?这就像bash作为服务器运行而python调用它。
我觉得这会优化调用,因为没有bash进程设置和拆卸。或者它不会带来性能优势?
答案 0 :(得分:4)
我认为这会优化调用,因为没有bash进程设置和拆卸。
subprocess
永远不会运行shell,除非您明确询问它,例如
#!/usr/bin/env python
import subprocess
subprocess.check_call(['ls', '-l'])
此调用在不调用ls
的情况下运行/bin/sh
程序。
或者它不会带来任何性能优势?
如果您的子进程调用实际上使用了shell,例如specify a pipeline consicely,或者您使用bash process substitution可能是冗长且容易出错的,直接使用subprocess
模块定义然后它调用bash
是性能瓶颈不太可能 - 首先测量它。
有些Python包也允许指定这些命令,例如plumbum
could be used to emulate a shell pipeline。
如果要将bash
用作服务器进程,则pexpect
对于与外部进程的基于对话的交互非常有用 - 尽管它不太可能影响时间性能。 fabric
允许运行本地和远程命令(ssh
)。
还有其他子进程包装器,例如sarge
,它可以解析字符串中指定的管道而不调用shell,例如,它启用cross-platform support for bash-like syntax (&&
, ||
, &
in command lines)或sh
- 一个完整的{{1}在Unix上提供默认情况下提供TTY的替换(看起来功能齐全但the shell-like piping is less straightforward)。您甚至可以使用Python-ish BASHwards外观语法来运行带有xonsh
shell的命令。
同样,在大多数情况下,它不太可能以有意义的方式影响性能。
以可移植的方式启动和与外部进程通信的问题很复杂 - 进程,管道,ttys,信号,线程,异步之间的交互。 IO,在各个地方缓冲都有粗糙的边缘。如果您不知道特定包如何解决与运行shell命令相关的许多问题,那么引入新包可能会使事情变得复杂。
答案 1 :(得分:1)
如果我理解正确这些方法产生一个bah进程,运行命令,获取输出然后终止进程。
Object.defineProperty(Item.prototype, 'id', {
get: function () {
return this.id;
},
set: function (value) {
if (!isNaN(value)) { // just an example to add some logic
throw Error('Item.id must be a number!');
}
this.id = value;
}
});
涉及更多一点。它实际上创建了一个I / O线程来避免死锁。见https://www.python.org/dev/peps/pep-0324/:
subprocess.Popen
方法,可以轻松发送communicate()
数据并阅读stdin
和stdout
数据,而不会有死锁的风险。大多数人都知道与子进程通信有关的流控制问题,但并非所有人都有耐心或技巧来编写完全正确且无死锁的选择循环。这意味着许多Python应用程序包含竞争条件。标准库中的stderr
方法解决了这个问题。
有没有办法让bash进程在后台持续运行,然后python调用可以直接进入该进程?
当然,你仍然可以使用communicate()
并向你的子进程发送消息并在不终止子进程的情况下接收消息。在最简单的情况下,您的消息可以是行。
当子进程可以在感兴趣的事件发生时继续向您发送消息时,这允许请求 - 响应样式协议以及发布 - 订阅。