views:

89

answers:

2

In a basic Unix-shell app, how would you print to stdout without disturbing any pending user input.

e.g. Below is a simple Python app that echos user input. A thread running in the background prints a counter every 1 second.

import threading, time

class MyThread( threading.Thread ):
    running = False
    def run(self):
        self.running = True
        i = 0
        while self.running:
            i += 1
            time.sleep(1)
            print i

t = MyThread()
t.daemon = True
t.start()
try:
    while 1:
        inp = raw_input('command> ')
        print inp
finally:
    t.running = False

Note how the thread mangles the displayed user input as they type it (e.g. hell1o wo2rld3). How would you work around that, so that the shell writes a new line while preserving the line the user's currently typing on?

+2  A: 

You have to port your code to some way of controlling the terminal as slightly better than a teletype -- e.g. with the curses module in Python's standard library, or other ways to move the cursor away before emitting output, then move it back to where the user's busy inputting stuff.

Alex Martelli
A: 

You could defer writing output until just after you receive some input. For anything more advanced you'll have to use Alex's answer

import threading, time
output=[]
class MyThread( threading.Thread ):
    running = False
    def run(self):
        self.running = True
        i = 0
        while self.running:
            i += 1
            time.sleep(1)
            output.append(str(i))

t = MyThread()
t.daemon = True
t.start()
try:
    while 1:
        inp = raw_input('command> ')
        while output:
            print output.pop(0)
finally:
    t.running = False
gnibbler