Bash env var 存在检查重构

Bash env var existence check refactor

我需要检查是否存在环境变量列表。 现在我正在做这当然是一个非常愚蠢的解决方案:

if [ -z "$MONGOLAB" ]; then
  echo "Missing $MONGOLAB"
  exit 1
fi

if [ -z "$APP_PORT" ]; then
  echo "Missing $APP_PORT"
  exit 1
fi

if [ -z "$ENV" ]; then
  echo "Missing $ENV"
  exit 1
fi
... more checks here

我该如何重构它? :)

您可以使用 for 循环并在那里检查所有这些:

for var in MONGOLAB APP_PORT ENV; do
    [[ -z "${!var}" ]] && echo "Missing $$var"
done

另一种选择是:

[[ $MONGOLAB && $APP_PORT && $ENV ]] || exit 1

如果你碰巧 运行 对多个变量进行长时间的健全性检查,并且代码变得丑陋,我建议使用 @anubhava 的解决方案,即更优雅。

我通常使用 die 函数而不是 exit 1 以在人类可读描述和退出状态代码方面对用户更具描述性:

##
# die (optional status version): Print a message to
# stderr and exit with either the given status or
# that of the most recent command.
# Usage: some_command || die [status code] "message" ["arguments"...]
#
die() {
  local st="$?"
  if [[ "" != *[^0-9]* ]]; then
    st=""
    shift
  fi
  warn "$@"
  exit "$st"
}

此函数取自 Common utility functions (warn, die),我鼓励您进一步阅读,并可能使用最适合您需求的不同版本。 请注意,die 使用了一个名为 warn 的函数,您可以在上面的 link 中找到它。

P.S.

请注意,按照惯例,环境变量(PATHEDITORSHELL、...)和内部 shell 变量(BASH_VERSION , RANDOM, ...) 全部大写。所有其他变量名都应该是小写的。自从 变量名称区分大小写,此约定可避免意外覆盖环境和内部变量。

这是一种方法:

#!/bin/bash
set -e

err=
for v in MONGOLAB APP_PORT ENV; do
    err="$err${!v-$v not set$'\n'}"
done
if test -n "$err"
then printf "%s" "$err" >&2; exit 1
fi

echo "All environment variables set"
exit 0

它改进了您的解决方案,因为它立即通知用户所有必需但未设置的变量,避免了典型的烦人的来回脚本来满足它。

我们通过为每个未设置的变量添加一条消息来建立错误值,然后如果它是非空的,打印它并中止。

${!v-...} 构造是一种间接 - 如果有一个名为 $v 的变量,则什么都不替换,否则替换我们的消息。

替代版本

这使用所需变量的数组,并构建单行错误消息:

#!/bin/bash
set -e

required_vars=(MONGOLAB APP_PORT ENV)
missing_vars=''
for v in "${required_vars[@]}"; do
    missing_vars="$missing_vars${!v-$v }"
done
if test -n "$missing_vars"
then printf "Unset required variables: %s\n" "$missing_vars" >&2; exit 1
fi

echo "All environment variables set"
exit 0

备选方案,作为函数

#!/bin/bash
set -e

check_vars() {
    local m=''
    for v in "$@"; do
        m="$m${!v-$v }"
    done
    if test -n "$m"
    then printf "Unset required variables: %s\n" "$m" >&2; return 1
    fi
}

check_vars MONGOLAB APP_PORT ENV

echo "All environment variables set"
exit 0