理论+实验·Shell编程之循环语句、函数、数组
文章目录
for语句的结构
读取不通的变量值,用来逐个执行同一组命令
for 变量名 in 取值列表 ===>变量名是临时变量名从取值列表里面去读
do
命令序列
done
for语句应用实例
示例一
批量添加用户
用户名存放在user.txt文件中,每行一个
初始化密码均设为123456
验证脚本
#!/bin/bash
#定义集合
list=`cat /opt/users.txt`
#遍历创建新用户
for user in $list
do
#创建新用户
useradd $user
#设置密码
echo "123456" | passwd --stdin $user
echo "$user创建成功"
done
示例二
根据IP地址检查主机状态
IP地址存放在ipadds.txt文件中,每行一个
使用ping命令检测各主机的连通性
#!/bin/bash
#定义集合
ip_=`cat /opt/ipadds.txt`
#遍历
for ipaddress in $ip_
do
#pingIP地址
ping -c 3 -i 0.2 -W 3 $ipaddress &>/dev/null ===>-c 次数 -i 间隔多久在ping一次 -W 等待时间
if [ $? -eq 0 ];then
echo "${ipaddress} is up"
else echo "${ipaddress} is down"
fi
done
常用变量
变量i=1
i<=10
i++ 自身加1
((;;)) ===>没有条件无限循环
break ===>退出当前循环
exit 0 ===>退出应用程序,后面的所有语句都不会执行
exit 0 ===>0是状态码 0 表示正常退出
(1-100)偶数和
#!/bin/bash
sum=0
for ((i=1;i<=100;i++))
do
#条件筛选
if [ `expr $i % 2` -eq 1 ];then
let sum=${sum}+${i}
fi
done
echo "${sum}"
(1-100)奇数和
#!/bin/bash
sum=0
for ((i=1;i<=100;i+=2))
do
let sum+=$i
done
echo "$sum"
++ ===>自身变量+1
-- ===>自身变量-1 let可以单独使用
+=5 ===>自身变量+5
-=5 ===>自身变量*5
\*=5 ===>自身变量乘以5
/=5 ===>自身变量除以5
%=5 ===>自身变量%5
((;;)) 无限循环
$() ===> `` 命令替换
[ ] ===>test 条件判断
$[ ] ===> $(( )) 算术运算
${} 变量替换
(()) ===> 支持数学运算符的 条件判断
while语句的结构
重复测试某个条件,只要条件成立则反复执行
while 条件测试操作
do
命令序列
done
只要成立会一直不停的执行下去
while语句应用实例
示例一
批量添加用户
用户名称以stu开头,按数组顺序进行编号
一共添加20各用户,即stu1,stu2,stu3…stu20
从初始密码均设为123456
#!/bin/bash
i=1
user=stu$i
while [ $i -le 20 ]
do
echo stu$i
useradd stu$i
echo "123456" | passwd --stdin $user
echo "用户${user}输出成功"
let i++
done
示例二
猜商品价格游戏
通过变量RANDOM获得随机数
提示用户猜测并记录次数,猜中后退出循环
#!/bin/bash
#假设商品价格为60元
read -p "请猜出商品的价格(元):" howmuch
while [ $howmuch -ne 60 ];do
echo "离商品价格还有一点距离"
read -p "请重新猜出商品的价格(元):" howmuch
done
echo "恭喜您猜对了,商品价格为$howmuch"
coutinue 跳过本次continue以下执行语句直接进入下一次循环
break 退出当前循环语句
exit 1 直接退出不执行下面的语句
双重循环示例
九九乘法口诀表
#!/bin/bash
i=1
while [ $i -le 9 ]
do
j=1
while [ $j -le $i ]
do
echo -n "${i}*${j}"="`expr ${i} \* ${j}` "
let j++
done
echo ""
let i++
done
等腰三角形
#!/bin/bash
read -p "请输入行数:" num
i=1
while [ $i -le $num ]
do
j=${num}
while [ $j -ge $i ]
do
echo -n " "
let j--
done
k=1
while [ $k -le $i ]
do
echo -n "* "
let k++
done
echo ""
let i++
done
until语句的结构
重复测试某个条件,只要条件不成立则反复执行
until 条件测试操作
do
命令序列
done
until语句应用实例
示例一
计算1~50的和值
通过循环累加的方式计算1-50的和值
#!/bin/bash
i=1
sum=0
until [ $i -eq 51 ]
do
\#echo $i
let sum+=$i
let i++
done
echo "和为:$sum"
示例二
为指定用户发送在线消息
若用户不在线(未登录系统),则每10分钟试一次,直至用户登录系统后在发送信息
用户名与信息通过位置参数传递给脚本
#!/bin/bash
username=$1
#格式参数不能为空
if [ $# -lt 1 ];then
echo "Usage:'basename $0' <username> [<message>]"
exit 1
fi
#验证是否属于系统用户
if grep "^$username" /etc/passwd > /dev/null;then空格:
else
echo "not user"
exit 2
fi
#测试用户是否在线,如果不在线,每5秒联系一次
until who | grep "$username" > /dev/null;do
echo "user not login"
sleep 5
done
#发送消息
echo "$2" | write "$username"
echo "${username}发送成功"
Shell函数
将命令序列按格式写在一起
可方便重复使用命令序列
Shell函数定义
[ function ] 函数名(){
命令序列
[return x] ===>返回的状态码 $?
返回数据 echo输出
}
调用函数的方法
函数名 [参数1] [参数2]
函数应用实例
示例一
两个数字求和
通过sum (){} 定义函数
使用read命令交互输入两个数并求和
#!/bin/bash
function sum(){
#命令序列
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
SUM=$[${num1}+${num2}]
#echo返回的是处理结果值
echo "和为:$SUM"
#return返回的是状态码
return 100
}
sum
示例二
编写登录系统后便可使用的用户自定义函数
编辑用户自定义函数文件/root/function
在当前Shelll中加载可执行的函数文件/root/function
在~/.bashrc文件中添加source /root/function命令
[root@localhost opt]# vim /root/.bashrc
......
function sum(){
#命令序列
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
SUM=$[${num1}+${num2}]
#echo返回的是处理结果值
echo "和为:$SUM"
#return返回的是状态码
return 100
}
[root@localhost opt]# source /root/.bashrc ===>重新加载以下配置文件
[root@localhost opt]# sum ===>直接调用
函数的作用范围
函数在Shell脚本中仅在当前Shell环境中有效
Shell脚本中变量默认全局有效
将变量限定在函数内部使用local命令
示例
函数内部变量通过local来实现
通过定义myfun函数,在其内部设置局部变量i
函数内部和外部分别赋值,进行结果验证
local score ===>加了local就是局部变量
函数的参数
参数的用法
函数名称参数1参数2多数…
参数的表示方法
$1 $2 $3… S(10} ${11} …
示例
通过函数参数将日志信息写入文件,
通过定义appendfile函数实现
递归函数
调用自己本身的函数
示例
递归遍历目录
通过定义递归函数list_files来实现
#!/bin/bash
function list_files(){
for f in `ls $1`
do
if [ -d "$1/$f" ];then
echo "$2$f"
#递归调用
list_files "$1/$f" " $2"
else
echo "$2$f"
fi
done
}
list_files "/var/log" ""
Shell数组
应用场景包括
获取数组长度
获取元素长度
遍历元素
元素切片 ===>某一个子部份
元素替换
元素删除
…
数组定义方法
方法一
数组名= (value0 value1 value2 ...)
方法二
数组名= ([0]=value [1]=value [2]=value ...)
方法三
列表名="value0 value1 value2"
数组名=($列表名)
方法四
数组名[0]="value"
数组名[1]="value"
数组名[2]="value"
数组包括的数据类型
数值类型
字符类型
使用""或’'定义
#!/bin/bash
#创建存放(1-100)奇数的数组
for ((i=0,j=1;i<=99,j<=100;i++,j+=2))
do
arr[$i]="$j"
done
echo ${arr[*]}
#!/bin/bash
#创建任意数字及长度的数组,根据客户的需求加入元素
i=0
while [ $i -ge 0 ]
do
read -p "请输入该数组的元素:" num
arr[$i]="$num"
let i++
if [ -z $num ];then
echo ${arr[*]}
exit 1
fi
done
Shellt数组操作
获取数组长度
$(数组名[@/]}
[root@localhost -# arr-number=(1 2 3 4 5);
[root@localhost -arr-length=$(#arr-number[*]}
root@localhost -]# echo $arr_length
5
读取某下标赋值
$(数组名[下表])
[root@localhost-arr-index2-$(arr-number[2])
[root@localhost-# echo $arr-index2
3
数组遍历
[root@localhost ~] # for v in $farr numberl@}
>do
>echo $v
> done
1
2
3
4
5
示例
#!/bin/bash
#不满足60分的都加到60分
score=(66 58 49 60 88 96)
for ((i=0;i<=&{#score[*]};i++));do
if [ ${score[$i]} -lt 60 ];then
new[$i]=60
else
new[$i]=${score[$i]}
fi
done
echo ${new[*]}
#!/bin/bash
#显示出最大的那个分数
score=(66 58 49 60 88 96)
tmp=0
for ((i=0;i<${#score[*]};i++));do
if [ ${score[$i]} -gt $tmp ];then
tmp=${score[$i]}
fi
done
echo $tmp
#!/bin/bash
#将分数从大到小排序
arr=(85 100 56 69 75 98 65 45)
for ((i=0;i<${#arr[*]};i++))
do
for ((j=$i+1;j<${#arr[*]};j++))
do
if [ ${arr[$i]} -lt ${arr[$j]} ];then
tmp=${arr[$i]}
arr[$i]=${arr[$j]}
arr[$j]=$tmp
fi
done
done
echo ${arr[*]}
数组切片
${数组名[@或*]:起始位置:长度}
[root@centos-7-# arr=(1 2 3 4 5)
[root@centos-7-]# echo $farr[@])
1 2 3 4 5
[root@centos-7-]# echo $farr[@]:0:2}
1 2
root@centos-7 - echo $arr[@]:2:3}
3 4 5
数组的替换
${数组名[@或*]/查找字符/替换字符}
[root@centos-7 -]#arr=(1 2 3 4 5)
[root@centos-7-]# echo ${arr[@14/66}
12 3 66 5
[root@centos-7-]#echo $farr@])
1 2 3 4 5
[root@centos-7-# arr=($(arr[@]/4/66})
[root@centos-7 -]# echo $farr[@])
1 2 3 66 5
数组删除
unset
[root@centos-7 -# arr=(1 2 3 4 5)
[root@centos-7~#unset arr
[root@centos-7 -]# echo ${arr[*])
[root@centos-7- arr=(1 2 3 4 5)
[root@centos-7-#unset arr[2)
[root@centos-7-]# echo ${arr[*])
1 2 4 5
示例
#!/bin/bash
#将低于60分以下的成绩删除
score=(10 20 30 40 50 90 80 50 60)
i=1
for f in ${score[*]};do
if [ $f -lt 60 ];then
unset score[$i]
fi
lei i++
done
echo ${score[*]}
Shell脚本调试
echo命令
bash命令
命令语法
sh [-nvx] 脚本名
set命令
set -x:开启调节模式
set +x:关闭调节模式