如何在没有任何shell脚本的情况下运行新进程并与之建立连接?

时间:2016-12-17 23:59:42

标签: python linux python-3.x

我的目的是创建一个其他程序的新进程,并与它建立一个长时间的连接(写入其stdin和读取结果的机会),即不是原子写 - 读操作,随后杀死创建的进程。我只能使用程序代码,而不是任何shell命令。

有我的代码:

import subprocess
proc = subprocess.Popen(['myprog', '-l'], shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
#proc was kept
#after some waiting I try to send to proc some command
if proc.returncode == None:
    proc.stdin.write(b'command')
    response = process.communicate()[0]

此代码返回空字符串(如果提交了一个事务)或者上升BrokenPipeError(如果它在循环中运行)。 在第一次process.communicate()之后,proc是否仍然存活?我需要用什么方法来控制proc的stdin / stdout?

1 个答案:

答案 0 :(得分:1)

您正在检查proc.returncode == None

但是,如果您阅读documentation of subprocess,则返回代码为0或负数,但绝不是None

  • 其次,如果你有长时间运行的进程,你应该调整并处理timeout,或者禁用它。

  • 第三:你真的应该真的避免在Popen shell=True,这是一个巨大的安全风险。

以下是我通常如何处理Popen的一些例子:

from shlex import split as sh_split
from subprocess import PIPE, Popen, TimeoutExpired


def launch(command, cwd=None, stdin=None, timeout=15):
    with Popen(
        sh_split(command), universal_newlines=True,
        cwd=cwd, stdout=PIPE, stderr=PIPE, stdin=PIPE
    ) as proc:
        try:
            out, err = proc.communicate(input=stdin, timeout=timeout)
        except TimeoutExpired:
            proc.kill()
            out, err = proc.communicate()
        return proc.returncode, out.splitlines(), err.splitlines()

这是为了简短的生活过程,但我希望你能看到如何处理stdin,stdout和stderr。