连续从python的子进程调用shell命令并解析输出

时间:2018-08-30 16:39:53

标签: python python-3.x subprocess

我正在开发一个嵌入式应用程序,该应用程序使用了CANBOAT存储库中的一些预编译的二进制文件。

有两种二进制文件可供使用:

  1. actisense-serial
  2. analyzer

在外壳中,需要执行actisense -r /dev/ttyUSB0 | analyzer -json才能从连接到USB端口的设备获取信息。上面提到的命令将JSON信息转储到STDOUT。

示例输出:

{"timestamp":"2018-08-30T16:27:23.629Z","prio":2,"src":3,"dst":255,"pgn":128259,"description":"Speed","fields":{"SID":106,"Speed Water Referenced Type":"Paddle wheel"}}

{"timestamp":"2018-08-30T16:27:23.629Z","prio":2,"src":6,"dst":255,"pgn":128259,"description":"Speed","fields":{"SID":106,"Speed Water Referenced Type":"Paddle wheel"}}

上述值始终显示在STDOUT上。

我希望在python脚本中使用上述shell命令来获取JSON值,以对其进行解析并将其保存到数据库中。

最初,我想从subprocess.check_output开始。

我尝试过:

import subprocess

if __name_ == "__main__":

     while True:
         value = subprocess.check_output(['actisense-serial -r /ttyUSB0',
                                           '|',
                                           'analyzer -json'],
                                        shell=True)
         print(value)

但是没有可用的输出。我不确定如何将STDOUT的输出路由到check_output

如何实现此目的,可以解析来自shell命令的连续JSON信息并在应用程序中进一步使用?

1 个答案:

答案 0 :(得分:1)

使用stdout时,您可以将管道传递到stderrPopen

actisense_proc = subprocess.Popen(['actisense-serial', '-r', '/ttyUSB0'], 
                                  stdout=subprocess.PIPE)
analyzer_proc = subprocess.Popen(['analyzer', '-json'], stdin=actisense_proc.stdout,
                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while analyzer_proc.poll() is None:
    print(analyzer_proc.stdout.readline())

还要注意,我没有使用shell=True,而是使用了两个Popen调用,并将第一个的stdout通过管道传递到第二个的stdin

编辑:错过了问题的流式传输部分。已更新,因此它将不断从stdout管道读取。这将一直运行直到子进程终止。