Do programs run from an ssh session depend on the connection?
The output of programs is buffered, so if the connection is slow the program will be halted if the buffer fills up.
If you use screen
, it has a buffer as well that it uses to try and display to a connected session. But a program connected in the screen session will not be stopped if screen
cannot update the remote terminal fast enough. Just like when a connection is lost, the program continues filling screens
buffer until it overflows (pushing out the oldest information). What you see coming in (and can scroll back to) is depending on what is (still) in that buffer. screen
effectively discouples your program from your terminal (and your slow SSH connection).
An SSH connection can die prematurely if the underlying TCP connection receives a packet with the RST flag. That could happen if one side sends a packet (which might be a periodic SSH keepalive probe) but doesn't receive a TCP acknowledgement in a reasonable amount of time, or if a router decides that the connection has been idle too long, or if an ISP is just being evil.
In the Unix terminal model, when the terminal connection is dropped, the terminal driver sends a HUP signal to the shell, whose termination also causes a SIGHUP to be sent to processes running in the shell.
From the Unix Programmer FAQ, item 1.15:
SIGHUP
is a signal that means, by convention, "the terminal line got hung up". It has nothing to do with parent processes, and is usually generated by the tty driver (and delivered to the foreground process group).However, as part of the session management system, there are exactly two cases where
SIGHUP
is sent on the death of a process:
When the process that dies is the session leader of a session that is attached to a terminal device,
SIGHUP
is sent to all processes in the foreground process group of that terminal device.When the death of a process causes a process group to become orphaned, and one or more processes in the orphaned group are stopped, then
SIGHUP
andSIGCONT
are sent to all members of the orphaned group. (An orphaned process group is one where no process in the group has a parent which is part of the same session, but not the same process group.)
The default signal handler for SIGHUP is to terminate the process:
Signal Value Action Comment ---------------------------------------------------------------------- SIGHUP 1 Term Hangup detected on controlling terminal or death of controlling process
It is possible to avoid process termination, though.
You can insert a signal handler that ignores SIGHUP. To do that as a user, wrap the command in
nohup
. For example:nohup make all &
You can tell the shell to dissociate a child process from it. For example, Bash has a
disown
built-in command:make all
CtrlZ
bg disown %1
Then, the SIGHUP will not be propagated to the child (which is no longer a child).
- Some programs, notably daemons, will use the mechanisms above automatically: a program can install an alternate SIGHUP handler (using
sigaction(2)
), or it could choose to join a new session (setsid(2)
). - You can run
screen
ortmux
, which allocates a pseudo-TTY to run a session with a shell that does not receive the SIGHUP when the SSH connection dies. The SIGHUP is not relayed from the SSH session to the screen/tmux session.
Incidentally, an alternate way to deal with unreliable SSH connections is to use the Mosh protocol instead. Mosh runs over UDP, so there is no TCP connection that risks getting reset.