Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running parallel functions with dependency in bash

Tags:

linux

bash

I have 2 functions:

One for the main job that takes some inconsistent time:

functionA {
        sleep 10  #FOR INSTANCE
    ((a++))  #added to try catching job finish
}

And other for drawing a progress:

functionB {
    # DOT PROGRESS COUNTER
}

I need functionB to be running ONLY while functionA is active, so i do:

a=0    
    until ((a>0))
        do
            functionA & functionB 
        done
    echo "functionA is done"

However, in result I get the endless loop of both functions.

Tried while loop as well - result is the same.

What should be done to stop functionB when functionA is done?

EDIT: in debugger i see that "$a" for functionB is always 0. Why?

like image 721
faceless Avatar asked Feb 14 '26 11:02

faceless


1 Answers

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
like image 151
cxw Avatar answered Feb 17 '26 02:02

cxw



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!