Le Ctrl+\
qui a été mentionné est interprété par votre logiciel de terminal et la liaison de clé est configurée via stty
. Sauf si vous avez un moyen de personnaliser votre logiciel de terminal, vous ne pourrez utiliser que les quelques signaux déjà intégrés.
Selon la fonctionnalité dont vous avez besoin ou la distance que vous souhaitez prendre, une autre option est écrire votre propre "terminal d'exécution de processus". Il s'agit d'un script qui exécute une application pour vous et place votre terminal en mode brut afin qu'il puisse traiter les frappes qui exécutent des actions personnalisées. Ci-dessous, un exemple simplifié qui montre ce que je veux dire. Vous pouvez également faire quelque chose de similaire via curses ou urwid si vous le souhaitez.
Pour gérer la sortie de processus, vous aurez besoin de capturer le stdout/stderr
de et l'afficher bien à l'écran, en utilisant si vous manipulez le terminal manuellement ou à l'aide d'un widget urwid pour afficher la sortie dans une fenêtre de défilement, etc. La même idée s'appliquerait également aux autres systèmes GUI (wx, tkinter, etc.) mais le contrôle terminal a été mentionné.
Voici term.py
qui met en oeuvre un interprète terminal première de base:
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()
est ici un simple script target.py
pour faire tourner et imprimer les signaux qu'il reçoit:
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)
Exemple d'utilisation:
% 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' est toujours vrai. – delnan
sur quelle plateforme? le signal de support sur Windows manque beaucoup de signaux ... –
Son tagged, linux. – Nix