【问题标题】:How can I put result from rfcomm shell command in to a variable in python?如何将 rfcomm shell 命令的结果放入 python 中的变量中?
【发布时间】:2018-12-21 20:07:42
【问题描述】:

我在python中使用这个脚本来连接蓝牙设备然后获取数据,但是我想知道这个shell命令的结果以便做下一步工作

import os
import time
import signal
import subprocess


p = subprocess.Popen("sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1",shell=True)
(stderr,stdout) = p.communicate()
print 'stderr: [%s]' % stderr
print 'stdout: [%s]' % stdout
time.sleep(5)
while True:
     print "Device is ready"
     time.sleep(5)

此代码是我运行命令时的示例:

"sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1" 

在shell中,它返回:

Connected /dev/rfcomm0 to XX:XX:XX:XX:XX:XX on channel 1
Press CTRL-C for hangup

但是我怎样才能把上面的结果放在一个变量中,因为我需要知道这个命令的结果? 我在子进程中使用 stdout、stderr 但不起作用。 我正在使用 python 2.7

Python subprocess and user interaction

link 上面讨论了在一般变量中获取输出,但我的问题中与 rfcomm 相关的问题,它没有将其结果放入变量中,我运行这些脚本并且它们运行良好,但它不起作用当它与 rfcomm 命令一起使用时

【问题讨论】:

标签: python variables subprocess rfcomm


【解决方案1】:

如果您使用的是 Python 3.5 或更高版本, 您可以改用run。这样你就可以直接访问了,

result = subprocess.run(["sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1"], stdout=subprocess.PIPE)

然后像这样访问你想要的,

result.stdout

如果您使用 Python 2.7,正如我链接的文档所建议的那样,他们会将您重定向到 Older high-level API 部分。 从那里你会注意到你可以使用check_output

result = subprocess.check_output(["sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1"])

注意,如果您想捕获错误,也请使用 stderr=subprocess.STDOUT 标志。

result = subprocess.check_output("sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1", stderr=subprocess.STDOUT, shell=True)

最后,有一个重要的事情你不应该知道,

默认情况下,此函数会将数据作为编码字节返回。输出数据的实际编码可能取决于被调用的命令,因此通常需要在应用程序级别处理对文本的解码。

编辑

因为您的目标似乎是在运行时获得输出。看看这个answer。我更喜欢链接而不是重新发明轮子。

【讨论】:

  • 其实我用的是python 2.7
  • runcheck_output 只会在 rfcomm 完成时完成。我的印象是 OP 希望进程保持运行并与之交互。
  • @tripleee 是的,我现在看到了。谢谢你的洞察力。我在编辑中链接了一个解决方案。
  • 确实如此,但正确的做法是将此问题指定为重复问题。
【解决方案2】:

您可能需要在返回数据之前发出 CTRL+C 命令。

发送信号并捕获异常以处理返回的内容。

import os
import time
import signal
import subprocess


stream = []
try:
    p = subprocess.Popen("sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1",shell=True)
    #(stderr, stdout) = p.communicate()

    #print 'stderr: [%s]' % stderr
    #print 'stdout: [%s]' % stdout
    #time.sleep(5)
    #print "Device is ready"

    time.sleep(5)

    os.kill(p.pid, signal.CTRL_C_EVENT)
    p.wait()

except KeyboardInterrupt:                
#except Exception: 
    for line in p.stdout: #May also be p.stderr
        stream.append(line)                         

    for x in stream:                    
        print(x)

【讨论】:

  • 我运行你的代码,但是使用这个脚本,它会在“Connected /dev/rfcomm0 to 00:13:EF:C0:01:79 on channel 1 Press CTRL-C for hangup”之后等待不会转到“设备准备就绪”命令等。
  • 你把while循环去掉了吗?
  • 我完全运行你的代码,它在运行 "p = subprocess.Popen("sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1",shell=True )" 它返回 Connected /dev/rfcomm0 to 00:13:EF:C0:01:79 on channel 1 Press CTRL-C for hangup" 并等待无限
  • 如果你把p.wait()的线拿出来会怎样?
  • 我取出了那条线,但没有发生。和以前一样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 2021-11-29
  • 1970-01-01
  • 2022-10-19
  • 1970-01-01
相关资源
最近更新 更多