Я пишу сценарий в AIX 5.3, который будет перебирать выходные данные df
и проверьте каждый том по другому файлу конфигурации. Если том появляется в файле конфигурации, он установит флаг, который понадобится позже в сценарии. Если в моем файле конфигурации есть только один столбец, и я использую for
цикл, это отлично работает. Однако моя проблема в том, что если я использую while read
цикл для заполнения более одной переменной в строке, любые переменные, которые я установил между while
и done
отбрасываются.
Например, предположим, что содержимое /netapp/conf/ExcludeFile.conf представляет собой набор строк, содержащих по два поля каждая:
volName="myVolume"
utilization=70
thresholdFlag=0
grep volName /netapp/conf/ExcludeFile.conf | while read vol threshold; do
if [ $utilization -ge $threshold ] ; then
thresholdFlag=1
fi
done
echo "$thresholdFlag"
В этом примере thresholdFlag всегда будет равен 0, даже если том отображается в файле и его использование превышает пороговое значение. Я мог бы добавить echo "setting thresholdFlag to 1"
там вы увидите эхо, и в конце все равно будет эхо 0.
Есть ли чистый способ сделать это? Я думаю, что мой цикл while выполняется в подоболочке, и изменения, которые я вношу в переменные, на самом деле вносятся в локальные переменные, которые отбрасываются после done
.
Зоредаш указал мне на это в чате, а Поиге упомянул об этом в своем ответе: эту проблему можно решить с помощью подоболочки.
Когда мне пришлось сменить for
цикл, который считывает одну переменную из моего grep за раз в while read var1 var2
В цикле, который позволил мне читать несколько переменных, я смог привязать временные переменные, которыми я манипулировал в цикле while, используя круглые скобки для определения явной подоболочки. Вот пример:
sum=0
grep volume configfile | head -n1 | (while read var1 var2; do
let sum=var1+var2
done
echo "The sum is $sum.")
Без круглых скобок вы всегда будете выводить сумму, равную 0. С их помощью вы выводите сумму первых двух значений в первой совпадающей строке вашего grep.
Кроме того, как указывает Пойдж в другом ответе, вы можете использовать подоболочку для заполнения переменной в области видимости следующим образом:
var=$( cat file | while read a b; do
sum=a+b
echo "$sum"
done)
echo "$var"
В этом случае значение var, которое вы выводите в конце, будет последней суммой, которую вы вычислили в своем цикле, даже если сумма была уничтожена в конце подоболочки.
По крайней мере, двумя способами - вернуть код ошибки и проверить его или обернуть код вспомогательной оболочки:
Res=$(cat /etc/hosts | while read h _rest; do
[ "$h" = 'fe00::0' ] && echo 'Found'
done
)
echo $Res