Я хочу заполнить ассоциативный массив в bash в несколько нетривиальной настройке. У меня есть конвейер команд для создания требуемого ввода для массива.bash: доступ к глобальным переменным из конвейера команд
Вот минимальный/игрушка пример:
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"]}"
В этом примере mapping
изменяется внутри 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 использует подоболочку в первом случае, но не во втором?
РЕДАКТИРОВАТЬ: после немного больше копания, вопрос в основном является дубликатом this one. Хороший список опций для обработки этого вопроса можно найти на http://mywiki.wooledge.org/BashFAQ/024
Ваше понимание подоболочку правильно, то выполняется команда трубы с обеих сторон в отдельных подоболочек, когда правая сторона (петля) завершает все изменения в этой субоболочке теряются. <<(команда), открывает команду в подоболочке, и цикл находится в основном, поэтому вы сохраняете изменения в цикле while. – 123