Shahbaz
Shahbaz

Reputation: 47493

How to change a global variable and have a previous function see it?

To avoid the XY problem, here's what I'm trying to do:

terminate=0
terminated=0

monitor_something() {
  while [ "$terminate" -eq 0 ]; do
    echo "Doing stuff"
    sleep 1
  done
  terminated=1
}

monitor_something &
show_interface

terminate=1
while [ "$terminated" -eq 0 ]; do sleep 0.2; done

The idea is to run a loop in the background that takes care of some things (for example restart an erroneous service or whatever) and then show the user interface. When the user interface exits, I need to wait for monitor_something to properly exit without being in the middle of something.

The problem is that monitor_something doesn't see the change in terminate. Is this a problem because & is creating a subshell? Here's a simple script for testing purposes:

#! /bin/bash

var=10

func() {
  while true; do
    echo "var: $var"
    sleep 1
  done
}

func &

echo "Init"
sleep 2
echo "Changing var to 5"
var=5
sleep 2
echo "Done"

kill -TERM %1

My question is, how can I make that background function see the change in the global variable and respond to it? In general, what can I use to do what I'm trying to do? Could I for example tell monitor_something to ignore the TERM signal but set a variable instead and exit when that variable becomes 1?

Upvotes: 0

Views: 47

Answers (1)

chepner
chepner

Reputation: 530970

monitor_something() {
  stop=0
  trap 'stop=1' TERM
  while [ $stop -eq 0 ]; do
    echo "Doing stuff"
    sleep 1
  done
}

monitor_something & MONITOR_PID=$!
show_interface

kill $MONITOR_PID
wait $MONITOR_PID

The call to kill replaces the terminate variable, and the call to wait replaces the terminated variable.

Upvotes: 1

Related Questions