1

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()    
3
  • 1
    Are there any linebreaks in the output? What happens if you terminate the subprocess after a while? Does flushing g.stdout have an effect? Commented Sep 14, 2012 at 12:38
  • xinput test returns a new line for each event, And for terminate it just gives keyboardinterrupt Aha, I think your change to g.stdout.flush() had an effect. It now outputs, wooha! Commented Sep 14, 2012 at 13:10
  • The only issue now is that it takes quite a few seconds to flush, meaning for testing I have to acquire hundreds if not thousands of lines until they all dump at once. Is there anyway to force immediate dump as soon as I can get it (there is no delay when command is run from console) Commented Sep 14, 2012 at 13:32

2 Answers 2

3

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)
Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.