我有一个带有来自命令行参数的变量的脚本。我想检查其值是否为dev
,beta
或prod
之一。我有一个以下代码片段:
#!/usr/bin/env bash
ENV_NAME=$1
echo "env name = $ENV_NAME"
ENVIRONMENTS=('dev','beta','prod')
if [[ $ENVIRONMENTS =~ $ENV_NAME ]]; then
echo 'correct'
exit
else
echo 'incorrect'
exit
fi
当我运行我的脚本时,无论我传递哪些参数:./script.sh beta
或./script.sh
或./script.sh whatever
,我总是会回复correct
。我的剧本有什么问题?
答案 0 :(得分:2)
for i in ${ENVIRONMENTS[@]}; do
if [[ $i = $ENV_NAME ]]; then
echo "correct"
exit
fi
done
echo 'incorrect'
exit
答案 1 :(得分:2)
ENV_NAME=dev
ENVIRONMENTS="dev|beta|prod"
[[ $ENV_NAME =~ ^($ENVIRONMENTS)$ ]] && echo ${BASH_REMATCH[1]}
dev
答案 2 :(得分:2)
每个人都有一个很好的建议,但还有另一种方式。它比使用正则表达式更有效,并且可能比使用循环更有效,尤其是在具有更多值时。唯一的问题是这需要Bash 4.0或更新版本。
declare -A ENVIRONMENTS=([dev]=. [beta]=. [prod]=.)
if [[ -n ${ENVIRONMENTS["$ENV_NAME"]} ]]; then
...
答案 3 :(得分:0)
我喜欢隐藏丑陋的实现细节,特别是在涉及bash时。
function catPipe() # concatenate all arguments with a pipe character
{
local IFS='|'
echo "$*"
}
function matchList()
{
local needle="$1"
shift
local stack=$(catPipe "$@")
[[ "$needle" =~ ^($stack)$ ]]
}
如果你不喜欢有子贝壳,请使用:
function matchList()
{
local needle="$1"
shift
IFS='|' eval 'local stack="$*"'
[[ "$needle" =~ ^($stack)$ ]]
}
受konsolebox'解决方案的启发,我使用^($ var)$语法来避免部分匹配。首先它看起来像这样:
function matchList()
{
local needle="$1"
shift
local stack="$@"
[[ ${stack[@]} =~ "$needle" ]] # would allow partial machtes like 'eta'
}
可以使用字符串,数组或单个项目调用该函数:
variants='dev beta prod'
varArray=(dev beta prod)
matchList prop $variants && echo 'prop: match!'
matchList beta $variants && echo 'beta: match!'
matchList beta ${varArray[@]} && echo 'beta: match!'
matchList eta alpha beta gamma && echo 'eta: match!'
# Output:
beta: match!
beta: match!
或者原始示例:
matchList $ENV_NAME ${ENVIRONMENTS[@]} && echo 'correct'
旁注:我试图用案例提出解决方案,因为它自然符合要求。 它有效,但我无法弄清楚是否/如何在声明中使用环境。
ENV_NAME='beta'
ENVIRONMENTS='dev|beta|prod'
case $ENV_NAME in (dev|beta|prod) echo 'correct' ;; (*) echo 'incorrect' ;; esac