hcitool lescan子进程python不产生输出

时间:2013-09-04 12:18:39

标签: python subprocess

我遇到子流程代码问题。 subprocess.Popen()工作正常,但当我尝试通过stdout.read()读取其输出时,没有值可读。

**import os
import signal
import subprocess
import threading
import sys
import commands

print commands.getoutput("hcitool dev")
print 'down'
commands.getoutput('hciconfig hci1 down')
print 'up'
commands.getoutput('hciconfig hci1 up')
commands.getoutput('killall hcitool')
stop = False
ping = subprocess.call('hcitool lescan', shell = False,
stdout=subprocess.PIPE,executable='/bin/bash')
for i in ping.stdout:
    print i

def kill():
    global stop
    stop = True
    os.kill(ping.pid, signal.SIGTERM)

threading.Timer(5, kill).start()

#while not stop:
#   print 'now in while not loop'
#   sys.stdout.write(ping.stdout.read(1))

print 'trying to print stdout'
out, err = ping.communicate()
print "out",out

#result = out.decode()

print "Result : ",result**

当我将hcitool lescan更改为ping www.google.com并生成输出时,此代码正常工作,但当我尝试使用hcitool lescan时,它会永久挂起或不产生输出。感谢帮助!

4 个答案:

答案 0 :(得分:5)

上述任何一个答案对我都没有用。挂在hcitool的永远扫描。最后我写了一个shell脚本并用我的python代码调用它。这对我来说很好,我正在读取文件" result.txt"的输出。

hcitool lescan>result.txt &  
sleep 5  
pkill --signal SIGINT hcitool

答案 1 :(得分:0)

您的代码中存在多个错误,例如subprocess.call()返回一个整数(程序的退出状态),整数没有.stdout属性;此外,shell=False和非 - 无executable的组合很少有用(在这种情况下可能使用不正确)。

修复代码的最简单方法是使用check_output()

from subprocess import check_output as qx

output = qx(["hcitool", "lescan"]) # get all output at once
print output,

作为替代方案,您可以在刷新标准输出后立即逐行打印程序的输出:

from subprocess import Popen, PIPE

proc = Popen(["hcitool", "lescan"], stdout=PIPE, bufsize=1) # start process
for line in iter(proc.stdout.readline, b''): # read output line-by-line
    print line,
# reached EOF, nothing more to read
proc.communicate() # close `proc.stdout`, wait for child process to terminate
print "Exit status", proc.returncode

要杀死子进程,您可以使用其.kill()方法,例如:

from threading import Timer

def kill(process):
    try:
        process.kill()
        process.wait() # to avoid zombies
    except OSError: # ignore errors
        pass 

Timer(5, kill, [proc]).start() # kill in 5 seconds

答案 2 :(得分:0)

非常感谢..但问题是hcitool lescan永远不会停止,因此会在代码的下一行中挂起。 我在这里发现了类似的解决方案。这个工作正常,我没有必要杀死子进程,这段代码需要一些额外的时间来输出输出,但是下面这段代码很有效,

from os import kill
import signal
import subprocess
import threading
import tempfile
import sys
import time
from tempfile import TemporaryFile
import commands
t = TemporaryFile()
global pipe_output
print commands.getoutput("hcitool dev")
print 'down'
commands.getoutput('hciconfig hci0 down')
print 'up'
commands.getoutput('hciconfig hci0 up')
print commands.getoutput("hcitool dev")
commands.getoutput('killall hcitool')
p = subprocess.Popen('hcitool lescan', bufsize = 0,shell = True, stdout =subprocess.PIPE,stderr = subprocess.STDOUT)
time.sleep(10)
#os.kill(p.pid,signal.SIGTERM)
for i in range(0,30,1):
    print 'for'
    inchar = p.stdout.readline()
    i+=1
    if inchar:
        print 'loop num:',i
        print str(inchar)
        t.write(str(inchar))
print 'out of loop'
t.seek(0)
print t.read()

任何帮助如何减少等待时间,除了更改time.sleep(),表示赞赏 谢谢大家

答案 3 :(得分:0)

使用Popen类而不是调用类。 hcitool lescan将永远运行。 subprocess.call等待调用完成返回。 Popen不等。