和其他编程语言一样,Shell 也支持数组。数组(Array)是若干数据的集合,其中的每一份数据都称为元素(Element)。
Shell 并且没有限制数组的大小,理论上可以存放无限量的数据。和C语言类似,Shell 数组元素的下标也是从 0 开始计数。
获取数组中的元素要使用下标[ ]
,下标可以是一个整数,也可以是一个结果为整数的表达式;当然,下标必须大于等于 0。
遗憾的是,常用的 Bash Shell 只支持一维数组,不支持多维数组。
array_name=(ele1 ele2 ele3 ... elen)
注意,赋值号=
两边不能有空格,必须紧挨着数组名和数组元素。
数值类型的数组:一对括号表示数组,数组中元素之间使用“空格”来隔开。
字符串类型数组:同样,使用一对括号表示数组,其中数组中的元素使用双引号或者单引号包含,同样使用“空格”来隔开。
数组的四种定义方法:
<1>
[root@server day04]# array=(1 2 3)
[root@server day04]# echo ${array[*]}
1 2 3
<2>
[root@server day04]# array=([0]=one [1]=two [2]=three)
[root@server day04]# echo ${array[*]}
one two three ##这种方法可以实现只给特定元素赋值
<3>
[root@server day04]# array[0]=a
[root@server day04]# array[1]=b
[root@server day04]# echo ${array[*]}
a b three ##保留之前的array[2],相当于修改指定下标的值。
<4>动态定义数组变量,并使用命令的输出结果作为数组的内容
[root@server day04]# ls
backup.sh mysql_options.sh
[root@server day04]# array=($(ls))
[root@server day04]# echo ${array[*]}
backup.sh mysql_options.sh
<1>获取数组元素的值,一般使用下面的格式:
${array_name[index]} 其中,array_name 是数组名,index 是下标
使用@
或*
可以获取数组中的所有元素,例如:
[root@server day04]# echo ${array[*]}
backup.sh mysql_options.sh
[root@server day04]# echo ${array[@]}
backup.sh mysql_options.sh这两者都可以得到 array 数组的所有元素。
<2>获取数组长度
形式:${#数组名[@/*]} 可得到数组的长度。
[root@server day04]# num=(`seq 10`)
[root@server day04]# echo ${#num[@]}
10
[root@server day04]# echo ${#num[*]}
10
<3>对某个下标赋值
如果该下标元素已经存在,会修改该下标的值为新的指定值。
[root@server day04]# num[2]=100
[root@server day04]# echo ${num[*]}
1 2 100 4 5 6 7 8 9 10
如果指定的下标已经超过当前数组的大小,则新赋的值被追加到数组的尾部。
[root@server day04]# num[10]=88
[root@server day04]# echo ${num[*]}
1 2 100 4 5 6 7 8 9 10 88
<4>删除操作
清除某个元素:
unset array_name[index]
[root@server day04]# echo ${num[*]}
1 2 100 4 5 6 7 8 9 10 88
[root@server day04]# unset num[3]
[root@server day04]# echo ${num[*]}
1 2 100 5 6 7 8 9 10 88
清空整个数组:
unset array_name
[root@server day04]# echo ${num[*]}
1 2 100 5 6 7 8 9 10 88
[root@server day04]# unset num
[root@server day04]# echo ${num[*]}
<5>分片访问
形式为:${数组名[@或*]:开始下标:结束下标}
[root@server day04]# array=($(echo {a..z}))
[root@server day04]# echo ${array[*]}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@server day04]# echo ${array[*]:1:4}
b c d e
<6>模式替换
形式为:${数组名[@或*]/模式/新值}
[root@server day04]# test=(1 1 1 2 2 3)
[root@server day04]# echo ${test[@]/1/b}
b b b 2 2 3
<7>数组的遍历
数组遍历我们使用for语句来实现:
for v in ${arr_number[@]}; do
echo $v;
done
练习:
利用for循环打印下面这句话中字母个数大于4的单词
Your brain will give you reasons why you can't but your heart will give you reasons you can
#!/bin/bash
arr=(Your brain will give you reasons why you cannot but your heart will give you reasons you can)
for ((i=0;i<${#arr[*]};i++)) ##echo ${#arr[i]} 能直接输出数组对应下标的元素的字符个数
do
if [ ${#arr[i]} -gt 4 ];then
echo "${arr[i]}"
fi
done
运行脚本的结果如下:
<1>通过内部系统变量($RANDOM)获得随机数
<2>通过openssl命令
OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用
openssl命令的格式是"openssl command command-options args",command部分有很多种命令,这些命令需要依赖于openssl命令才能执行,所以称为伪命令(pseudo-command),每个伪 命令都有各自的功能,大部分command都可以直接man command查看命令的用法和功能。
[root@server day04]# openssl rand -base64 40
hMuznEovcjwYiRIqbO0lyqTXX05HaxDNpzWjxa4RSLiGejJevX0gyA==
面试题:
<1>使用for循环在/westos目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串westos
#!/bin/bash
Path=/westos
[ -d "$Path" ] || mkdir -p $Path
for i in `seq 10`
do
random=$(openssl rand -base64 40 | sed 's/[^a-z]//g' | cut -c 3-12) ##[^ ]表示匹配不在指定字符组内的任意字符
touch $Path/${random}_westos.html
done
运行脚本的结果为:
md5sum命令
md5sum命令用于生成和校验文件的md5值。它会逐位对文件的内容进行校验。是文件的内容,与文件名无关,也就是文件内容相同,其md5值相同。md5值是一个128位的二进制数据,转换成16进制则是32(128/4)位的进制值。
md5校验,有很小的概率不同的文件生成的md5可能相同。比md5更安全的校验算法还有SHA*系列的。
在网络传输时,我们校验源文件获得其md5sum,传输完毕后,校验其目标文件,并对比如果源文件和目标文件md5 一致的话,则表示文件传输无异常。否则说明文件在传输过程中未正确传输。
重要的参数:
-b 以二进制模式读入文件内容
-t 以文本模式读入文件内容
-c 根据已生成的md5值,对现存文件进行校验
--status 校验完成后,不生成错误或正确的提示信息,可以通过命令的返回值来判断。
md5值重定向
将生成md5值重定向到指定的文件,通常文件的扩展名我们会命为.md5
[root@server day04]# md5sum test
9bbcbd2a512f9ca2d6e9da4e18e1a388 test
[root@server day04]# md5sum test > file_test.md5
[root@server day04]# cat file_test.md5
9bbcbd2a512f9ca2d6e9da4e18e1a388 test[root@server day04]# md5sum -c file_test.md5
test: OK ## 生成当前文件的md5,并和之前已经生成的md5进行对比,一致,则返回OK,表示文件内容一致[root@server day04]# vim test ##改变文件的内容
[root@server day04]# md5sum -c file_test.md5
test: FAILED ##文件内容发生变化,返回错误信息
md5sum: WARNING: 1 computed checksum did NOT match
练习:
产生10位字母与数字混合的随机数:
[root@server day04]# echo $RANDOM | md5sum | cut -c 3-12
18a089e174
<2>建立westos01-westos10十个用户,并给每个用户随机生成10位的密码,将用户以及其对应的密码存在一个文件中。
#!/bin/bash
. /etc/init.d/functionsusername="westos"
passfile="/tmp/user.log"
for num in `seq -w 10`
do
pass="`echo $RANDOM | md5sum | cut -c 3-12`"
useradd $username$num &> /dev/null && {
echo $pass | passwd --stdin $username$num &> /dev/null
echo -e "user:$username$num\tpasswd:$pass" >> $passfile
}
if [ $? -eq 0 ];then
action "$username$num is ok" /bin/true
else
action "$username$num is failed" /bin/false
fi
done
运行脚本的结果: