匹配变量值并设置默认值

匹配变量值并设置默认值

我有一个变量可以采用任何值"SUBSCRIPT", "ITERATE", "COUNTER"

如何测试其中任何一个中的变量,并"SUBSCRIPT"在不匹配的情况下默认为?

我想要一个紧凑的形式并提出了以下内容

  [[ "${signal}" == "SUBSCRIPT" || "${signal}" == "ITERATE" ||
     "${signal}" == "COUNTER" ]] || signal="SUBSCRIPT"

前面提到的会失败吗?

答案1

虽然你的代码应该工作,有几种可以说更简洁的方法来编写相同类型的操作。

第一种方法可以在任何 POSIX shell 中工作并使用标准case语句:

case $signal in
    SUBSCRIPT|ITERATE|COUNTER)
        # do nothing
        ;;
    *)
        signal=SUBSCRIPT
esac

case语句将变量的值设置为字符串,SUBSCRIPT除非它已经具有三个值之一SUBSCRIPTITERATECOUNTER

您可以将其写在一行上,如下所示:

case $signal in (SUBSCRIPT|ITERATE|COUNTER) ;; (*) signal=SUBSCRIPT; esac

您还可以if在以下位置使用更紧凑的语句bash

if [[ $signal != @(SUBSCRIPT|ITERATE|COUNTER) ]]; then
    signal=SUBSCRIPT
fi

或者,如果适用,使用短路评估,

[[ $signal == @(SUBSCRIPT|ITERATE|COUNTER) ]] || signal=SUBSCRIPT

这使用扩展的通配模式来测试变量的值是否与提到的三个值中的任何一个匹配(语法是从 shell 继承的ksh)。如果它match (测试在代码的第一个变体中被反转,我||在第二个变体中使用),变量的值被重置为 string SUBSCRIPT

答案2

对于仅三个有效值,现有答案提供了很好的方法。随着数量的增加,这可能会派上用场:

signal=foo
default='SUBSCRIPT'
if [ -n "$signal" ]; then
    valid_values=(
        SUBSCRIPT ITERATE COUNTER
    )

    declare -A tmpar=()
    for str in "${valid_values=[@]}"; do
        tmpar[$str]=1
    done
    test -n "${tmpar["$signal"]}" || signal="$default"
else
    signal="$default"
fi

答案3

SUBSCRIPT如果您的意思是希望变量在未设置/为空时被赋予以下值:

ITERATE=${ITERATE:-$SUBSCRIPT}

相关内容