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.
请注意,按照惯例,环境变量(PATH
、EDITOR
、SHELL
、...)和内部 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
我需要检查是否存在环境变量列表。 现在我正在做这当然是一个非常愚蠢的解决方案:
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.
请注意,按照惯例,环境变量(PATH
、EDITOR
、SHELL
、...)和内部 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