Prevent currently running linux task to be killed after logout from SSH
I have a computational task running for a few days on a linux server via SSH connection. It is not on the background, so the SSH connection is under hold of the task.
I want to restart the local machine (not the server) from which I have opened ssh session, but want to keep the task running. Is that any possible?
If your task is already launched, it is too late*
to consider alternative solutions that insert an additional layer between your ssh
session and the shell running the command, like screen
, tmux
, byobu
, nohup
and the likes.
If your process support to be placed in the background and particularly doesn't hang when stdout
and stderr
are unwritable/closed, you can put it in the background before logging out with ControlZ and bg
then detach it from your shell with the disown
builtin.
eg:
$ ssh localhost
You have new mail.
Last login: Fri Jun 6 11:26:56 2014
$ /bin/sleep 3600
^Z[1] + Stopped /bin/sleep 3600
$ bg
[1] /bin/sleep 3600&
$ jobs
[1] + Running /bin/sleep 3600
$ disown %1
$ exit
Connection to localhost closed.
$ ps -ef|grep sleep
jlliagre 12864 1 0 21:12 ? 00:00:00 /bin/sleep 3600
jlliagre 13056 12477 0 21:13 pts/18 00:00:00 grep sleep
$
*
As Bob commented, there are actually several hackish ways to reparent a tty session under Linux. repty, retty, injcode and neercs. The most advanced looks to be reptyr but you might need root privileges to enable ptrace to hack your process.
One solution is to use GNU screen. You could start up screen
, run your command, then detach with C-a d
. Later, to reconnect, do screen -r
, and you are back in your previous session.
Other benefits of screen are window management (so you can switch to other shells while your command is running, without needing a new SSH connection), and it allows your command to remain in the foreground, whether in the current session or a later one.
Edit: As noted in the comments, this will only work if you remember to start screen
before running the command. If the command is already running, then you will need @jlliagre's solution.
One of the "standard" ways to do so, is to use the nohup
command, included in coreutils
, like this:
nohup COMMAND [ARGS] &
But the command will redirect the output (STDOUT
& STDERR
AFAIK) of the program into a file nohup.out
, making it somehow annoying sometimes (like generating a huge log file), so you may want to make your own redirection, or redirect it to /dev/null if you want.