Search code examples
bashsshcsh

Getting ssh to execute a command in the background on target machine


This is a follow-on question to the How do you use ssh in a shell script? question. If I want to execute a command on the remote machine that runs in the background on that machine, how do I get the ssh command to return? When I try to just include the ampersand (&) at the end of the command it just hangs. The exact form of the command looks like this:

ssh user@target "cd /some/directory; program-to-execute &"

Any ideas? One thing to note is that logins to the target machine always produce a text banner and I have SSH keys set up so no password is required.


Solution

  • This should solve your problem:

    nohup myprogram > foo.log 2> foo.err < /dev/null &
    

    The syntax and unusual use of < /dev/null are explained especially well in this answer, quoted here for your convenience.

    < /dev/null is used to instantly send EOF to the program, so that it doesn't wait for input (/dev/null, the null device, is a special file that discards all data written to it, but reports that the write operation succeeded, and provides no data to any process that reads from it, yielding EOF immediately).

    So the command:

    nohup myscript.sh >myscript.log 2>&1 </dev/null &
    #\__/             \___________/ \__/ \________/ ^
    # |                    |          |      |      |
    # |                    |          |      |  run in background
    # |                    |          |      |
    # |                    |          |   don't expect input
    # |                    |          |   
    # |                    |        redirect stderr to stdout
    # |                    |           
    # |                    redirect stdout to myscript.log
    # |
    # keep the command running 
    # no matter whether the connection is lost or you logout
    

    will move to background the command, outputting both stdout and stderr to myscript.log without waiting for any input.


    See also the wikipedia artcle on nohup, also quoted here for your convenience.

    Nohuping backgrounded jobs is for example useful when logged in via SSH, since backgrounded jobs can cause the shell to hang on logout due to a race condition. This problem can also be overcome by redirecting all three I/O streams.