45

I am using SSH to start a background process on a remote server. This is what I have at the moment:

ssh remote_user@server.com "nohup process &"

This works, in that the process does start. But the SSH session itself does not end until I hit Ctr-C.

When I hit Ctr-C, the remote process continues to run in the background.

I would like to place the ssh command in a script that I can run locally, so I would like the ssh session to exit automatically once the remote process has started.

Is there a way to make this happen?

futureshocked
  • 2,105
  • 4
  • 23
  • 32

4 Answers4

48

The "-f" option to ssh tells ssh to run the remote command in the background and to return immediately. E.g.,

ssh -f user@host "echo foo; sleep 5; echo bar"

If you type the above, you will get your shell prompt back immediately, you will then see "foo" output. Five seconds later you will then see "bar" output. In the meantime, you could have been using the shell.

Douglas
  • 2,555
  • 3
  • 24
  • 30
  • 12
    Note that this will keep your SSH session running in the background. If the session is disconnected the command will stop running. – Questionmark Nov 22 '16 at 21:07
37

When using nohup, make sure you also redirect stdin, stdout and stderr:

ssh user@server 'DISPLAY=:0 nohup xeyes < /dev/null > std.out 2> std.err &'

In this way you will be completely detached from the remote process. Be carefull with using ssh -f user@host... since that will only put the ssh process in the background on the calling side. You can verify this by running a ps -aux | grep ssh on the calling machine and this will show you that the ssh call is still active, but just put in the background.

In my example above I use DISPLAY=:0 since xeyes is an X11 program and I want it started on the remote machine.

Ronny Andersson
  • 1,558
  • 13
  • 12
  • It worked for my with a forked process like '''rsync --daemon''' that wouldn't exit otherwise – Adrien Clerc May 19 '14 at 14:50
  • This method is great when you fork your script during execution. My ssh was not exiting even after the script I executed was finished. I spent whole my day to somehow fix it. Thank you for the answer – DaTval Nov 19 '14 at 01:06
  • Is it necessary to redirect `stdin` to `/dev/null`? Is it necessary to invoke `nohup` via SSH? I think SSH does not send HUP anyway. I didn't find any difference with `ssh user@server "process &>/dev/null &"` – Alek Mar 16 '23 at 18:55
5

You could use screen to run your process on this screen, detach from screen Ctrl-a :detach and exit your current session without problem. Then you can reconnect to SSH and attach to this screen again to continue with your task or check if is finished.

Or you can send the command to an already running screen. Your local script should look like this:

ssh remote_user@server.com
screen -dmS new_screen sh
screen -S new_screen -p 0 -X stuff $'nohup process \n'
exit    

For more info see this tutorial

Questionmark
  • 834
  • 2
  • 15
  • 26
Majlik
  • 1,082
  • 1
  • 10
  • 20
  • Somethink like this? `ssh remote_user@server.com 'screen -S world/ -X stuff "nohup process "'` – Majlik Nov 15 '13 at 08:58
  • These didn't quite work for my problem, but I found another article that matched my question: http://stackoverflow.com/questions/29142/getting-ssh-to-execute-a-command-in-the-background-on-target-machine – futureshocked Nov 15 '13 at 22:50
-1

Well this question is almost 10 years old, but I recently had to launch a very long script (taking several hours to complete) on a remote server and I found a way using the crontab.

If can edit your user's crontab on the remote server, connect with ssh to the server, edit the crontab and add an entry that will start your script the next minute. Let's say it's 15h03. Add this line :

4 15 * * * /path/to/your/script.sh

save your crontab, wait a minute for the script to be launched. Then edit again your crontab to remove this entry.

You can then safely exit ssh, even shut down your computer while the script is running.

dj3c1t
  • 9
  • 2