bashで連想配列を書きたいと思っています。私は配列のために必要な入力を生成するコマンドのパイプラインを持っています。ここでbash:コマンドパイプラインからグローバル変数にアクセスする
は、最小限の/おもちゃの例です。この例mapping
で
declare -A mapping
seq 10 | while read i; do
key="key_$i"
val="val_$i"
echo "mapping[$key]=$val"
mapping["${key}"]="${val}"
done
echo "${mapping["key_1"]}"
echo "${mapping["key_2"]}"
while
内で変更されますが、これらの変更は、グローバル名前空間に反映されません。これは、while
が別のサブシェルの内部で動作するためです。したがって、名前空間は分岐しています。
は(私が示唆するもの)サブシェルの問題を避けるために、私は次のを思い付いた:
declare -A mapping
while read i; do
key="key_$i"
val="val_$i"
echo "mapping[$key]=$val"
mapping["${key}"]="${val}"
done < <(seq 10)
echo "${mapping["key_1"]}"
echo "${mapping["key_2"]}"
while
ループがで左つつ、生成部は、明示的に、サブシェルに入りますトップレベルのみ。建設はうまくいく。
私の質問は:私の目標を達成するためのより良い方法はありますか?そして、サブシェルに関する私の提案は正しいですか?もしそうなら、なぜbashが最初のケースではサブシェルを使用しますが、2番目のケースでは使用しませんか?
EDIT:もう少し掘り下げた後、質問はほとんどthis oneの複製です。問題を処理するためのオプションの良いリストは、これはあなたの2番目のコードスニペットよりも良い方法ですが、最初のものを解決する方法は、右のパイプの後にサブシェル{ ... }
を使用することであるかどうかわからないhttp://mywiki.wooledge.org/BashFAQ/024
パイプコマンドは、右側(ループ)がそのサブシェルへのすべての変更を終了すると、別のサブシェルで両側を実行します。 <<(command)、サブシェルでコマンドを開き、ループがメインループにあるので、whileループからの変更を保持します。 – 123