Bash: How to retrieve a variable value inside a background while loop Bash: How to retrieve a variable value inside a background while loop shell shell

Bash: How to retrieve a variable value inside a background while loop


This is due to the & creating a new subshell for the first while loop.

I'm pretty certain you'll need to use some kind of IPC to solve this. Using a pipe or a named pipe to implement a producer/consumer setup would be reasonable.

A rough example:

#!/bin/bashmyvar=AAAwhile true;do    sleep 3    myvar_piped=BBB    echo $myvar_piped # this goes to the pipe.    sleep 1done | # this connects the two loops.while true;do    # if we consumed something (timeout=1) print it, else print our own variable.    if read -t 1 myvar_piped #    then        echo "${myvar_piped}"    else        echo "${myvar}"    fi  done

Outputs:

AAAAAAAAABBBAAAAAAAAAAAABBB


Substantially, there is nothing you can do to read the variable directly in the parent shell.

The first loop is run in a sub-shell because of the &; the sub-shell's memory is completely independent of the main shell's memory, and there's no way (short of doing ghastly things like running the debugger on the sub-shell) to access the child's memory from the parent shell.

If you can modify the sub-shell process to write its variable's value every second, then the parent might be able to detect that. Alternatively, if the sub-shell writes the variable to a file with a known name every time it changes the variable, then you can read the file as often as you want in the parent:

#!/bin/bashtmp=$(mktemp)trap "rm -f $tmp; exit 1" 0 1 2 3 13 15myvar=AAAecho $myvar > $tmpwhile true;do    sleep 3    myvar=BBB    echo $myvar > $tmp    sleep 3    myvar=CCC    echo $myvar > $tmpdone &while cat $tmpdo    sleep 1donerm -f $tmptrap 0

The trappery ensures the temporary file is removed under most circumstances (signals HUP, INT, QUIT, PIPE and TERM).