我正在尝试编写 bash 脚本,它将自动读取当前和自定义目录中的所有文件名,然后将新创建的 docker 映像名称应用到通过 kubectl 找到的 yml 文件,然后从两个数组读取映像名称和完整注册表名称:
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/looping-over-arrays-printing-both-index-and-value