bash массив массивов

Напишите сценарий, который является родительским для обоих, тогда вы сможете легко управлять обоими . Альтернативно установить канал связи между двумя каналами .

Чтобы специально игнорировать определенные фоновые задания, вы можете зафиксировать PID($!— это PID последнего фонового задания )и wait $pidожидать только завершения этого задания.

2
22.10.2019, 21:09
2 ответа

Это довольно распространенная проблема в bashдля ссылки на массив внутри массивов, для которых вам нужно создать ссылки имени -с помощью declare -n. Имя, следующее за -n, будет действовать как ссылка на имя для значения, присвоенного (после =). Теперь мы рассматриваем эту переменную с атрибутом nameref для расширения, как если бы это был массив, и делаем полное правильное раскрытие массива в кавычках, как и раньше.

for group in "${subgroups[@]}"; do
    declare -n lst="$group"
    echo "group name: ${group} with group members: ${lst[@]}"
    for element in "${lst[@]}"; do
        echo -en "\tworking on $element of the $group group\n"
    done
done

Обратите внимание, что bashподдерживает nameref только начиная с версии 4.3. Для более старых версий и других обходных путей см. Назначение косвенных/ссылочных переменных

6
27.01.2020, 21:58

Минимальные изменения для корректной работы вашего скрипта, становится:

#!/bin/bash

declare -a bar=("alpha" "bravo" "charlie")
declare -a foo=("delta" "echo" "foxtrot" "golf")

declare -a groups=("bar" "foo")

for group in "${groups[@]}"; do
    lst="$group[@]"
    echo "group name: ${group} with group members: ${!lst}"
    for element in "${!lst}"; do
        echo -en "\tworking on $element of the $group group\n"
    done
done

Два основных изменения::

  • Не используйте "${!lst[@]}", даже "${!group[@]}"для доступа к элементам массива . Этот синтаксис только для доступа к массиву индексов .

    Используйте ${!lst}".

  • Переменная lst должна содержать строку , которую вы бы написали внутри обычной ${ }, то есть:lst=foo[@]на первом уровне, и lst="$group[@]", если вам нужно, чтобы имя массива также косвенно через значение переменной group.

     lst="$group[@]"
    

Эквивалентный синтаксис с namerefsне имеет!(и не требует )для расширения значений.
Как следствие, необходимо удалить [@]выше.

echo "using namerefs"

for group in "${groups[@]}"; do
    declare -n lst=$group
    echo "group name: ${group} with group members: ${lst[@]}"
    for element in "${lst[@]}"; do
        echo -en "\tworking on $element of the $group group\n"
    done
done
4
27.01.2020, 21:58

Теги

Похожие вопросы