【问题标题】:How do you change a variable in a KSH if or case statement?如何更改 KSH if 或 case 语句中的变量?
【发布时间】:2011-06-12 18:12:11
【问题描述】:

有人知道如何在 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}

【问题讨论】:

    标签: variables if-statement ksh


    【解决方案1】:

    你确定你在 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 支持,但在重定向到 while 循环的 done 时不支持,因此无法在 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=${CFG_FILE%%.*}VALUE=${#*=}; VALUE=${VALUE%%=*} 来代替NAME=$(echo $CFG_FILE | cut -f1 -d\.)
    • 通常应该在输出中引用变量,例如在每个的 echo 语句和 cat 命令中
    • 我建议养成使用小写或混合大小写变量名的习惯,以避免与 shell 变量冲突(尽管您发布的代码中没有)

    【讨论】:

      猜你喜欢
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-23
      • 2014-02-02
      • 2021-06-30
      相关资源
      最近更新 更多