【问题标题】:subprocess.communicate(input_string) still tries to read input from stdinsubprocess.communicate(input_string) 仍然尝试从标准输入读取输入
【发布时间】:2017-07-20 20:58:47
【问题描述】:

我正在尝试利用 python 子进程来运行带有输入的可执行二进制文件。

我的可执行文件将一个 JSON 对象作为输入并使用它来处理。如果您单独运行可执行文件,它将阻止等待来自标准输入的输入。

以下命令在终端上运行正常:

echo '{"values":{"value_1":"1122","value_2":"abcd"}}' | ../path/to/bin/executable-script -option1=x -topic my_kafka_topic

但我需要在我的 python 脚本中生成输入 JSON。所以我现在正在尝试这个:

import sys
import subprocess

if __name__ == '__main__':

    input_string = '{\"values\":{\"value_1\":\"1122\",\"value_2\":\"abcd\"}}'
    input_bytes = [elem.encode("hex") for elem in input_string]

    bashCommand = '../path/to/bin/executable-script -option1=x -topic my_kafka_topic'
    process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
    print 'program blocks on next line'
    data, error = process.communicate(input=input_bytes)
    print 'data is {}'.format(data)

不幸的是,我的程序不会在 python 脚本中运行,它只会阻止等待我输入输入。如果我输入输入它工作正常。

但我不希望它阻塞。我希望它像在命令行中一样运行。我该怎么做?

【问题讨论】:

  • 旁白:不要使用bashCommand.split()。将其指定为要开始的数组。否则,只要你想用文字空格指定文件名或其他输入,你就会遇到错误。
  • 如果您在没有任何外壳的情况下运行 bashCommand 名称,则会产生误导——这意味着如果添加到该行,像 2>err.log 这样的外壳语法将起作用,但这意味着完全错误。

标签: python unix subprocess


【解决方案1】:

将参数传递给process.communicate() 是正确的,但您还需要传递stdin=subprocess.PIPE。因此:

command = ['../path/to/bin/executable-script', '-option1=x', '-topic', 'my_kafka_topic']
process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
#                                   ^^^^^^^^^^^^^^^^^^^^^
process.communicate(input_data)

【讨论】: