Shell SIGKILL Keybinding

18

Comment puis-je configurer une liaison de touches pour envoyer un SIGKILLau travail de premier plan actuel? Je sais déjà que Ctrl+ Cest SIGINTet Ctrl+ \est SIGQUIT. Je voudrais une option plus sévère.

Y a-t-il quelque chose de sérieusement déconseillé à ce sujet?

drewrobb
la source
Il est envoyé par le pilote du terminal, pas par le shell (qui ignore totalement ce que vous faites avec le programme).
user1686
Vous n'avez pas noté le shell spécifié, qui est zsh, et le fait que la question parle de raccourcis clavier. C'est une question sur la configuration zshde l'éditeur de ligne, pas sur la configuration de son terminal.
JdeBP

Réponses:

26

Déconseillé ou non, il est en fait impossible:

Les raccourcis clavier Control + [?] Sont en fait gérés par le pilote tty et non par le shell, car tant qu'un processus s'exécute au premier plan, les entrées et sorties de votre terminal seront transmises directement au processus. Le shell ne pourrait jamais agir sur (ou même voir) vos touches.

Vous pouvez obtenir une liste des combinaisons de touches Ctrl + [?] Actuellement attribuées à partir de stty -a; cependant, seuls intr(SIGINT, généralement lié à Ctrl + C) quit(SIGQUIT, généralement lié à Ctrl + \) et susp(SIGSUSP, généralement lié à Ctrl + Z) correspondent aux signaux Unix réels. ( kill,par exemple, n'envoie pas SIGKILL, mais supprime l'entrée actuelle.)

Malheureusement, il n'y a aucun moyen d'envoyer l'un des deux signaux qui ne peuvent pas être désactivés par un processus (SIGKILL et SIGSTOP), donc si les trois signaux mentionnés n'ont aucun effet, vous devrez utiliser une autre méthode ( par exemple un autre shell) pour tuer le processus de premier plan.

(En fait, en plus de capturer les trois signaux, le processus de premier plan peut même désactiver les combinaisons de touches spéciales en premier lieu en définissant le tty en mode "brut". SSH le fait, par exemple - c'est ainsi qu'il peut relayer un Ctrl + C pressé localement sur l'hôte distant.)

lxgr
la source
3

Oui, il y a quelque chose de déconseillé. Vous sautez directement du SIGINTau SIGKILLsignal. Je suggère, comme le font d’autres personnes , d’envisagerSIGHUP ou les SIGTERMsignaux avant d'utiliser l'option nucléaire. Ensuite, il est déconseillé d'avoir ceci comme liaison de clé, ce qui signifie bien sûr que cela ne fonctionnera que lorsque ZLE est actif et que le shell vous invite de manière interactive à entrer, pas lorsque des commandes sont en cours d'exécution. (Pour cela, vous auriez besoin de configurer le terminal, et non pas la coquille, et le besoin d'avoir une discipline de ligne terminale qui met en œuvre l' envoi d' SIGTERMcomme une extension du comportement spécifié POSIX.)

Sur cette note, personne d'autre ne semble avoir encore remarqué que vous posez des questions sur les raccourcis clavier de l'éditeur de ligne shell, pas sur le terminal. Pour répondre à la première partie de votre question, alors:

Vous configurez une fonction shell pour envoyer le signal à la tâche "en cours".

function terminate-current-job() { kill -s TERM %+ ; }

Ensuite, vous construisez un widget défini par l'utilisateur ZLE qui appelle cette fonction shell.

zle -N terminate-current-job terminate-current-job

Enfin, vous liez ce widget à une clé de votre choix.

bindkey "^/" terminate-current-job
JdeBP
la source
1
Je suppose qu'il ne parle pas réellement de l'éditeur de ligne - s'il tape dans le shell, il n'y aurait pas de processus de premier plan en cours, non? Le shell ne verrait jamais réellement les touches si un processus de premier plan était en cours d'exécution et connecté au terminal actuel.
lxgr