Shell SIGKILL Keybinding
Unadvisable or not, it is actually impossible:
The Ctrl+[?] keybindings are actually handled by the tty driver and not by the shell, because as long as there is a process running in the foreground, input and output of your terminal will be forwarded directly to the process. The shell would never be able to act upon (or even see) your keypresses.
You can get a list of the currently assigned Ctrl+[?] key combinations from stty -a
; however, only intr
(SIGINT, usually bound to Ctrl+C) quit
(SIGQUIT, usually bound to Ctrl+\) and susp
(SIGSUSP, usually bound to Ctrl+Z) correspond to actual unix signals. (kill
, for example, doesn't send SIGKILL, but deletes the current input.)
Unfortunately, there is no way to send one of the two signals that can't be disabled by a process (SIGKILL and SIGSTOP), so if all of the three mentioned signals have no effect, you'll have to use some other way (e.g. another shell) to kill the foreground process.
(Actually, in addition to catching all of the three signals, the foreground process can even disable the special key combinations in the first place by setting the tty to "raw" mode. SSH does this, for example – this is how it can relay a locally pressed Ctrl+C to the remote host.)
Yes, there's something inadvisable. You're leaping directly from the SIGINT
to the SIGKILL
signal. I suggest, as other people do, looking at sending the SIGHUP
or SIGTERM
signals before employing the nuclear option. Then there's the inadvisability of having this as a key binding, which of course means that it will only work when ZLE is active and the shell is interactively prompting you for input, not when commands are running. (For that, you would need to configure the terminal, not the shell, and need to have a terminal line discipline that implements sending SIGTERM
as an extension the POSIX specified behaviour.)
On that note, no-one else seems to have yet noticed that you are asking about shell line editor keybindings, not the terminal. To answer the first part of your question, then:
You set up a shell function to send the signal to the "current" job.
function terminate-current-job() { kill -s TERM %+ ; }
Then you construct a ZLE user-defined widget that invokes this shell function.
zle -N terminate-current-job terminate-current-job
Then, finally, you bind that widget to a key of your choice.
bindkey "^/" terminate-current-job