Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

When I start an SSH session that executes a long-running command, what happens with Ctrl+C (SIGINT) handling?

I can see that the SSH session is closed, but I am not sure who gets the SIGINT first: is it...

  1. the remote long-running command? that is, (a) the signal handler in the remote command is called and stops the remote command, (b) the shell that spawned it detects that the command stopped, and stops as well (c) the remote sshd detects the shell stopped, so it closes the connection

    or

  2. the local ssh receives the signal, and closes the connection.

I think that (1) is happening, but want to make sure.

I am also uncertain about what happens with shell handling of SIGINTs in this case. For example, if I ...

ssh remote 'while true ; do sleep 1 ; date ; done'

and Ctrl+C, then the remote connection is dropped. Is there a way to run the remote command under a shell that will stay alive after Ctrl+C? That is, in this case, stop the loop and allow me to keep working on the remote shell?

share|improve this question
2  
A noninteractive ssh (ssh remote command, as opposed to ssh remote) will be killed (on the local side) by the SIGINT generated by typing ctrl-C. The remote side will probably (depends on the OS) stay running until it tries to read or write to the closed socket. If you want all your keystrokes, including ctrl-C, to be passed on to the remote, use ssh remote. – Mark Plotnick Nov 21 '13 at 11:52
    
@MarkPlotnick: OK Mark - if you add your response below as an answer, I will accept it... In my own tests, I verified that the remote doesn't receive any signal. – ttsiodras Oct 13 '14 at 13:59
    
up vote 7 down vote accepted

ssh can be invoked in a few different ways, each resulting slightly different treatment of terminal-initiated signals like Ctrl-C.

  • ssh remotehost will run an interactive session on remotehost. On the client side, ssh will try to set the tty used by stdin to "raw" mode, and sshd on the remote host will allocate a pseudo-tty and run your shell as a login shell (e.g. -bash).

    Setting raw mode means that characters that would normally send signals (such as Ctrl-C and Ctrl-\) are instead just inserted into the input stream. ssh will send such characters as-is to the remote host, where they will likely send SIGINT or SIGQUIT and, typically, kill any command and return you to a shell on the remote host. The ssh connection will stay alive, as long as the remote shell is alive.

  • ssh -t remotehost command args ... will run an interactive session on remotehost, just like the above, except on the remote side, your_shell -c "command args ..." will be run. As above, if you type Ctrl-C, it will be sent to the remote host, where the command will likely receive SIGINT and immediately exit, and then the remote shell will exit. The remote sshd then closes the connection, and ssh reports Connection to remotehost closed.

  • ssh remotehost command args ... will run a non-interactive session on remotehost. On the client side, ssh will not set the tty to raw mode (well, except to read in a password or passphrase). If you type Ctrl-C, ssh will get sent SIGINT and will immediately be terminated, without even issuing a Connection to remotehost closed message.

    The your_shell -c "command args ..." processes will likely remain running on the remote host. Either they will exit on their own, or one process will try to write data to the now-closed ssh socket, which will cause a (typically) fatal SIGPIPE signal to be sent to it.

share|improve this answer
    
Technically, the remote command doesn't write directly to the socket. Its stdout is a pipe. And sshd at the other end reads the data, encrypts it, and sends it over the socket. The end result is the same though. The command will get a sigpipe because that pipe is gone when the client disconnects. – Stéphane Chazelas Mar 2 at 10:12
    
@StéphaneChazelas Thanks, I will edit the answer to correct it. – Mark Plotnick Mar 8 at 18:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.