El Ctrl+\
que se ha mencionado es interpretado por el software de su terminal, y la vinculación de la clave se configura a través del stty
. A menos que tenga alguna forma de personalizar el software de su terminal, solo podrá usar las pocas señales que ya están integradas.
Dependiendo de la cantidad de funcionalidad que necesite o de la distancia que desee tomar, otra opción es para escribir su propio "terminal de ejecución de proceso" simple. Esta sería una secuencia de comandos que ejecuta una aplicación para usted y coloca su terminal en modo raw para que pueda procesar las pulsaciones de teclas que realizan acciones personalizadas.
A continuación se muestra un ejemplo simplificado que muestra lo que quiero decir. También puede hacer algo similar a través de curses o urwid si lo desea.
Manejar salida del proceso que había necesidad de capturar el stdout/stderr
de y mostrarlo adecuadamente a la pantalla, usando si está manipulando el terminal manualmente, o usando un widget de urwid para mostrar el resultado en una ventana de desplazamiento, etc. La misma idea también se extendería a otros sistemas GUI (wx, tkinter, etc.) pero se mencionó el control terminal.
Aquí es term.py
que implementa un intérprete de terminal prima básica:
import os, signal, subprocess, sys, tty, termios
sigmap = {
'\x15': signal.SIGUSR1, # ctrl-u
'\x1c': signal.SIGQUIT, # ctrl-\
'\x08': signal.SIGHUP, # ctrl-h
'\x09': signal.SIGINT, # ctrl-i
}
# setup tty
fd = sys.stdin.fileno()
old_tc = termios.tcgetattr(fd)
tty.setraw(fd)
# spawn command as a child proc
cmd = sys.argv[1:]
proc = subprocess.Popen(cmd)
while 1:
try:
ch = sys.stdin.read(1)
# example of ansi escape to move cursor down and to column 0
print '\033[1Eyou entered', repr(ch)
if ch == 'q':
break
signum = sigmap.get(ch)
if signum:
os.kill(proc.pid, signum)
finally:
pass
termios.tcsetattr(fd, termios.TCSANOW, old_tc)
sys.exit()
Aquí es un simple script target.py
a girar e imprimir las señales que recibe: ejemplo
import signal, sys, time
def handler(num, _):
print 'got:', sigmap.get(num, '<other>')
if num == signal.SIGINT:
sys.exit(1)
return 1
signames = ['SIGINT','SIGHUP','SIGQUIT','SIGUSR1']
sigmap = dict((getattr(signal, k), k) for k in signames)
for name in signames:
signal.signal(getattr(signal, name), handler)
while 1:
time.sleep(1)
Uso:
% python term.py python target.py
you entered 'h'
you entered 'i'
you entered '\x1c'
got: SIGQUIT
you entered '\x15'
got: SIGUSR1
you entered '\x08'
got: SIGHUP
you entered '\t'
got: SIGINT
you entered 'q'
'2' es siempre cierto. – delnan
en qué plataforma? soporte de señal en Windows le faltan muchas señales ... –
Está etiquetado, linux. – Nix