Изменение глобальной переменной из цикла подоболочек в bash

#bash #shell #loops #scripting #subshell

#bash #оболочка #циклы #сценарии #подоболочка

Вопрос:

Моя цель состоит в том, чтобы измерить текущую загрузку системы в процентах, а затем мигать светодиодом в течение этого процента секунды. Для этого у меня была функция «get_load», которая измеряет среднюю нагрузку за секунду в цикле while и запускала ее как подоболочку get_load amp; . Функция get_load также определяет глобальную переменную LASTLOAD после каждой итерации. После этого у меня есть функция flip_led, которая включает индикатор, переходит в режим ожидания в течение 1 секунды последней загрузки, выключает его, а затем переходит в режим ожидания в течение 1 секунды ПОСЛЕДНЕЙ ЗАГРУЗКИ (всего должно быть до одного)

Проблема в том, что глобальная переменная LASTLOAD, похоже, никогда не обновляется или, по крайней мере, не распространяется в цикл flip_led.

Мой вопрос в том, как я могу запустить цикл в подоболочке, но чтобы эта подоболочка влияла на глобальные переменные в исходном сценарии?

Вот сам скрипт

 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 amp;
flip_led amp;

  

Комментарии:

1. Пожалуйста, покажите свой скрипт.

2. @MarkSetchell сделали, извините!

3. Практически все переменные оболочки являются глобальными в обычном смысле этого слова: видимыми для любой функции в том же процессе . Вы спрашиваете о межпроцессном взаимодействии , а это совсем другое дело.

4. how can I run a loop in a subshell, but have that subshell influence global variables in the initial script? Любым способом межпроцессного взаимодействия.

5. О, это именно то, что я искал, спасибо, что указали мне правильное направление! Каков был бы наилучший способ отметить эту проблему как решенную?