#linux #bash #loops #infinite-loop #updating
#linux #bash #циклы #бесконечный цикл #обновление
Вопрос:
Я увеличиваю значение переменной в первом цикле и использую ее во втором цикле.
Моя проблема: переменная не изменяется во втором цикле. (Это пример, я знаю, что могу переместить код, который изменяет значение, из цикла в функцию, но у меня есть программа с несколькими функциями и несколькими циклами).
Мой вопрос: как обновить значение переменной (увеличивающееся внутри первого цикла while) во втором цикле while?
Вот иллюстрация (первый цикл увеличивает значение counter_value, но второй цикл остается равным «1») :
#!/bin/bash
counter_value="1"
function Print_counter_value () {
echo $counter_value ; }
#_____FIRST LOOP_____
while : ; do # infinite loop
#echo first loop works
counter_value=$[$counter_value 1]
echo $counter_value 1st_loop amp; sleep 2
done amp;
#_____SECOND LOOP_____
while : ; do # infinite loop
#echo second loop works
Print_counter_value amp; sleep 1
done amp;
Спасибо!
Комментарии:
1. Переместить код, который изменяет значение, из цикла в функцию?
2. @choroba Спасибо за ваш ответ, но это пример. На самом деле у меня есть несколько циклов, вызывающих одну и ту же переменную, поэтому для меня лучше обновлять переменную в каждом цикле, чем перемещать код 50 раз.
3. Процессы Bash не используют и не могут совместно использовать переменные. Вам пришлось бы записать значение в файл / канал / fifo или что-то в этом роде
Ответ №1:
Строка, которая увеличивает переменную:
((counter_value ))
Нет необходимости переводить второй цикл в фоновый режим. Сохранение переменной в файл немного неуклюже, но это работает.
#!/bin/bash
counter_value=1
file="/tmp/temp$$"
echo "counter_value=$counter_value" > "$file"
function Print_counter_value () {
echo $counter_value ; }
#_____FIRST LOOP_____
while : ; do # infinite loop
. "$file"
((counter_value ))
echo "counter_value=$counter_value" > "$file"
sleep 2
done amp;
#_____SECOND LOOP_____
while : ; do # infinite loop
. "$file"
Print_counter_value amp; sleep 1
done
Комментарии:
1. Спасибо вам за ответ. Не могли бы вы, пожалуйста, объяснить немного больше? Я заменил строку, содержащую counter_value=$[$counter_value 1], на ((counter_value ), но это не работает.
2. Вторые циклы по-прежнему придерживаются значения 1
Ответ №2:
Вы не можете сделать это с переменными.
Используя amp;
знак в конце каждого цикла, вы разветвляете процесс, то есть создаете новый процесс, который будет запускать код цикла. Каждый из этих двух новых процессов будет иметь свои собственные адресные пространства ==> counter_value
отличается от адресного пространства в родительском процессе. Запись в него не изменит его значение ни в родительском процессе, ни в дочернем процессе. Будет обновлено только локальное значение.
«Я знаю, что могу переместить код, который изменяет значение, из цикла в функцию»
Перемещение этого кода ничего не изменит. Оба дочерних процесса будут вызывать эту функцию, но каждый будет читать / записывать свою собственную counter_value
и изменения первого цикла не будут отражены в том, что считывает второй цикл.
Чтобы увидеть / «поверить», что это другой процесс, вы можете напечатать внутри циклов переменные $$
(PID) и $BASHPID
(PID дочернего процесса или вложенной оболочки). Вы заметите, что они отличаются друг от друга.
Если вы хотите, чтобы эти процессы обновляли данные друг друга, вам придется использовать, как упоминалось в комментариях, другие методы. И имейте в виду, что вы можете столкнуться с проблемами параллелизма.