Shell SIGKILL Keybinding

20

7

How can I setup a keybinding to send a SIGKILL to the current foreground job? I already know that Ctrl+C is SIGINT and Ctrl+\ is SIGQUIT. I would like a more severe option.

Is there anything seriously unadvisable about this?

drewrobb

Posted 2011-05-26T05:23:09.983

Reputation: 621

It's sent by the terminal driver, not by the shell (which is entirely unaware of what you're doing with the program). – user1686 – 2011-05-26T06:13:57.043

You haven't noted the shell specified, which is zsh, and the fact that the question talks about keybindings. This is a question about configuring zsh's line editor, not about setting up one's terminal. – JdeBP – 2011-05-26T09:31:30.143

Answers

28

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.)

lxgr

Posted 2011-05-26T05:23:09.983

Reputation: 1 041

3

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

JdeBP

Posted 2011-05-26T05:23:09.983

Reputation: 23 855

1I guess he's not actually talking about the line editor - if he's typing into the shell, there would be no running foreground process, right? The shell would never actually see the keypresses if there is a foreground process running and connected to the current tty. – lxgr – 2012-04-28T08:59:46.240