
私は、現在のディレクトリとカスタム ディレクトリ内のすべてのファイル名を自動的に読み取り、新しく作成された Docker イメージの名前を kubectl 経由で見つかった yml ファイルに適用し、2 つの配列からイメージ名と完全なレジストリ名を読み取る bash スクリプトを作成しようとしています。
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=`...`
これは配列をほとんど作成しません。コマンド置換からの出力はすべて、配列の要素 0 に割り当てられます。実際の配列割り当て構文は、つまり括弧と要素を個別の単語として使用します。name=(elem1 elem2 ... )
単語分割を使用して出力を要素に分割することもできますが、それでも括弧が必要になり、 および のIFS
グロブの対象になります。は、 およびdeclare -a aaa=( $(echo foo bar) )
という 2 つの要素を作成します。改行だけでなく、単語間のスペースでも分割されることに注意してください。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
私の理解では、処理された出力を2 つの配列に格納し、各配列要素が処理された出力の行に対応するようにしたいということです。
このスクリプトは、 の出力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/looping-over-arrays-printing-both-index-and-value