Bashは関数内にarrayというパラメータを生成します。

Bashは関数内にarrayというパラメータを生成します。

渡された名前を使用して配列に書き込む関数を作成しようとしています。以下のbash機能が提供されます。

function writeToArray {
    local name="$1"
    echo "$name"
    declare -a "$name"
    ${name[0]}="does this work?"      
}

次のように実行します。

writeToArray $("test")

2 つのエラーが発生します。

bash: declare: `': not a valid identifier
=does this work?: command not found

私はこれができると期待しています:

writeToArray $("test")
for item in "${test[@]}"; do
        echo "item"
        echo "$item"
done

次のように印刷する必要があります。

item
does this work?

配列(関数の外部で名前付きtest配列を読み取ることができるように例で名前付き)に書き込むように正しく設定するにはどうすればよいですか?test

答え1

namerefを使用してこれを行うことができます。

writeToArray() {
    local -n writeToArray_name="$1"
    writeToArray_name[0]="does this work?"      
}

テスト:

bash-5.0$ test[123]=qwe
bash-5.0$ writeToArray test
bash-5.0$ typeset -p test
declare -a test=([0]="does this work?" [123]="qwe")

bashまだnamerefがない以前のバージョンでは、次のものを使用できますeval

writeToArray() {
  eval "$1[0]='does this work?'"
}

引数writeToArrayとともに呼び出して引数として渡し、シェル言語でコードとして呼び出すと、配列インデックス0の要素に割り当てられます(連想配列でも機能し、スカラー変数は配列に変換されます)。testevaltest[0]='does this work?'evaldoes this work?test

これは、リストコンテキストで$("test")コマンド出力と分割+グローブをキャプチャして拡張するための構文です。 (別名引数が渡されないと出力は生成されません)空の文字列に展開され、Split + globは結果を提供しません。testtest[$("test")

ここでこれ名前writeToArrayしたがって、 に渡す変数はtestその内容("$test")でもなく、同じ名前のコマンド出力( )でもなく、"$(test)"Split + globの影響を受ける同じ名前のコマンド出力でもありません。あなたの試みとして。$("test")

関連情報