Kill process spawned by ssh when ssh dies

This is a question that has been addressed several times, not only here, but also in other sites of the stack exchange network (e.g. How to make ssh to kill remote process when I interrupt ssh itself?
). However, I cannot make any of the solutions work for me.

I’m running a command through ssh. Whenever I exit ssh, I want the command to die as well. This command is a daemon called ktserver that runs indefinitely until you press Ctrl-C.

I run it as follows: ssh -t compute-0-1 ktserver and, indeed, when I press Ctrl-C, the process ends gracefully and the ssh session ends.

However, if instead of pressing Ctrl-C, I kill the ssh process using the kill command (for example, sending SIGINT or SIGHUP), the ktserver process stays alive.

How can I make the ktserver always die independent on how ssh is killed?

EDIT: If, instead of ktserver I run something completely different, such as gedit, everything works like a charm (i.e. gedit dies when the connection dies). Therefore, there might be something wrong with the process itself. For example, I thought that it might be ignoring SIGHUP or SIGINT. However, when I run kill -1 ktserver or kill -2 ktserver, the process dies as expected.

EDIT2: As Mark Plotnick points out, the issue is related to the fact that there is no communication circulating on the ssh channel. I’ve confirmed by running ssh -t <host> read and killing the ssh process afterwards. readwas still alive and kicking.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I found that simply using -t -t as an argument to ssh made it work. I did not have to set huponexit to either the originating or remote shell.

I tested this as follows:

Doesn’t work:

ssh <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="eb9e988e99ab998e86849f8e">[email protected]</a> sleep 100
^C

This killed the ssh session, but I can see the sleep process is still running on the remote host (ps -ef | grep sleep shows it).

Does work:

ssh -t -t <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="02777167704270676f6d7667">[email protected]</a> sleep 100
^C

This kills the ssh session and the remote sleep process was also killed. I’ve also verified that the signal that is sent to the remote process is SIGINT if you use ControlC. I also verified that SIGKILL (-9) applied to the ssh process will also kill the remote process.

EDIT 1:

That was true for sleep … for more stubborn remote processes, I found that ssh handles ^C differently that SIGINT. CtrlC worked, but kill -INT $pid didn’.t

Here is what I finally came up with that worked for my actual application (stealing from the other answers).

ssh -t -t -i id_rsa <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="90e5e3f5e2d0fdf9f3a0">[email protected]</a> "/bin/sh -O huponexit -c 'sleep 100'"

Note the nested use of double quotes and single quotes. Note that your remote process MUST respond to SIGHUP by actually exiting!

Method 2

Usually when ssh connection dies the shell also dies. You can configure your shell to send a signal -1 (SIGHUP) when it terminates to all of its children.

For bash you can configure this option via the builtin command shopt. (shopt -s huponexit).

For zsh you want setoptHUP.

Method 3

If ssh doesn’t propagate signals it receives what would you expect from it?

UPD. (special for JosephR): it’s obviously an error in question itself which follows out of misunderstanding — “Kill process spawned by ssh when ssh dies”. SSH doesn’t spawn processes usually (sometimes it does, but this is another story), SSHD does instead, when we look at other side of connection. SSH merely relies on pseudo-terminal abstraction remote server has. That’s why the only thing which can be of help there is terminal’s ability to emit signals to its attached processes. This is somewhat very basic for every UNIX-like system.

Method 4

The solution posted here did not work for me but since this question came up first when I was searching for solution to similar problem and also -t -t trick was mentioned here I will post solution that worked for me for others to try.

ssh -t -t -o ControlMaster=auto -o ControlPath='~/test.ssh' your_remote_ip_goes_here "your_long_running_command" &
sleep 100
ssh -o ControlPath='~/test.ssh' -O exit your_remote_ip_goes_here

My long running command was not running anymore when connection was terminated like this.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x