为 Bash 数组创建 contains 函数

为 Bash 数组创建 contains 函数

我有这个 contains 函数,它应该检查数组是否具有特定值。数组本身作为第一个参数传递,值是第二个参数。

#!/usr/bin/env bash

set -e;

branch_type="${1:-feature}";
arr=( 'feature', 'bugfix', 'release' );

contains() {
    local array="$1"
    local seeking="$2"
    echo "seeking => $seeking";
#    for v in "${!array}"; do
     for v in "${array[@]}"; do
        echo "v is $v";
        if [ "$v" == "$seeking" ]; then
         echo "v is seeking";
            return 0;
        fi
    done
   echo "returning with 1";
   return 1;
}

if ! contains "$arr" "$branch_type"; then
    echo "Branch type needs to be either 'feature', 'bugfix' or 'release'."
    echo "The branch type you passed was: $branch_type"
    exit 1;
fi

echo "all goode. branch type is $branch_type";

如果您在没有任何参数的情况下运行脚本,它应该可以工作,因为默认值为“feature”,但由于某种原因,搜索不匹配任何内容。我没有收到错误,但包含功能未按预期工作。

当我运行不带任何参数的脚本时,我得到:

seeking => feature
v is feature,
returning with 1
Branch type needs to be either 'feature', 'bugfix' or 'release'.
The branch type you passed was: feature

现在这很奇怪

答案1

笔记:我将展示如何解决这个问题,以便它可以在 Bash 4 中运行。


我认为您将数组传递到函数中的方式不正确:

$ cat contains.bash
#!/usr/bin/env bash

branch_type="${1:-feature}";
arr=('feature' 'bugfix' 'release');

contains() {
    local array=$1
    local seeking="$2"
    for v in ${!array}; do
        if [ "$v" == "$seeking" ]; then
            return 0;
        fi
    done
   return 1;
}

if ! contains arr $branch_type; then
    echo "Branch type needs to be either 'feature', 'bugfix' or 'release'."
    echo "The branch type you passed was: $branch_type"
    exit 1;
fi

echo "the array contains: $branch_type";

我稍微改变了一些东西,现在看起来可以工作了:

$ ./contains.bash
the array contains: feature

变化

我只对你的原始脚本做了两处修改。我更改了函数contains()的调用方式,以便它传递arr此行的数组的裸名称:

if ! contains arr $branch_type; then

contains()并在使用传入参数设置数组的函数内更改了这一行,从局部变量的设置中去掉引号array

    local array=$1

参考

答案2

Bash3 的惯用法如下所示:

#!/usr/bin/env bash

set -e; 

branch_type="${1:-feature}";
arr=( 'feature' 'bugfix' 'release' );

contains() {

    local seeking="$1"
    shift 1;
    local arr=( "$@" )

    for v in "${arr[@]}"; do
        if [ "$v" == "$seeking" ]; then
            return 0;
        fi
    done
   return 1;
}

if ! contains "$branch_type" "${arr[@]}"; then
    echo "Branch type needs to be either 'feature', 'bugfix' or 'release'."
    echo "The branch type you passed was: $branch_type"
    exit 1;
fi

echo "the array contains: $branch_type";

真正的挂断是我试图这样做:

local seeking="$1"
local arr=( "$2" )

但这是必要的:

local seeking="$1"
shift 1;
local arr=( "$@" )

相关内容