66

I want to execute a script, start.sh on a remote server which runs this:

nohup node server.js &

Naively, I call SSH like this:

ssh myserver <<EOF
./start.sh &
EOF

This starts the script, but leaves the session connected. I want to follow this step with other commands in a script, so that's no good.

How can I SSH to the remote machine, launch a nohup command into the background, then disconnect? I suppose I could put the SSH process itself into the background, but that doesn't seem right.

Steve Bennett
  • 6,497
  • 8
  • 25
  • 28

5 Answers5

50

You have already found the right way, here document.

NOTE: you can put the ssh (client) into background by placing a & at the end, but you will not see the output. If you really want to do this, redirect the stdout/stderr to a file in case you need to check the response from the remote host.

Basically you can do it in either way:

Directly run the command{,s}

ssh user@host "nohup command1 > /dev/null 2>&1 &; nohup command2; command3"

OR

ssh user@host "$(nohup command1 > /dev/null 2>&1 &) && nohup command2 >> /path/to/log 2>&1 &"

NOTE: && requires the first command to return 0 before executing the second

Use Here document

ssh user@host << EOF
nohup command1 > /dev/null 2>&1 &
nohup command2 >> /path/to/command2.log 2>&1 &
......
EOF

The above 3 options should work for you.

In addition, take a look at the answer here: https://askubuntu.com/a/348921/70270

Terry Wang
  • 9,505
  • 4
  • 37
  • 30
18
ssh node "nohup sleep 10 &"

is not running in daemon mode, keeping your ssh session connected. Ssh session will return in 10 seconds, despite you used nohup.

Reason is that remote stdout and stderr still connected to your session. It keeps ssh session alive, nohup does not help.

This:

ssh node "nohup sleep 10 1>/dev/null 2>/dev/null &"

returns immediately. It does start remote process with nohup and exits ssh session immediately.

  • This was exactly our problem. We only had a 1>file.log. The ssh on the one machine was stuck. The process on the 'node' machine was running. When we added a 2>&1 just before the closing &, that let the ssh disconnect. – Lee Meador May 22 '19 at 22:11
  • 1
    This answer explains the key issue: that you need to redirect both stdout and stderr otherwise SSH will kill the command. – Davor Cubranic Mar 19 '20 at 03:06
  • Thank you for clarifying the actual problem: the need to redirect stdout & stderr. – Sebastiaan Oct 20 '20 at 09:24
  • 1
    Just as an even further clarification, nohup isn't even needed when redirecting the stdout and stderr. – fullStackChris Aug 11 '21 at 11:58
  • **Note:** If you run the above but `ssh` with the `-t` option (Force pseudo-terminal allocation) then SSH immediately terminates but the remote command never gets started properly. I omitted `-t` and it then worked. SSH connects passwordless, starts command on the remote (on my NAS it starts a long `wget --continue` download), quickly thereafter SSH terminates, but the command on the remote (wget on NAS) continued until the download had finished. I checked this as I later connected by SSH interactively and the download there was completed. Tested several times. Worked all times. Thanks! – porg Dec 24 '22 at 00:15
9

Why not just tmux or screen and be done with it? For example:

$ tmux new -s SessionNameHere
$ nohup /path/to/your/script.sh

This is practical if it's something that will continuously loop or take a while to finish. You can disconnect from the session and it will remain active.

Waldir Leoncio
  • 1,897
  • 4
  • 29
  • 43
Anon
  • 91
  • 1
  • 1
  • 4
    Doesn't really fit what I'm asking for, which is a single command that can be run on my laptop, which will connect, fork a command, then disconnect. – Steve Bennett Nov 13 '14 at 22:24
5

Shorter form:

ssh host "(command 1; command 2; ...) &>/dev/null &"

It appears, that bash itself performs detaching from terminal, so no nohup needed. I run Ubuntu 14.04 x86_64, bash 4.3.11.

Alek_A
  • 590
  • 5
  • 8
  • 2
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient [reputation](http://askubuntu.com/help/whats-reputation) you will be able to [comment on any post](http://askubuntu.com/help/privileges/comment). - [From Review](/review/low-quality-posts/532014) – David Foerster Feb 28 '16 at 09:34
  • This doesn't seem to work. `nohup; ` just outputs a complaint about missing arguments. – Steve Bennett Feb 29 '16 at 04:32
  • @DavidFoerster, no Idea why, if `command 1; command 2; ...` represents script OP want to run. OP can also use special case of this answer: `ssh myserver ./start.sh &>/dev/null &` – Alek_A Feb 29 '16 at 10:31
1

And last but not least, remember not to allocate a tty for your session.
If you do that, it will not work.

So if you got any -t or -tt or -ttt and so on in your command. Thats the reason why it is not working for you.

So instead of

ssh -tt host "(command 1; command 2; ...) &>/dev/null &"

Use

ssh host "(command 1; command 2; ...) &>/dev/null &"