String Bash环境变量存在性检查重构

String Bash环境变量存在性检查重构,string,bash,environment-variables,String,Bash,Environment Variables,我需要检查是否存在环境变量列表。 现在我在做这件事,这当然是一个非常愚蠢的解决方案: 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 ch

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

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 var in MONGOLAB APP_PORT ENV; do
    [[ -z "${!var}" ]] && echo "Missing \$$var"
done

您可以对
循环使用
,并在此处检查所有循环:

for var in MONGOLAB APP_PORT ENV; do
    [[ -z "${!var}" ]] && echo "Missing \$$var"
done
另一个选择是:

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 [[ "$1" != *[^0-9]* ]]; then
    st="$1"
    shift
  fi
  warn "$@"
  exit "$st"
}
我鼓励您进一步阅读此函数,并可能使用最适合您需要的不同版本。 请注意,
die
使用名为
warn
的函数,您可以在上面的同一链接中找到该函数

p.S.

请注意,按照惯例,环境变量(
PATH
EDITOR
SHELL
,…)和内部SHELL变量(
BASH\u VERSION
RANDOM
,…)完全大写。所有其他变量名称应为小写。自从 变量名区分大小写,此约定避免意外重写环境和内部变量。

另一个选项是:

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 [[ "$1" != *[^0-9]* ]]; then
    st="$1"
    shift
  fi
  warn "$@"
  exit "$st"
}
我鼓励您进一步阅读此函数,并可能使用最适合您需要的不同版本。 请注意,
die
使用名为
warn
的函数,您可以在上面的同一链接中找到该函数

p.S.

请注意,按照惯例,环境变量(
PATH
EDITOR
SHELL
,…)和内部SHELL变量(
BASH\u 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

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
作为一种功能,可供选择
是否需要区分未设置的变量和具有空值的变量?是否需要区分未设置的变量和具有空值的变量?