I'm writing a program which displays text on the terminal using Unix less(1). Here is the relevant portion:
less = subprocess.Popen(['less -F -'], stdin=subprocess.PIPE,
stdout=sys.stdout, shell=True)
try:
less.stdin.write(rfc_text)
less.stdin.flush()
less.stdin = sys.stdin
less.wait()
except IOError:
less.terminate()
return errno.EPIPE
except KeyboardInterrupt:
less.terminate()
return 0
While waiting for less to finish, I listen for the KeyboardInterrupt exception. If I catch one, I kill less with a SIGTERM signal, and exit my program.
Now, when that happens, I'm returned to my shell prompt, but the shell no longer echoes what I write and I have to do a reset(1) to make it work again.
Any ideas on how to make less die without taking my stdin with it into the grave? The full source is available on https://github.com/jforberg/rfc/blob/master/rfc.py
EDIT: After some experimenting, I have found out that both less(1) and man(1) by default ignore the control-C stroke. So simply ignoring it may be a viable option. I'm not sure I think it's the proper way to do it though, so if someone has suggestions I'm still very much interested.
The simplest way is to ask user to exit less
properly (by pressing q
):
#!/usr/bin/env python
from subprocess import PIPE, Popen
p = Popen(['less'], stdin=PIPE)
try:
p.communicate(''.join("%d\n" % i for i in range(1000)))
except KeyboardInterrupt:
print("Press `q` to exit.")
p.wait()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With