shell数组迷惑行为大赏汇总
摘要:事先我只知道普通数组可以通过小括号赋单个或多个值,并不知道还有通过下标定义的方法,所以迷惑为什么上面的循环变量读取文件值还不会被覆盖掉。很迷的是:这跟普通数组的直接使用下标定义几乎很像。
0x01
今天复习shell编程的时候看到一个简单的数组脚本,十分抽象,特来记录一下shell数组的迷惑行为
脚本如下:
#!/bin/bash while read line do hosts[++i]=$line done </etc/hosts for i in ${!hosts[@]} do echo "$i:${hosts[i]}" done
运行如下:
0x02
附普通数组的三种定义方法:
1、 declare 定义
declare -a先声明一个变量是数组类型的(下标从0开始),然后可以通过下标读取数值
# declare -a books # books[0]=linux # books[1]=shell
如上所示,可以根据下标一个一个进行添加数组元素,那肯定也就可以使用循环对数组添加多个元素了(如脚本本使用的方法)
2、 直接定义
① 使用小括号()直接定义一个数组变量
books=( linux shell awk openstack docker ) 或 books=(linux shell awk openstack docker)
② 在()中声明下标,默认从0开始,下标可以不连续(与关联数组定义非常像!关联数组需要declare,并且没有=号)
# books=([0]="linux" [1]="shell" [3]="docker")
3、 带下标定义
其实这种方法就是省略了declare的步骤,普通数组其实没有使用declare的必要
# books[0]=linux # books[1]=shell # books[3]=docker
这种方法肯定也可以使用for进行循环添加数组元素
while read line do hosts[++i]=$line done </etc/hosts
4、 从文件读取
# days=(`cat days.txt`)
0x03
#!/bin/bash while read line do hosts[++i]=$line done </etc/hosts for i in ${!hosts[@]} do echo "$i:${hosts[i]}" done
脚本迷惑行为大赏之一:
事先我只知道普通数组可以通过小括号赋单个或多个值,并不知道还有通过下标定义的方法,所以迷惑为什么上面的循环变量读取文件值还不会被覆盖掉!
脚本迷惑行为大赏之二:
如上图所示,更改脚本上面while循环的i值会影响数组的初始索引,上面的i变量也没有定义,为什么会影响数组的初始索引呢?
shell中+在前面是先+ 再赋值;+在后面是先赋值再+ 区别就是本次循环的初始值
shell中i++初始值为0,++i初始值为1。且shell中变量是可以直接进行简单运算的,如下
脚本迷惑行为大赏之三:
为什么sh -x调试结果显示上面的“hosts[++i]=”这一块是原样输出而不是“hosts[1]=”、“hosts[2]=”这样的呢?
请教柴老哥得出猜测:“我理解应该是跟循环+数组追加有关系的,不是个完整的数据结构”
有朋友知道的还望不吝赐教!!!
数组迷惑行为大赏之一:
关联数组的定义是需要declare声明的!如下:
# declare -A info # info=( [name]zjib [sex]male [age]11 )
很迷的是:这跟普通数组的直接使用下标定义几乎很像!对比如下!
普通数组使用下标定义:
books=([0]="linux" [1]="shell" [3]="docker")
关联数组定义: