Bash配列の包含関数の作成

Bash配列の包含関数の作成

配列に特定の値があるかどうかを確認する関数が含まれています。配列自体は最初のパラメータとして渡され、値は2番目のパラメータとして渡されます。

#!/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

多様性

元のスクリプトで2つのことが変更されました。次の行を使用して、配列のデフォルト名を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=( "$@" )

関連情報