如何更改KSH if或case语句中的变量?

时间:2011-01-20 21:01:17

标签: variables if-statement ksh

有没有人知道如何在KSH 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 :(得分:0)

你确定你在ksh中运行吗?哪个版本? Ksh93没有在while循环中设置子shell。但是,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命令
  • 我建议使用小写或混合大小写变量名来避免与shell变量发生冲突(尽管你发布的代码中没有变量)