Перебрать элементы, не разорвав их по пробелам
folders=("/var/log/nginx" "/var/log/app with space")
for d in "${folders[@]}"; do
ls -ld "$d"
done
Кавычки вокруг
${folders[@]} обязательны. Без них тот же цикл на моём тесте выдал четыре итерации вместо двух: путь распался на /var/log/app, with и space. И не путай @ с *: под кавычками "${folders[*]}" склеивает весь массив в одну строку.Посчитать элементы
echo "${#folders[@]}"
Нюанс:
${#folders} без [@] — это не размер массива, а длина первого элемента. У меня вернуло 8 вместо 3, и никакой ошибки.Обойти разреженный массив
for i in "${!sparse[@]}"; do
echo "$i = ${sparse[$i]}"
done
Нюанс: если удалить элемент через
unset, индексы останутся с дырками. Массив с индексами 0, 5, 9 имеет размер 3 — обход по seq 0 2 найдёт один элемент из трёх. Перебирать надо индексы через ${!arr[@]}, а не числа от нуля.Прочитать файл в массив
readarray -t lines < /var/log/app.log
readarray -t lines < <(grep -v '^$' /var/log/app.log)
Нюанс:
cat file | readarray -t lines не работает. Пайп запускает readarray в подоболочке, массив заполняется там и умирает вместе с ней. У меня получилось 0 элементов вместо 4, снова без ошибки. Нужен либо редирект, либо подстановка процесса < <(...).Сделать словарь
declare -A ports=([nginx]=80 [php-fpm]=9000)
Нюанс:
declare -A не формальность. Без него bash создаёт обычный индексный массив, все строковые ключи считаются нулём, и каждое присваивание перетирает предыдущее. Проверил: ${ports[nginx]} вернуло 9000 — значение от php-fpm.Общее у всех пяти: bash не ругается, а тихо делает не то. Поэтому
shellcheck на скриптах с массивами экономит больше времени, чем кажется.А вы конфиги в bash разбираете ассоциативными массивами или сразу отдаёте jq?
#Linux #Bash #Shell #Scripting #DevOps