Send current script to background

Hi scripters,

I'm quite used to run commands in the background using & like in:

$ myscript &

But this is NOT what I'm trying to do today. What I'm trying to achieve is to run a script the normal way (without &), have my script do a little checkup and then jump to background. Something like:

#!/bin/bash
if [[ -z ${1+set} ]]; then
    echo "Missing argument"
    exit 1
fi
echo "Arguments OK, going to background"
some_command_that_sends_the_script_to_background
# At that point, the user should have its terminal back and the script should be sent to bg
while true; do
    echo "doing some never ending daemon stuff" > log
    sleep 5
done

I tried the following:

bg
disown
exec &

If I google the following strings, I get nothing but what I already know :
bash current script to background
bash script send to background
bash send to background in the middle of a script

Can anyone point me in the right direction?

Thanks
Santiago

A block in parenthesis can be sent to the background

(
while true; do
    echo "doing some never ending daemon stuff" > log
    sleep 5
done
) </dev/null >/dev/null 2>&1 &

It is safer to disable stdin,stdout,stderr. E.g. the sleep command could try to set a CTRL-C interaction from the terminal.

1 Like

Processes don't work that way. The way to make a controlling process not be the controlling process, is to create a background process then make the foreground one quit. Hence why you need a subshell to do this one way or another.

Thanks MadeInGermany,

I'd rather not create a subshell. A lot of the scripts in which I need that feature use functions meaning I would have to replace all the `return' with some `exit'. But I see that it solves the problem somehow.

Thanks Corona688,

I don't understand what you're saying. What command are you proposing? I think `sesid' could do what I need but I can't get it to work.

You can't move the controlling shell into the background, just create a new one.

There's more than one way to skin a cat however, I'll try to whip up a method that changes your code less.

MadeInGermany's.

It creates a background process, via subshell, then quits.

Processes don't work that way.

How about this:

#!/bin/bash

if [[ -z ${1+set} ]]
then
        echo "Missing argument" >&2
        exit 1
fi

# Check if we're a background script
if [ -z "${_FG}" ]
then
        # Warn subshell that it is a subshell
        export _FG="1"

        # Re-run entire script and warn it that its a subshell
        ( exec "$0" "$@" ) &
        exit 0
fi

# This code will run in background
echo "Yeah okay we're in subshell"
sleep 10
echo "Woo"

When _FG is not set, it sets it, re-executes the program from scratch, then quits.

When _FG is set, it skips that and runs the code below.

This also means you can run your programs in the foreground, if you really feel like it, by doing _FG=1 ./myprogram.sh arguments

1 Like