一.数组
1.数组简介
变量:用一个固定的字符串,代替一个不固定字符串。
数组:用一个固定的字符串,代替多个不固定的字符串。
2.类型
普通数组:只能使用整数作为数组索引
关联数组:可以使用字符串作为数组索引
图示:
总结:变量切片有个索引的概念。一个索引(整数)对应一个字符。
普通数组:数组中的索引对应一个字符串。
关联数组:数组中的索引可以使用字符串。
3.普通数组
3.1定义数组
方法一:一次赋一个值
数组名[下标]=变量值
[root@localhost ~]# array1[0]=aaa
[root@localhost ~]# array1[1]=bbb
[root@localhost ~]# array1[2]=ccc
[root@localhost ~]# declare -a | grep array1
declare -a array1='([0]="aaa" [1]="bbb" [2]="ccc")'
[root@localhost ~]# echo ${array1[@]}
aaa bbb ccc
方法二:一次赋多个值
[root@localhost ~]# array2=(a1 b1 c1)
[root@localhost ~]# echo ${array2[@]}
a1 b1 c1
[root@localhost ~]# array3=(`cat /etc/passwd`)
[root@localhost ~]# array4=(`ls /var/ftp/shell/for*`)
[root@localhost ~]# array5=(tom jack alice "bash shell")
[root@localhost ~]# echo ${array5[*]}tom jack alice bash shell
[root@localhost ~]# colors=($red $green $blue $recolor)
[root@localhost ~]# array6=(1 2 3 4 5 6 7 "linux shell" [20]=saltstack)
3.2访问数组元素
访问数组元数:
[root@localhost ~]# echo ${array1[0]} #访问数组中的第一个元数
[root@localhost ~]# echo ${array1[@]} #访问数组中所有元数 等同于 echo ${array1[*]}
[root@localhost ~]# echo ${#array1[@]} #统计数组元素的个数
[root@localhost ~]# echo ${!array1[@]} #获取数组元素的索引
[root@localhost ~]# echo ${array1[@]:1} #从数组下标1开始
[root@localhost ~]# echo ${array1[@]:1:2} #从数组下标1开始,访问两个元素
4.关联数组
4.1定义关联数组
必须先声明关联数组
方法一:一次赋一个值
[root@localhost ~]# declare -A array
[root@localhost ~]# array[a1]=aaa
[root@localhost ~]# array[a2]=bbb
[root@localhost ~]# array[a3]=ccc
[root@localhost ~]# echo ${array[@]}
ccc bbb aaa
[root@localhost ~]# array[a3]=ddd
[root@localhost ~]# echo ${array[@]}
ddd bbb aaa
方法二:一次赋多个值
[root@localhost ~]# declare -A array[root@localhost ~]# array=([a]=tom [b]=bob [c]=jack)
[root@localhost ~]# array=([a]=tom [b]=bob [c]=jack [d]='bash shell')
[root@localhost ~]# echo ${array[@]}tom bob jack bash shell
[root@localhost ~]# echo ${array[d]}
bash shell
4.2访问数组元素
[root@localhost ~]# echo ${ass_array2[index2]} #访问数组中的第二个元数
[root@localhost ~]# echo ${ass_array2[@]} #访问数组中所有元数 等同于 echo ${array1[*]}
[root@localhost ~]# echo ${#ass_array2[@]} #获得数组元数的个数
[root@localhost ~]# echo ${!ass_array2[@]} #获得数组元数的索引
5.数组和循环
1.通过循环定义和显示数组
2.通过数组统计数据
6.案例
案例1:while脚本快速定义数组
[root@localhost ~]# cat array.sh
#!/bin/bash
#循环读取文件,定义数组
while read line
do
#hosts:数组名
#[++i]:索引递增,++i是1开始,i++是0开始。
#$line:值,即文件中的内容
hosts[++i]=$line
done < /etc/hosts
#输出索引每一行
for i in ${
!hosts[@]}
do
echo "$i : ${hosts[$i]}"
done
[root@localhost ~]# bash array.sh
1 :127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
2 : ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
案例2:for脚本快速定义数组
[root@localhost ~]# vim array-for.sh
#!/bin/bash
#OLD_IFS=$IFS
#IFS=$'\n'
for line in `cat /etc/hosts`
do
hosts[i++]=$line
done
for i in ${
!hosts[@]}
do
echo "$i---"
echo "${hosts[$i]}"
done
#IFS=$OLD_IFS
[root@localhost ~]# bash array-for.sh
0---
127.0.0.1
1---
localhost
2---
localhost.localdomain
3---
localhost4
4---
localhost4.localdomain4
5---
::1
6---
localhost
7---
localhost.localdomain
8---
localhost6
9---
localhost6.localdomain6
---解决for循环的空格分割问题:IFS=$'\n'---
[root@localhost ~]# vim array-for.sh
#!/bin/bash
OLD_IFS=$IFS #讲旧的分隔符备份
IFS=$'\n' #定义for的分隔符是换行符
for line in `cat /etc/hosts`
do
hosts[i++]=$line
done
for i in ${
!hosts[@]}
do
echo "$i---"
echo "${hosts[$i]}"
done
IFS=$OLD_IFS #将分隔符还原,便于脚本后方的for使用
案例3:数组统计性别
---1.定义性别文本---
[root@localhost ~]# vim sex.txt
jack m
alice f
tom m
---2.定义脚本统计性别---
[root@localhost ~]# vim sex.sh
#!/bin/bash
declare -A sex
while read line
do
type=`echo $line|awk '{print $2}'`
let sex[$type]++
done < sex.txt
for i in ${
!sex[@]}
do
echo "$i : ${sex[$i]}"
done
---3.测试脚本---
[root@localhost ~]# bash sex.sh
f : 1
m : 2
案例4:使用数组统计,用户shell的类型和数量
[root@localhost ~]# vim passwd.sh
#!/bin/bash
declare -A shells
while read ll
do
type=`echo $ll | awk -F: '{print $NF}'`
let shells[$type]++
done < /etc/passwd
for i in ${
!shells[@]}
do
echo "$i : ${shells[$i]}"
done
[root@localhost ~]# bash passwd.sh
/sbin/nologin : 39
/bin/sync : 1
/bin/false : 1
/bin/bash : 6
/sbin/shutdown : 1
/sbin/halt : 1
二.函数
1.概述
概念:函数是一段完成特定功能的代码片段(块)
在shell中定义了函数,就可以使代码模块化,便于复用代码
注意函数必须先定义才可以使用。
重点:传参 $ 1,$ 2
局部变量 local
返回值 return 即$ ?
2.定义函数
方法一:
函数名(){
函数要实现的功能代码
}
方法二:
function 函数名{
函数要实现的功能代码
}
3.调用函数
语法
函数名
函数名 参数1 参数2
4.示例
4.1示例1:初识函数
--- 需求 ---
编写循环脚本,功能菜单
provide these tools:
show disk info(d)
show mem info(m)
show cpu info(c)
quit(q)
--- 思路 ---
1.编写菜单和判断
2.添加循环
3.添加函数
--- 演示1 ---
[root@localhost ~]# vim menu.sh
#!/bin/bash
show_menu() {
cat << EOF
provide these tools:
show disk info(d)
show mem info(m)
show cpu info(c)
quit(q)
EOF
}
while :
do
show_menu
read -p "Input choice: " choice
case $choice in
d)
echo "===========disk info=============="
df -hT
;;
m)
echo "==========meme info==============="
free -m
;;
c)
echo "==========cpu info================="
uptime
;;
q)
break
;;
*)
show_menu
;;
esac
done
4.2示例2:阶乘函数(传参)
--- 需求 ---
制作函数用于阶乘
--- 思路 ---
1.了解阶乘概念
2.定义函数
3.引用函数
--- 演示 ---
[root@localhost ~]# vim factorial.sh
#!/bin/bash
fun(){
factorial=1
for((i=1;i<=$1;i++)) #等同于for i in `seq $i`
do
factorial=$[$factorial*$i]
done
echo "$1 阶乘: $factorial"
}
fun $1
4.3示例3:函数传参 数组传参
--- 1.阶乘脚本,通过数组给函数传参
[root@localhost ~]# vim array3.sh
#!/bin/bash
num=(1 2 3)
num2=(4 5 6)
array(){
factorial=1
for i in $*
do
factorial=$[factorial*$i]
done
echo $factorial
}
array ${
num[*]}
array ${
num2[*]}
--- 2.数组好处在于多个数组时传参效率增高 ---
4.4示例4:函数结果 赋予数组
--- 1.通过函数输出到数组 ---
[root@localhost ~]# vim array4.sh
#!/bin/bash
num=(1 2 3)
array(){
for i in $*
do
outarray[j++]=$[$i+5]
done
echo "${outarray[*]}"
}
result=`array ${
num[*]}`
echo ${
result[*]}
--- 2.函数不仅可以从数组中调取值,还可以赋予数组值
三.影响shell程序的内置命令
1.概览
:
true
false
exit
break
continue
shift
————————————————————————————————————————————————
shift 使位置参数向左移动,默认移动1位,可以使用shift 2
exit 退出整个程序
break 结束当前循环,或跳出本层循环
continue 忽略本次循环剩余的代码,直接进行下一次循环
2.continue/break/shift
--- 1.需求:通过循环脚本实现如下效果 ---
A123456789
B123456789
C123456789
D123456789
--- 2.编写循环脚本 ---
[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
A..D}
do
echo $i
for j in {
1..9}
do
echo $j
done
done
--- 3.测试脚本,观察结果 ---
[root@localhost ~]# bash for1.sh
A
1
2
3
4
5
6
7
8
9
B
......
--- 4.解决换行问题 ---
[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
A..D}
do
echo -n $i
for j in {
1..9}
do
echo -n $j
done
done
--- 5.测试脚本,观察结果 ---
[root@localhost ~]# bash for1.sh
A123456789B123456789C123456789D123456789
--- 6.外循环,添加一条空行语句 ---
[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
A..D}
do
echo -n $i
for j in {
1..9}
do
echo -n $j
done
#空行
echo
done
--- 7.测试,完成预期 ---
[root@localhost ~]# bash for1.sh
A123456789
B123456789
C123456789
D123456789
--- 8.总结:循环嵌套的规则是:外部循环一次,内部循环全部。 ---
--- 9.需求:跳出关于5的循环需求 ---
A12346789
B12346789
C12346789
D12346789
--- 10.continue ---
[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
A..D}
do
echo -n $i
for j in {
1..9}
do
if [ $j -eq 5 ];then
continue
fi
echo -n $j
done
echo
done
--- 11.break ---
[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
A..D}
do
echo -n $i
for j in {
1..9}
do
if [ $j -eq 5 ];then
break 2
fi
echo -n $j
done
echo
done
[root@localhost ~]# bash for1.sh
A1234
--- 12.shift ---
Ⅰ.for循环不定义循环范围,循环去参数作为循环范围
[root@localhost ~]# vim sum.sh
#!/bin/bash
for i
do
let sum+=$i
done
echo "sum : $sum"
[root@localhost ~]# bash sum.sh
sum :
[root@localhost ~]# bash sum.sh 1
sum : 1
[root@localhost ~]# bash sum.sh 2
sum : 2
[root@localhost ~]# bash sum.sh 3
sum : 3
[root@localhost ~]# bash sum.sh 1 3
sum : 4
Ⅱ.使用while循环,发现停不下来
[root@localhost ~]# vim sum-while.sh
#!/bin/bash
while [ $# -ne 0 ]
do
let sum+=$1
echo $sum
done
echo "sum : $sum"
[root@localhost ~]# bash sum-while.sh 1 2
-根本停不下来。因为循环为真。-
Ⅲ.使用shift移动参数的命令,结果得以实现
[root@localhost ~]# vim sum-while.sh
#!/bin/bash
while [ $# -ne 0 ]
do
let sum+=$1
shift
done
echo "sum : $sum"
[root@localhost ~]# bash sum.sh 1 2
sum : 3
[root@localhost ~]# bash sum.sh 1 2 3
sum : 6
-shift 1使参数 左移1位,shift 2 左移2位-
Ⅳ.另一个,创建用户的案例
[root@localhost ~]# vim useradd-shift.sh
#!/bin/bash
while [ $# -ne 0 ]
do
useradd $1
echo "$1 is created"
shift
done
[root@localhost ~]# bash useradd-shift.sh aa bb
aa is created
bb is created