I need to run commands on a server via an SSH session and close the session without killing the process on the server. How can this be implemented correctly.
Server and client are linux systems.
Please note than I can't install additional software on server.
Why do ssh not return when I try to background job on target.
ssh user@host 'sleep 300 &'
Then you have to hit Ctrl+C to get your session.
This is because each connection hold 3 file descriptors: STDIN (0)
, STDOUT (1)
and STDERR (2)
. The connection will stay open while at least one of this file descriptors are in use.
This is aproximatively what nohup
do.
ssh user@host 'exec 0<&-;exec 1>&-;exec 2>&-; sleep 300 &'
This will do the job.
nohup
:ssh user@host 'nohup sleep 300 &'
Will do the job too.
You could store output in files located somewhere on server side:
ssh user@host 'exec 0<&-;exec 1>>/path/to/logfile;exec 2>>/path/to/errlog; sleep 300 &'
>>
for adding log to existing files... you could use uniq files by adding $$
or date +%F
...
ssh user@host 'exec 0<&-;exec 1>/path/to/logfile-$$;exec 2>&1; sleep 300 &'
2>&1
cited after 1>file
will redirect STDERR
as STDOUT
to file
.
ssh user@host 'exec 0<&-;exec 1>/path/to/file-$(date +%F-%T).$$;exec 2>&-;sleep 300 &'
Only STDOUT
will be stored in newfiles.
screen
screen
is installedIf you would be able to access interactive front end, you could:
ssh user@host screen -dmS mySleep sh -c \
"'x=0;while [ \$x -lt 300 ];do echo \$x;x=\$((x+1));sleep 1;done'"
This will start a background job, printing 1 ling each 300 next second, then finish.
To reconnect this, you could
ssh -t user@host screen -x mySleep
Then Ctrl+A, followed by d for leaving background task.
screen
at user
levelIf you can't install something in server, maybe* could you
install something in your $HOME
directory:
(* This will be easy if your architecture is same than on server. If not, you even could find compatible binaries or cross compile yourself.)
$ ssh user@host
user@host:~$ mkdir bin lib
user@host:~$ exit
$ scp /path/to/bin/screen user@host:~/bin
$ ssh user@host
user@host:~$ bin/screen
bin/screen: error while loading shared libraries: libutempter.so.0:
cannot open shared object file: No such file or directory
user@host:~$ exit
$ scp /path/to/lib/libutempter.so.0 user@host:~/lib
$ ssh user@host
user@host:~$ LD_LIBRARY_PATH=~/lib bin/screen
bin/screen: /lib/x86_64-linux-gnu/libcrypt.so.1: version `XCRYPT_2.0'
not found (required by bin/screen)
user@host:~$ exit
$ scp /lib/x86_64-linux-gnu/libcrypt.so.1 user@host:~/lib
$ ssh user@host
user@host:~$ LD_LIBRARY_PATH=~/lib bin/screen
Cannot make directory '/run/screen': Permission denied
user@host:~$ mkdir $HOME/.screen
user@host:~$ SCREENDIR=$HOME/.screen LD_LIBRARY_PATH=~/lib bin/screen
Finally, now it work...
$ ssh user@host SCREENDIR=\~/.screen LD_LIBRARY_PATH=\~/lib bin/screen -dmS mySleep sh -c \
"'x=0;while [ \$x -lt 300 ];do echo \$x;x=\$((x+1));sleep 1;done'"
$ ssh -t user@host SCREENDIR=\~/.screen LD_LIBRARY_PATH=\~/lib bin/screen -x mySleep
There are lot of other alternatives, like tmux
, byobu
...
Upto create your own wrapper...