Скрипт массива Bash, объединение

Скрипт массива Bash, объединение

Я пытаюсь написать bash-скрипт, который автоматически считывает все имена файлов в текущем и пользовательских каталогах, затем применяет имена новых созданных образов Docker к найденным файлам yml через kubectl, а затем считывает из двух массивов имена образов и полные имена реестра:

declare -a IMG_ARRAY=`docker images | awk '/dev2/ && /latest/' | awk '{print $1}' | sed ':a;N;$!ba;s/\n/ /g'`
declare -a IMG_NAME=`docker images | awk '/dev2/ && /latest/' | awk '{print $1}' | awk -F'/' '{print $3}' | cut -f1 -d"." | sed ':a;N;$!ba;s/\n/ /g'`

IFS=' ' read -r -a array <<< "$IMG_NAME"
for element in "${array[@]}"
  do
     kubectl set image deployment/$IMG_NAME $IMG_NAME=$IMG_ARRAY --record
     kubectl rollout status deployment/$IMG_NAME
done

Оба массива имеют одинаковое количество индексов. Мой цикл должен брать первые индексы из IMG_NAME и помещать в команды kubectl для каждого индекса массива. Сейчас он берет весь массив...

решение1

declare -a IMG_ARRAY=`...`

Это не создает много массива, весь вывод от подстановки команды назначается нулевому элементу массива. Фактический синтаксис назначения массива — , т.е. со скобками и элементами как отдельными словами.name=(elem1 elem2 ... )

Вы можете использовать разбиение по словам, чтобы разделить вывод на элементы, но это все равно потребует скобок, и вы будете подвержены IFSи подстановке. declare -a aaa=( $(echo foo bar) )создает два элемента fooи bar. Обратите внимание, что он разделяет по пробелу между словами, а не только по новым строкам.

Использование mapfile/ readarrayздесь, вероятно, лучше, поскольку оно явно сделано для чтения строк в массив. Текст справки командной строки ( help mapfile) описывает это:

mapfile: mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
    Read lines from the standard input into an indexed array variable.

    Read lines from the standard input into the indexed array variable ARRAY, or
    from file descriptor FD if the -u option is supplied.  The variable MAPFILE
    is the default ARRAY.

решение2

Насколько я понимаю, вы хотите получить обработанные выходные данные docker imagesв виде двух массивов, где каждый элемент массива соответствует строке обработанных выходных данных.

Этот скрипт не тестировался, поскольку я не знаю ни вывода, docker imagesни синтаксиса команды для kubectl.

mapfile -t IMG_ARRAY < <(docker images | awk '/dev2/ && /latest/' | awk '{print $1}' | sed ':a;N;$!ba;s/\n/ /g')
mapfile -t IMG_NAME < <(docker images | awk '/dev2/ && /latest/' | awk '{print $1}' | awk -F'/' '{print $3}' | cut -f1 -d"." | sed ':a;N;$!ba;s/\n/ /g')

total=${#IMG_NAME[*]}

for (( i=0; i<$(( $total )); i++ ))
do 
     kubectl set image deployment/$IMG_NAME[$i] $IMG_NAME[$i]=$IMG_ARRAY[$i] --record
     kubectl rollout status deployment/$IMG_NAME[i]
done

Видетьhttps://www.cyberciti.biz/faq/bash-iterate-array/иhttps://mywiki.wooledge.org/BashFAQ/005для объяснений.

Вместо

total=${#IMG_NAME[*]}

for (( i=0; i<$(( $total )); i++ ))

Вы также можете использовать

for i in ${!IMG_NAME[@]}

видетьhttps://stackoverflow.com/questions/6723426/цикл-по-массивам-печать-обоих-индексов-и-значений

Связанный контент