问题
I am trying to stream the output of xinput into my python program, however my program just waits and stays blank. I think it may have something to do with buffering but I cannot say. Running xinput test 15
gives me my mouse movements, but doing this will not print it. By the way, to find out your mouseid just type xinput
and it will list your devices.
#!/usr/bin/env python
import sys
import subprocess
# connect to mouse
g = subprocess.Popen(["xinput", "test", str(mouse_id)], stdout=subprocess.PIPE)
for line in g.stdout:
print(line)
sys.stdout.flush()
回答1:
Your code works for me; however it looks like the xinput
cmd buffers its output if not connected to a tty. When running your code, keep moving the mouse and eventually xinput
should flush stdout and you'll see your lines show up in chunks... at least i did when running your code.
I re-wrote your code to eliminate buffering, but I couldn't get it to not come out in chunks, hence why I believe xinput
is to blame. When not connected to a TTY, it doesn't flush the stdout buffer with each new event. This can be verified with xinput test 15 | cat
. Moving your mouse will cause the data to print in buffered chunks; just like your code.
My test code is below if helpful
#!/usr/bin/python -u
# the -u flag makes python not buffer stdios
import os
from subprocess import Popen
_read, _write = os.pipe()
# I tried os.fork() to see if buffering was happening
# in subprocess, but it isn't
#if not os.fork():
# os.close(_read)
# os.close(1) # stdout
# os.dup2(_write, 1)
#
# os.execlp('xinput', 'xinput', 'test', '11')
# os._exit(0) # Should never get eval'd
write_fd = os.fdopen(_write, 'w', 0)
proc = Popen(['xinput', 'test', '11'], stdout = write_fd)
os.close(_write)
# when using os.read() there is no readline method
# i made a generator
def read_line():
line = []
while True:
c = os.read(_read, 1)
if not c: raise StopIteration
if c == '\n':
yield "".join(line)
line = []
continue
line += c
readline = read_line()
for each in readline:
print each
回答2:
Take a look at sh, specifically this tutorial http://amoffat.github.com/sh/tutorials/1-real_time_output.html
import sh
for line in sh.xinput("test", mouse_id, _iter=True):
print(line)
来源:https://stackoverflow.com/questions/12420999/reading-stdout-from-xinput-test-in-python