My objective is to measure the current system load as a percentage, and then blink an LED for that percentage of a second. To do this I had a function "get_load" which measures the average load over a second, in a while loop, and was running this as a subshell like get_load &
. The get_load function is also defining a global LASTLOAD variable after each iteration. After that I have a flip_led function which turns the led on, sleeps for 1-LASTLOAD seconds, turns it off and then sleeps for 1-LASTLOAD seconds (should total to one)
The problem is, the global LASTLOAD variable never seems to be updated, or at least doesnt propagate into the flip_led loop.
My question is how can I run a loop in a subshell, but have that subshell influence global variables in the initial script?
Heres the script itself
readonly LEDTRIGGER="/sys/class/leds/led0/trigger"
readonly LEDBRIGHTNESS="/sys/class/leds/led0/brightness"
LASTLOAD=0
ISRUNNING=1
function get_load() {
# Define all local variables used in function
local user1 sys1 idle1 user2 sys2 idle2 u s i load
while [[ $ISRUNNING -eq 1 ]]; do
# Get initial usage
read -r user1 sys1 idle1 \
<<<"$(grep 'cpu ' /proc/stat | awk '{print $2" "$4" "$5}')"
sleep 1
# Get usage after a second has passed
read -r user2 sys2 idle2 \
<<<"$(grep 'cpu ' /proc/stat | awk '{print $2" "$4" "$5}')"
u=$(echo "scale=4;$user2-$user1" | bc)
s=$(echo "scale=4;$sys2-$sys1" | bc)
i=$(echo "scale=4;$idle2-$idle1" | bc)
# Return the average usage over the last second rounded
load=$(echo "scale=4;($u+$s)*100/($u+$s+$i)" | $BC)
# loadint=$(echo "($load+0.5)/1" | $BC)
percent=$(echo "scale=4;$load/100" | $BC)
# echo "load: $load, loadint: $loadint, percentage: $percent"
# return "$loadint"
# echo "$percent"
LASTLOAD=$percent
echo "$LASTLOAD"
done
}
function flip_led() {
while [[ $ISRUNNING -eq 1 ]]; do
local remainder
remainder=$(echo "scale=2;1-$LASTLOAD" | $BC)
echo 1 | sudo tee $LEDBRIGHTNESS >/dev/null
echo "led on for $LASTLOAD, off for $remainder"
$SLEEP "$LASTLOAD"
echo 0 | sudo tee $LEDBRIGHTNESS >/dev/null
$SLEEP "$remainder"
done
}
echo none | sudo tee $LEDTRIGGER >/dev/null
echo 0 | sudo tee $LEDBRIGHTNESS >/dev/null
get_load &
flip_led &