Как вы меняете переменную в KSH if или case? - PullRequest
1 голос
/ 21 января 2011

Кто-нибудь знает, как установить переменную с глобальной областью видимости в операторе if, case или loop?

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

CFG_DIR=${WORK_DIR}/cfg
CFG_FILE=${CFG_DIR}/$1
NAME=$(echo $CFG_FILE | cut -f1 -d\.)

UPPER_BUS_NETWORK="H"

cat ${CFG_FILE} | grep -v ^\# |
while read CLINE
do
    PROPERTY=$(echo $CLINE | cut -f1 -d\=)
    VALUE=$(echo $CLINE | cut -f2 -d\=)

    if [ ${PROPERTY} = "UpperBusService" ]; then
        UPPER_BUS_SERVICE="${VALUE}"
    fi
    if [ ${PROPERTY} = "UpperBusNetwork" ]; then
        UPPER_BUS_NETWORK="${VALUE}"
    fi
done

echo ${UPPER_BUS_NETWORK}

1 Ответ

0 голосов
/ 21 января 2011

Вы уверены, что запускаете это в ksh? Какая версия? Ksh93 не настраивает подоболочку в цикле while. Bash, dash, ash и pdksh делают, хотя. Я не уверен насчет ksh88.

Сравнить

$ bash -c 'a=111; echo foo | while read bar; do echo $a; a=222; echo $a; done; echo "after: $a"'
111
222
after: 111

до

ksh -c 'a=111; echo foo | while read bar; do echo $a; a=222; echo $a; done; echo "after: $a"'
111
222
after: 222

Zsh дает тот же результат, что и ksh93.

К сожалению, pdksh не поддерживает подстановку процессов, а ksh93 поддерживает, но не при перенаправлении в done цикла while, поэтому обычное решение, которое работает в Bash, недоступно. Вот как это будет выглядеть:

# Bash (or Zsh)
while read ...
do
    ...
done < <(command)

Использование временного файла может быть единственным решением:

command > tmpfile
while read
do
    ...
done < tmpfile

Некоторые дополнительные примечания:

  • Вместо cat ${CFG_FILE} | grep -v ^\# до grep -v ^\# "${CFG_FILE}"
  • Обычно вы должны использовать read -r, чтобы обратные слеши обрабатывались буквально
  • Вместо NAME=$(echo $CFG_FILE | cut -f1 -d\.) вы должны иметь возможность делать что-то вроде NAME=${CFG_FILE%%.*} и VALUE=${#*=}; VALUE=${VALUE%%=*}
  • Переменные обычно должны выводиться в кавычки на выходе, например, в каждой ваших операторов echo и вашей cat команды
  • Я рекомендую использовать имена переменных в нижнем или смешанном регистре, чтобы избежать конфликта с переменными оболочки (хотя в вашем опубликованном коде их нет)
...