Using SSH to remotely start a process

I have written a script that I am using to push and deploy a new service to several machines under my control, and in order to execute the process I am using ssh to remotely start the process.

Unfortunately, whenever I use SSH to start the process, the SSH command never seems to return, causing the script to stall.

The command is specified as:

ssh $user@$host "/root/command &"

Whenever I run simple commands, such as ps or who, the SSH command returns immediately, however when I try and start my process it does not return.

I have tried tricks like wrapping my process in a simple bash script that starts the process and then exits, however this also hangs the SSH command (even if the bash script echos a success message, and exits normally).

Does anyone have any insight into what is causing this behaviour, and how I can get the SSH command to return as soon as the process has been started?


Solution 1:

SSH connects stdin, stdout and stderr of the remote shell to your local terminal, so you can interact with the command that's running on the remote side.

As a side effect, it will keep running until these connections have been closed, which happens only when the remote command and all its children (!) have terminated (because the children, which is what "&" starts, inherit std* from their parent process and keep it open).

So you need to use something like

ssh user@host "/script/to/run < /dev/null > /tmp/mylogfile 2>&1 &"

The <, > and 2>&1 redirect stdin/stdout/stderr away from your terminal. The "&" then makes your script go to the background. In production you would of course redirect stdin/err to a suitable logfile.

See

http://osdir.com/ml/network.openssh.general/2006-05/msg00017.html

Edit:

Just found out that the < /dev/null above is not necessary (but redirecting stdout/err is). No idea why...

Solution 2:

You could try nohup. Man nohup for more details.

ssh host "nohup script &"

If you want to keep the output on the remote machine, here's a variant.

ssh user@host 'export REMOTE=myname; nice nohup ./my-restart >
logfile.log 2>&1 &'