私はbash連想配列を参照として関数に渡し、関数が完了した後にネイティブスクリプトで変更されたことを確認できるように努めています。最も直接的な方法のようなものを見つけましたここ私の場合を除いて、機能は実行中です。バックグラウンドで。私が何をしても、この場合、上記のリンクされたソリューションは機能しないようです。
以下のコードスニペットでは、上記のリンクで動作するサンプルコードを取得し、関数呼び出しに「&」を追加し、次の行に「wait」を追加して問題をできるだけ簡単に説明しました。
Bashは基本的なスクリプトとバックグラウンド機能が互いに踏むのを防ぐことを試みているようですが、それを解決する方法がわかりません。
サンプルコード:
foo () {
declare -n fooarray="$1"
fooarray["fookey"]=foovalue
}
declare -A myarray
myarray["mainkey"]=mainvalue
foo myarray &
wait
for key in "${!myarray[@]}"; do
printf '%s = %s\n' "$key" "${myarray[$key]}"
done
出力:
bash-4.4$ ./test.sh
mainkey = mainvalue
どんな助けでも大変感謝します。私は配列の内容をファイルに書き込んでから再解析するなど、愚かなことをすることを知っていますが、これよりもエレガントな解決策を期待しています。
ベストアンサー1
重要な要約:バックグラウンドで実行される機能は別々のプロセスです。バックグラウンドで実行されている間、子はデータのコピーを受け取ります。このコピーに対する変更は親コピーに伝播されません。
コードに行番号を追加してみましょう。
1 foo () {
2 declare -n fooarray="$1"
3 fooarray["fookey"]=foovalue
4 }
5
6 declare -A myarray
7
8 myarray["mainkey"]=mainvalue
9 foo myarray &
10 wait
11
12 for key in "${!myarray[@]}"; do
13 printf '%s = %s\n' "$key" "${myarray[$key]}"
14 done
行9では、bashは自分自身を2つのプロセスに分岐します。 1つは、実行され続けて10行目で停止される親プロセスです。wait
このプロセスは、9行前に存在していたデータのコピーを使用してfoo関数の内容を実行します。
観察:親プロセスは関数のコードを実行しませんfoo
が、子プロセスは行2と3のみを実行します。
子の行2は、他のリンクされた回答で説明されているように配列参照照会を実行します。fooarray["mainkey"]
上記のコピー操作のため、子の値は「mainvalue」です。次に、3行目に「fookey」を追加しますが、これを行います。コピー材料。 3行目以降は、3行目の割り当てが成功したため、子プロセスは正常に終了します。
親は実行されず、foo
子はコピーを変更するため、親は"fookey"
変更を見ることができません。
子アイテムが親アイテムを変更できるようにするには、継続的なプロセス間通信メカニズム(ファイルやパイプなどの「IPC」)を使用し、そのIPCを読み取って更新して、親アイテムがデータを「選択」するようにする必要があります。コピー。