0

Below is a simple example of what I'm trying to accomplish. I'm trying to force an ssh script to not wait for all child processes to exit before returning. The purpose is to launch a daemon process on a remote host via ssh.

test.sh

#!/bin/bash

(
sleep 2 
echo "done"
) &

When I run the script on the console it returns immediately, with "done" appearing 2 seconds later.

When I run the script as an ssh script, the ssh command . It appears to wait until all child processes have terminated until ssh exits.

ssh example

$ ssh [email protected] /home/mike/test.sh
(2 seconds)
done

standard terminal example

$ ./test.sh
$ 
(2 seconds)
done

How can I make ssh return when the parent/main process has terminated?

EDIT:

I'm aware of the -f option to ssh to run the process in the background . It leaves the ssh process and connection open on the source host. For my purposes this is unsuitable.

1 Answer 1

2
ssh [email protected] /home/mike/test.sh

When you run ssh in this fashion, the remote ssh server will create a set of pipes (or socketpairs) which become the standard input, output, and error for the process which you requested it to run, in this case the script process. The ssh server doesn't end the session based on when the script process exits. Instead, it ends the session when it reads and end-of-file indication on the script process's standard output and standard error.

In your case, the script process creates a child process which inherits the script's standard input, output, and error. A pipe (or socketpair) only returns EOF when all possible writers have exited or closed their end of the pipe. As long as the child process is running and has a copy of the standard output/error file descriptors, the ssh server won't read an EOF indication on those descriptors and it won't close the session.

You can get around this by redirecting standard input and standard output in the command that you pass to the remote server:

ssh [email protected] '/home/mike/test.sh > /dev/null 2>&1'
(note the quotes are important)

This avoids passing the standard output and standard error created by the ssh server to the script process or the subprocesses that it creates.

Alternately, you could add a redirection to the script:

#!/bin/bash

(
exec > /dev/null 2>&1
sleep 2 
echo "done"
) &

This causes the script's child process to close its copies of the original standard output and standard error.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.