How can I work around the problem that ssh
does not forward the SIGTERM
signal?
I want print-signal.py
to terminate of the ssh root@localhost
process terminates:
ssh root@localhost /root/print-signal.py
Unfortunately only the ssh process itself gets the signal, not the remote command (print-signal.py
). The remote command does not terminate :-(
Since openssh does not forward the SIGTERM
to the remote command, I am searching for a work-around.
How to terminate print-signal.py
if ssh root@localhost
... terminates?
This is a follow-up question to: Forwarding SIGTERM over ssh
The shell can easily help you for such problem, if it supports some builtin variable( $! ). Here is a basic shell solution by replacing your command by a very long sleep.
The script sent in the command is running on the remote host.
You could write a wrapper which terminates if the parent process is the init process:
The tool
terminate-command-if-parent-is-lost
needs to do this:Start the argv as subprocess (in this example
print-signal.py
). Then it checks every second the status of its parent pid (in Pythonos.getppid()
).If ppid is 1 (the init process), then the print-signal.py process has lost its parent. This means "ssh root@localhost ..." was terminated (or connection was closed).
Now
terminate-command-if-parent-is-lost
terminates the subprocess.Disclaimer: the answer below is not for SIGTERM, but SIGINT. This is not an answer to the question due to oversight.
The problem you are observing is due to a missing tty which should be in control of the process you try to run. If there is no tty available, ssh is unable to send the signals to the process. When you use the option
-t
to thessh
command, it will force pseudo-terminal allocation which makes it possible to send signals over ssh :A very nice explanation how and why is given by Giles on unix.stackexchange.
Here you see how it works :
On an other terminal you see then that
print_signal.py
is running onPID=26992
under thessh
withPID=26991
without a tty (username@notty
)After killing the ssh process with kill or CTRL-C, the process is still active but runs now under
/sbin/init
(PPID=1
)using the
-t
flag nicely kills the process on the other side:On an other terminal you see then that
print_signal.py
is running onPID=39277
under thessh
withPID=39276
bound to a tty (username@pts/10
)After killing the ssh process
The process is now clearly terminated on the other server
I have just been having exactly this problem. While I haven't figured out the exact cause, what happens when ssh is terminated is that your process is reparented to init. You can tell your process to ask for a signal when it's parent dies instead using prctl.
If you use python-prctl, put the following early on in
/root/print-signal.py