BASH / DASH:配列を関数に渡す最善の方法は何ですか?

BASH / DASH:配列を関数に渡す最善の方法は何ですか?

私はこの配列を持っています:

PARAMETERS_OF_COMPONENTS[1]="component1"
PARAMETERS_OF_COMPONENTS[2]="component21 component22 component23"
PARAMETERS_OF_COMPONENTS[3]="component3"
PARAMETERS_OF_COMPONENTS[4]="component41 component42 component43"

その配列をこの関数に渡したいと思います。

foo()
{
    local param1="$1"
    local param2="$2"
    local array_param="$3"
    . . .

    echo "${PARAMETERS_OF_COMPONENTS[@]}"
}

このように配列を渡すとき:

foo "$param1" "$param2" "${PARAMETER_OF_COMPONENTS[@]}"

その後、関数は以下を印刷します。

component1

また、配列を渡すためにさまざまな方法を試しましたが、まだ正しい解決策を見つけることができませんでした。

配列を関数に正しく渡すには?また、ソリューションはダッシュと互換性がなければなりません(少なくともbashismを除く)。

UPD @Kusalanandaは、Dashが配列をサポートしていないと説明しました。明確にしていただきありがとうございます。

もう一つ質問します。$1フォームに直接渡さずに$2グローバル変数を使用せずに関数に多くの引数を渡す方法は何ですか?いくつかのアイデアがありますが、あなたのアプローチを聞きたいです。

私の使命は、関数をあるファイルから別のファイルに移動することです。関数はグローバル変数を使用します。グローバル変数を使用したくありません。それでは、最も正しい方法でこれを行う方法は何ですか?

答え1

sh配列とキーワードをサポートしていないシェルでは、関数で配列を引き続きlocal使用できます$@。最初の2つのパラメータを選択してshift 2から、それを使用して$@残りのパラメータを保存できます。

foo () {
    arg1=$1
    arg2=$2

    shift 2  # shift $3 into $1, $4 into $2 etc.

    for n in "$@"; do    # or just: for n do
        printf 'Other argument: %s\n' "$n"
        # other code acting on "$n"
    done
}

foo "arg1" "arg2" "arg3" "arg4"

関数がグローバル変数を変更する必要がなく、変数の名前空間を不要な変数で汚染したくない場合は、すべての変数を( ... )ローカル変数にするのではなく、関数の本文をラップします。{ ... }


元のデータを使用し、foo上記のように宣言します。

set -- "component1" \
       "component21 component22 component23" \
       "component3" \
       "component41 component42 component43"

foo "$param1" "$param2" "$@"

配列とをサポートするシェルはlocalまったく同じことを行いますが、関数はとして宣言された変数を使用しようとしますが、呼び出しは次のようlocalになります。

foo "arg1" "arg2" "${myarray[@]}"

で複数の配列を渡すには、関数bashで名前参照を使用します(bash4.3以降が必要)。

foo () {
   local arg1=$1
   local arg2=$2
   local -n arr1=$3
   local -n arr2=$4

   for n in "${arr2[@]}"; do ...; done
}

foo "arg1" "arg2" myarray1 myarray2

関数の対応する名前参照変数と同じ名前の関数に配列変数を渡すことができないことに注意してください(これはバグだと思います。動作しますksh93)。

関連情報