Bash: How to get a script to rerun itself as a background task? Bash: How to get a script to rerun itself as a background task? shell shell

Bash: How to get a script to rerun itself as a background task?


The & is being applied to the exec command itself, so exec foo & forks a new asynchronous subshell (or equivalent thereto, see below). That subshell immediately replaces itself with foo. If you want the parent (that is, your script) to terminate as well, you'll need to do so explicitly with an exit command.

The exec is probably not buying you anything here. Bash is clever enough to not actually start a subshell for a simple backgrounded command. So it should be sufficient to do:

if $async; then  nohup "${BASH_SOURCE[0]}" --sync "${args[@]}" 0<&- &> /dev/null &  exit 0fi

I don't know of a way to do this without a subshell. But when you write shell scripts, you get subshells. Personally I'd just use a simple variable and test it with something like if [[ $async ]]; instead of executing true or false, but since those are also bash builtins, it's pretty well equivalent. In other shells they might run in subshells.

Now that I think of it, since you're reprocessing all the options in async execution anyway, you might as well just fork and exit from within the case statement, so you don't need the second check at all:

case "$1" in    --sync)        nohup "${BASH_SOURCE[0]}" --sync "${args[@]}" 0<&- &> /dev/null &        exit 0        ;;


I disagree with rici's answer because the question clearly states background-ing is only wanted when --sync is NOT passed into the script. What was shown appears to be an infinite loop, and isn't checking all the parameters passed. I believe the original code was fine, except for the final "async && exec ...". The following replacement for that line should work:

if [ "$async" = true ]; then   nohup "${BASH_SOURCE[0]}" --sync "${args[@]}" 0<&- &> /dev/null &   exit 0fi

followed by what your code is supposed to do when --sync is passed.