0

I want to create the script which runs function in background, but leaves ability to query that function about results, pause, resume or other way to interact with it.

For simplicity, lets say, i want to run the counter in the background which increases each second. For user interaction i will leave endless loop with read function.

When I enter p I expect to see current $counter value.

When I enter q I expect while loop in loop_counter function will stop as I set $RUN to false.

#!/bin/bash
RUN=true
counter=0

print_counter() {
        echo "Current value is: $counter"
}

loop_counter() {
        while $RUN
        do
                echo $counter >> file
                ((counter++))
                sleep 1
        done
}

loop_counter &

while true
do
        echo "Print or Quit?"
        read x

        case $x in
                p) print_counter ;;
                q) RUN=false; break ;;
                *) echo "Use p or q!" ;;
        esac
done

wait

I print $counter value to file, just to watch on another terminal with tail -f file

When I hit p I get 0 as $counter loops in subshell.

When I hit q script brakes from the while loop and it waits for subprocess in background will stop. Unfortunately it continues as variable $RUN in function loop_counter remains true.

Any ideas how can I read the current value of $counter or change the value of $RUN? Is it possible to create something like a socket?

Thanks

Petras L
  • 183
  • 1
  • 1
  • 7
  • 1
    `loop_counter &` kicks off a separate, asynchronous process that is no longer associated with your current script, so something like a call to `print_counter` is going to print the counter for the current process which is ... 0; to enable communications between the 2 processes you could look at a) some sort of socket solution, b) using a combo of `kill` and signals (`loop_counter` would need to `trap` said signals and take the appropriate action), c) passing directives (and data?) via a FIFO/pipe and/or file ... – markp-fuso Oct 31 '20 at 20:31
  • ... a variation on the 'pipe' idea would be coprocesses whereby the stdin and/or stdout of the processes is redirected to pipes, and then messages can be passed via said pipes – markp-fuso Oct 31 '20 at 20:46
  • I don't think there's a great direct way to do this, but you can do amazing things with Redis (`redis-cli`) if you want to stick with bash. – ShawnMilo Oct 31 '20 at 21:57
  • You can export `RUN` and `counter` variables, so they will be accessible by parent script, – Yuri Ginsburg Nov 01 '20 at 03:11
  • @markp-fuso. Yes, trap works well if one action is need all the time. But if multiple different actions is needed - this will not work. I thought to use socat UNIX-LISTEN:mysocket,fork EXEC:print_counter and trigger it with socat UNIX:mysocket - <<<"p", but socat cant execute functions. Just script. And still, we need to run socat to background and let the script work further, which means it will start new isolated subshell. Trying to figure it out how to use synergy of socat, trap and/or netcat to achieve this... – Petras L Nov 02 '20 at 13:33

0 Answers0