从Python的subprocess中持续调用shell命令并解析输出。

17 浏览
0 Comments

从Python的subprocess中持续调用shell命令并解析输出。

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

有两个可用于使用的二进制文件:

  1. actisense-serial
  2. analyzer

在shell中,需要执行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信息可以被解析并在应用程序中进一步使用?

0
0 Comments

问题的原因是原始代码使用了communicate()方法来获取输出,这个方法会一次性获取所有输出内容,而不是连续地读取输出流。因此,代码需要修改为使用readline()方法来连续读取输出流。

解决方法是使用Popenstdout参数和stdin参数来设置输出和输入的管道。通过将第一个进程的stdout管道传递给第二个进程的stdin管道,实现了连续地读取输出流。

下面是修改后的代码:

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调用,并将第一个进程的输出流传递给第二个进程的输入流。

参考链接:stackoverflow.com/questions/10405515/…

0