Reading stdout from xinput test in python

被刻印的时光 ゝ 提交于 2019-12-11 06:51:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!