Назад | Перейти на главную страницу

В то время как цикл читает несколько строк из grep

Я пишу сценарий в 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