【问题标题】:How to check if an environment variable exists and get its value? [duplicate]如何检查环境变量是否存在并获取其值? [复制]
【发布时间】:2017-01-10 19:26:55
【问题描述】:

我正在编写一个 shell 脚本。在这个 shell 脚本中,我有一个变量,它要么采用默认值,要么采用环境变量的值。但是,环境变量不一定要存在。

例如,假设在运行脚本之前,我执行了以下操作:

export DEPLOY_ENV=dev

我如何告诉脚本搜索此环境变量,并将其值存储在脚本内的变量中。另外,如何告诉脚本如果这个环境变量不存在,就存储一个默认变量?

【问题讨论】:

  • printenv DEPLOY_ENV 应该这样做
  • 我试过了,出于测试目的 tempV=$(printenv LANG) 它没有打印任何东西,尽管系统具有 LANG 的值
  • 您的声明没有“打印”任何内容。它将环境变量LANG 的值存储到shell 变量tempV 中。至于此线程中的其他建议:请注意,没有它们,您可以区分您是否有环境变量或shell变量。如果这种区别真的很重要,应该考虑@sjsam 建议的解决方案。

标签: bash shell


【解决方案1】:

你可以使用parameter expansion:

${parameter:-word}

如果 parameter 未设置或为 null,则替换 word 的扩展。否则,参数的值被替换。

所以试试这个:

var=${DEPLOY_ENV:-default_value}

还有 ${parameter-word} 形式,它仅在 parameter 未设置时替换默认值(但在它为 null 时不替换)。

为了说明两者的区别:

$ unset DEPLOY_ENV
$ echo "'${DEPLOY_ENV:-default_value}' '${DEPLOY_ENV-default_value}'"
'default_value' 'default_value'
$ DEPLOY_ENV=
$ echo "'${DEPLOY_ENV:-default_value}' '${DEPLOY_ENV-default_value}'"
'default_value' ''

【讨论】:

  • 我的脚本无法读取DEPLOY_ENV的值,为了确保系统中存在环境变量,我在终端写了printenv DEPLOY_ENV,返回了正确的值。但是,脚本无法获取它。
【解决方案2】:

环境变量和脚本中的变量没有区别。环境变量只是在调用脚本之前在脚本之外定义的。从脚本的角度来看,变量就是变量。

您可以检查是否定义了变量:

if [ -z "$a" ]
then
    echo "not defined"
else 
    echo "defined"
fi

然后为未定义的变量设置默认值或执行其他操作。

-z 检查零长度(即空)字符串。请参阅man bash 并查找条件表达式部分。

如果您想避免未定义的变量以创造性的方式破坏事物,您还可以在脚本的开头使用set -u 使其在遇到未定义的变量时失败。

【讨论】:

    【解决方案3】:

    [ -z "${DEPLOY_ENV}" ] 检查DEPLOY_ENV 的长度是否为零。所以你可以运行:

    if [[ -z "${DEPLOY_ENV}" ]]; then
      MY_SCRIPT_VARIABLE="Some default value because DEPLOY_ENV is undefined"
    else
      MY_SCRIPT_VARIABLE="${DEPLOY_ENV}"
    fi
    
    # or using a short-hand version
    
    [[ -z "${DEPLOY_ENV}" ]] && MyVar='default' || MyVar="${DEPLOY_ENV}"
    
    # or even shorter use
    
    MyVar="${DEPLOY_ENV:-default_value}"
    

    【讨论】:

    • 您可以将"${DEPLOY_ENV}"替换为$DEPLOY_ENV
    • MyVar="$DEPLOY_ENV:-default_value" 在 bash 上对我不起作用,因此在可能的情况下用花括号 ${...} 包围通常更安全。
    • “甚至更短的使用时间”让我很开心!
    • 这可行,并且在极端情况下可能有价值,但它是一个重新发明的轮子......相反,请参阅为这个确切目标而制定的参数“扩展答案”。
    • @Finesse Always quote a tested string. tldp.org/LDP/abs/html/comparison-ops.html
    【解决方案4】:

    如果不关心未设置变量和空值变量的区别,可以使用default-value参数扩展:

    foo=${DEPLOY_ENV:-default}
    

    如果您确实在意差异,请去掉冒号

    foo=${DEPLOY_ENV-default}
    

    您还可以使用-v 运算符来显式测试是否设置了参数。

    if [[ ! -v DEPLOY_ENV ]]; then
        echo "DEPLOY_ENV is not set"
    elif [[ -z "$DEPLOY_ENV" ]]; then
        echo "DEPLOY_ENV is set to the empty string"
    else
        echo "DEPLOY_ENV has the value: $DEPLOY_ENV"
    fi
    

    【讨论】:

    • 请注意,-v 选项是在 Bash 4.2 中引入的,许多系统仍在运行旧版本的 Bash。
    • 即使bash 4.2 此时已经超过 5 年了;我倾向于将任何较旧的事物视为值得在问题中特别提及的特殊情况。
    • 时间过得真快……
    • @anon58192932 那是因为您使用的是/bin/bash,它在 Mac OS X 上只有 3.2.x 版本。
    • 切换到 linux 的原因列表获得了另一个条目...谢谢@chepner
    【解决方案5】:
    NEW_VAR=""
    if [[ ${ENV_VAR} && ${ENV_VAR-x} ]]; then
      NEW_VAR=${ENV_VAR}
    else
      NEW_VAR="new value"
    fi
    

    【讨论】:

      猜你喜欢
      • 2012-04-28
      • 1970-01-01
      • 2011-06-21
      • 2011-01-21
      • 2013-08-12
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      相关资源
      最近更新 更多