If I am understanding your question correctly, I think this may do it—
#!/bin/bash
done=
functionA() {
sleep 3 # Placeholder for the actual work functionA does
done=y # Tell the outer loop we're done
kill "$1" # Stop the progress indicator
}
functionB() {
while :; do # The progress indicator - run forever
echo .
sleep 1
done
}
until [[ "$done" ]]; do
functionB &
functionA $!
done
$!
is the PID of the last-spawned background process, in this case a bash
subshell (a separate process) running functionB
in the background.
I think functionB
was always seeing $a
as 0
because functionA
was run in a subshell, so its changes to a
never made it back to the main shell where functionB
was running.
By contrast, the code above runs functionB
in the subshell and lets functionA
expressly kill that subshell from the main shell. That way functionA
's changes to done
are visible in the until
loop (I think).
Example output:
$ ./test.sh
.
.
.
$
Another option
If functionA
may have to run more than once, you can use this:
#!/bin/bash
done=
functionA() {
sleep 3 # Do work
done=y # If functionA needs to run again, don't set $done
}
functionB() {
while :; do # Run forever, until terminated
echo .
sleep 1
done
}
functionB & # Start the progress indicator
progress_pid="$!"
until [[ "$done" ]]; do # Do the work
functionA
done
kill "$progress_pid" # Stop the progress indicator