
Estou tentando escrever um script bash, que lerá automaticamente todos os nomes de arquivos nos diretórios atuais e personalizados e, em seguida, aplicará os novos nomes de imagens do docker criados aos arquivos yml encontrados via kubectl e, em seguida, lerá dois nomes de imagens de matrizes e nomes completos de registro:
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
Ambas as matrizes possuem o mesmo número de índices. Meu loop deve pegar os primeiros índices de IMG_NAME e colocá-los em comandos kubectl para cada índice de array. Por enquanto está levando todo o array....
Responder1
declare -a IMG_ARRAY=`...`
Isso não cria muito array, toda a saída da substituição do comando é atribuída ao elemento zero do array. A sintaxe real de atribuição de array é , ou seja, com parênteses e os elementos como palavras distintas.name=(elem1 elem2 ... )
Você poderia usar a divisão de palavras para separar a saída em elementos, mas isso ainda requer os parênteses, e você está sujeito IFS
e globbing. declare -a aaa=( $(echo foo bar) )
cria os dois elementos foo
e bar
. Observe que ele se divide no espaço entre as palavras, não apenas nas novas linhas.
Usar mapfile
/ readarray
é provavelmente melhor aqui, já que é feito explicitamente para ler linhas em um array. O texto de ajuda da linha de comando ( help mapfile
) descreve isso:
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.
Responder2
Meu entendimento é que você deseja ter a saída processada docker images
em duas matrizes onde cada elemento da matriz corresponde a uma linha da saída processada.
Este script não foi testado porque não conheço a saída docker images
nem a sintaxe do comando 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
Verhttps://www.cyberciti.biz/faq/bash-iterate-array/ehttps://mywiki.wooledge.org/BashFAQ/005para explicações.
Em vez de
total=${#IMG_NAME[*]}
for (( i=0; i<$(( $total )); i++ ))
você também pode usar
for i in ${!IMG_NAME[@]}
verhttps://stackoverflow.com/questions/6723426/looping-over-arrays-printing-both-index-and-value