переменная остается пустой после проблемы цикла в сценариях оболочки - PullRequest
0 голосов
/ 16 сентября 2011

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

#!/bin/bash

list=""

list=`mtx -f /dev/sg2 status | while read status
do
    result=$(echo ${status} | grep "Full")
    if [ -z "$result" ]; then
        continue
    else
       echo $(echo ${result} | cut -f3 -d' ' | tr -d [:alpha:] | tr -d [:punct:])
    fi
done`

echo ${list}

for haha in ${list}
do
    printf "current slot is:%s \n" ${haha}
done

Программа выполняет то, что выполняет mtx -f /dev/sg2 status и переходит к каждой строке и проверяет, заполнен ли диск.Если в этой строке указано «Full», я запишу номер слота в этой строке и добавлю list.

Обратите внимание, что я ставлю обратную кавычку после list= в строке 6,и после этого он охватывает весь цикл while.Причина неясна для меня, но я получил это использование, просто прибегая к помощи.Говорят, что цикл while откроет отдельную оболочку или что-то в этом роде, поэтому, когда цикл while будет выполнен, все, что вы объедините в цикле, будет потеряно, поэтому в моей первоначальной реализации list все еще пусто послецикл while.

Мой вопрос таков: даже если приведенный выше код работает нормально, он выглядит довольно хитрым для других, и, что еще хуже, я могу сделать только ОДИН list после завершения цикла.Есть ли лучший способ исправить это, чтобы я мог извлечь больше информации из цикла?Например, если мне нужно list2 для хранения других значений?Спасибо.

Ответы [ 2 ]

0 голосов
/ 01 декабря 2011

См. это объяснение . Когда задействован канал, код while read... выполняется не в вашей текущей оболочке, а в подоболочке (дочерний процесс, который не может обновить переменные текущего процесса (окружения / оболочки)).

Выберите один из перечисленных обходных путей, чтобы цикл while read... выполнялся в текущей оболочке.

0 голосов
/ 21 сентября 2011

Ваш сценарий оболочки работает.Если вы хотите получить две единицы информации на одну строку вместо одной, вам придется изменить эту строку

echo $(echo ${result} | cut -f3 -d' ' | tr -d [:alpha:] | tr -d [:punct:])

, чтобы объединить нужные значения, разделенные запятой или любым другим «специальным» символом.Тогда вы можете разобрать свой список следующим образом:

for haha in ${list}
do
   printf "current slot is:%s, secondary info:%s \n" $(echo ${haha} | cut -f1 -d',') $(echo ${haha} | cut -f2 -d',')
done
...