针对变量的不同取值,分别执行不同的命令序列
这种情况与多分支的if语句非常相似,只不过if语句需要判断多个不同的条件,而case语句指示判断一个变量的不同取值
格式:
case 变量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
....
*)
默认命令序列
esac
实例:
case 控制指令 in
start)
启动XX服务
;;
stop)
停止XX服务
;;
....
*)
显示服务脚本的用法
esac
提示用户输入一个字符
判断出该字符是字母,数字或者其他字符
[root@localhost opt]# vim panduan.sh
#!/bin/bash
read -p "请输入一个字符:" aa
case "$aa" in
[0-9])
echo "你输入的是数字"
;;
[a-z]|[A-Z])
echo "你输入的是字母"
;;
*)
echo "你输入的是符号"
esac
~
[root@localhost opt]# chmod +x panduan.sh
[root@localhost opt]# ./panduan.sh
请输入一个字符:3
你输入的是数字
[root@localhost opt]# ./panduan.sh
请输入一个字符:e
你输入的是字母
[root@localhost opt]# ./panduan.sh
请输入一个字符:#
你输入的是符号
成绩0-100分
0-59分:不及格
60-74:及格
75-84:良好
85-100:优秀
[root@localhost opt]# vim chengji.sh
#!/bin/bash
read -p "请输入你的成绩:" aa
case "$aa" in
#[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])
[1-5][0-9]|[0-9])
echo "你的成绩不合格"
;;
6[0-9]|7[0-4])
echo "你的成绩合格"
;;
7[5-9]|8[0-4])
echo "你的成绩良好"
;;
8[5-9]|9[0-9]|100)
echo "你的成绩优秀"
;;
*)
echo "输入有误"
esac
~
[root@localhost opt]# ./chengji.sh
请输入你的成绩:0
你的成绩不合格
[root@localhost opt]# ./chengji.sh
请输入你的成绩:59
你的成绩不合格
[root@localhost opt]# ./chengji.sh
请输入你的成绩:60
你的成绩合格
[root@localhost opt]# ./chengji.sh
请输入你的成绩:74
你的成绩合格
[root@localhost opt]# ./chengji.sh
请输入你的成绩:75
你的成绩良好
[root@localhost opt]# ./chengji.sh
请输入你的成绩:84
你的成绩良好
[root@localhost opt]# ./chengji.sh
请输入你的成绩:85
你的成绩优秀
[root@localhost opt]# ./chengji.sh
请输入你的成绩:100
你的成绩优秀
[root@localhost opt]# ./chengji.sh
请输入你的成绩:101
输入有误
[root@localhost opt]# ./chengji.sh
请输入你的成绩:-1
输入有误
用户名存放在users.txt文件中,每行一个
初始密码均设为123456
[root@localhost opt]# vim user.txt
zhangsan
lisi
wangermazi
zhaoliu
tianji
wangba
[root@localhost opt]# vim useradd.sh
#!/bin/bash
Lists=$(cat /opt/user.txt)
for bb in $Lists
do
useradd $bb
echo "123456" | passwd --stdin $bb
echo "$bb添加成功"
done
[root@localhost opt]# chmod +x useradd.sh
[root@localhost opt]# ./useradd.sh
Changing password for user zhangsan.
passwd: all authentication tokens updated successfully.
zhangsan添加成功
useradd: warning: the home directory already exists.
Not copying any file from skel directory into it.
Creating mailbox file: File exists
Changing password for user lisi.
passwd: all authentication tokens updated successfully.
lisi添加成功
Changing password for user wangermazi.
passwd: all authentication tokens updated successfully.
wangermazi添加成功
Changing password for user zhaoliu.
passwd: all authentication tokens updated successfully.
zhaoliu添加成功
Changing password for user tianji.
passwd: all authentication tokens updated successfully.
tianji添加成功
Changing password for user wangba.
passwd: all authentication tokens updated successfully.
wangba添加成功
[root@localhost opt]# cat /etc/passwd | grep "bash"
root:x:0:0:root:/root:/bin/bash
dd:x:1000:1000:cn-tangzheng:/home/dd:/bin/bash
zhangsan:x:1001:1001::/home/zhangsan:/bin/bash
lisi:x:1002:1002::/home/lisi:/bin/bash
wangermazi:x:1003:1003::/home/wangermazi:/bin/bash
zhaoliu:x:1004:1004::/home/zhaoliu:/bin/bash
tianji:x:1005:1005::/home/tianji:/bin/bash
wangba:x:1006:1006::/home/wangba:/bin/bash
脚本可以适当修改优化:如
echo "123456" | passwd --stdin $bb &> /dev/null
批量删除用户:在刚刚的基础上修改
[root@localhost opt]# vim useradd.sh
#!/bin/bash
Lists=$(cat /opt/user.txt)
for bb in $Lists
do
userdel -r $bb '-r 删除家目录'
#echo "123456" | passwd --stdin $bb &> /dev/null
echo "$bb删除成功"
done
[root@localhost opt]# ./useradd.sh
zhangsan删除成功
lisi删除成功
wangermazi删除成功
zhaoliu删除成功
tianji删除成功
wangba删除成功
[root@localhost opt]# cat /etc/passwd | grep "bash"
root:x:0:0:root:/root:/bin/bash
dd:x:1000:1000:cn-tangzheng:/home/cn-tangzheng:/bin/bash
检测IP地址192.168.197.0-192.168.197.10段落
使用ping命令检测各主机的连通性
[root@localhost opt]# vim ipchk.sh
#!/bin/bash
for ((i=1;i<=10;i++))
do
ping -c 3 -i 0.2 -W 3 "192.168.197.$i" &> /dev/null
if [ $? -eq 0 ]
then
echo "Host 192.168.197.$i is up"
else
echo "Host 192.168.197.$i is down"
fi
done
[root@localhost opt]# ./ipchk.sh
Host 192.168.197.1 is up
Host 192.168.197.2 is up
Host 192.168.197.3 is down
Host 192.168.197.4 is down
Host 192.168.197.5 is down
Host 192.168.197.6 is down
Host 192.168.197.7 is down
Host 192.168.197.8 is down
Host 192.168.197.9 is down
Host 192.168.197.10 is down
方式一:
#!/bin/bash
for ((i=1;i<=10;i++))
do
echo "$i"
done
方式二:
#!/bin/bash
i=1
for ((;i<=10;i++))
do
echo "$i"
done
方式三:
#!/bin/bash
i=1
for ((;i<=10;))
do
echo "$i"
let i++
done
方式四:
#!/bin/bash
i=1
for ((;;))
do
if [ $i -le 10 ]
then
echo "$i"
let i++
else
exit 0
fi
done
输出结果
[root@localhost opt]# ./number.sh
1
2
3
4
5
6
7
8
9
10
let 对整数进行数学运算
let和双小括号 (( )) 一样,let 命令也只能进行整数运算,不能对小数(浮点数)或者字符串进行运算。
语法格式
let 表达式
或
let "表达式"
或
let '表达式'
以上方式都等价于 ((表达式))
当表达式中含有 Shell 特殊字符(例如 |)时,需要用双引号" "
或者单引号' '
将表达式包围起来。
和 (( )) 类似,let 命令也支持一次性计算多个表达式,并且以最后一个表达式的值作为整个 let 命令的执行结果。
方式一:计算偶数的和
#!/bin/bash
sum=0
for((i=0;i<=10;i+=2))
do
let sum+=$i
done
echo "总和为:$sum"
方式一:计算奇数的和
#!/bin/bash
sum=0
for((i=1;i<=10;i+=2))
do
let sum+=$i
done
echo "总和为:$sum"
方式二:求偶数和
#!/bin/bash
sum=0
for((i=0;i<=10;i+=2))
do
if [ `expr $i % 2` -eq 0 ]
then
let sum+=$i
fi
done
echo "总和为:$sum"
#!/bin/bash
sum=0
for((i=1;i<=10;i+=2))
do
if [ `expr $i % 2` -eq 1 ]
then
let sum+=$i
fi
done
echo "总和为:$sum"
重复测试某个条件,只要条件成立则反复执行
语句结构
while 条件测试操作
do
命令序列
done
语句结构示例
while 未猜中正确的价格
do
反复猜测商品价格
done
使用while循环语句输出1-10数字
#!/bin/bash
i=0
while [ $i -le 10 ]
do
echo "$i"
let i++
done
[root@localhost opt]# . cccc.sh
0
1
2
3
4
5
6
7
8
9
10
while true:死循环有时候也有奇效,可与用户交互
#!/bin/bash
while true
do
read -p "请输入yes退出:" KEY
if [ $KEY = yes ]
then
break
fi
done
echo "正常退出"
[root@localhost opt]# ./sixunhuan.sh
请输入yes退出:no
请输入yes退出:1
请输入yes退出:d
请输入yes退出:!
请输入yes退出:a
请输入yes退出:yes
正常退出
用户名称以stu开头,按数字顺序进行编号
一共添加20个用户,即stu1,stu2…stu20
初始密码设置为
#!/bin/bash
i=0
while [ $i -le 19 ]
do
let i++
useradd stu$i
echo "123456" | passwd --stdin stu$i &> /dev/null
echo "stu$i添加成功"
done
echo "添加完毕"
[root@localhost opt]# ./useradd.sh
stu1添加成功
stu2添加成功
stu3添加成功
stu4添加成功
stu5添加成功
stu6添加成功
stu7添加成功
stu8添加成功
stu9添加成功
stu10添加成功
stu11添加成功
stu12添加成功
stu13添加成功
stu14添加成功
stu15添加成功
stu16添加成功
stu17添加成功
stu18添加成功
stu19添加成功
stu20添加成功
添加完毕
通过变量RANDOM获得随机数
提示用户猜测并记录次数,猜中后退出循环
#!/bin/bash
A=`expr $RANDOM % 1000`
i=0
echo "商品的实际价格为0-999之间,猜猜看是多少?"
read -p "请输入你猜测的价格数目:" num
while [ $num -le 999 ] && [ $num -ge 1 ]
do
let i++
if [ $num -eq $A ]
then
echo "恭喜你答对了,实际价格是$A"
echo "你一共猜测了$i 次"
exit 0
elif [ $num -lt $A ]
then
echo "太低了"
read -p "请输入你猜测的价格数目:" num
else
echo "太高了"
read -p "请输入你猜测的价格数目:" num
fi
done
命令格式
continue n
n 表示循环的层数:
如果省略 n,则表示 continue 只对当前层次的循环语句有效,遇到 continue 会跳过本次循环,忽略本次循环的剩余代码,直接进入下一次循环。
如果带上 n,比如 n 的值为 2,那么 continue 对内层和外层循环语句都有效,不但内层会跳过本次循环,外层也会跳过本次循环,其效果相当于内层循环和外层循环同时执行了不带 n 的 continue。这么说可能有点难以理解,稍后我们通过代码来演示。
continue 关键字也通常和 if 语句一起使用,即满足条件时便跳出循环。
#!/bin/bash
for ((k=1;k<=9;k++))
do
for ((i=1;i<=$k;i++))
do
echo -n ""$k"x"$i"=$(expr $k \* $i) "
if [ $i -eq $k ]
then
echo -e '\n'
fi
done
done
[root@localhost opt]# ./99.sh
1x1=1
2x1=2 2x2=4
3x1=3 3x2=6 3x3=9
4x1=4 4x2=8 4x3=12 4x4=16
5x1=5 5x2=10 5x3=15 5x4=20 5x5=25
6x1=6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36
7x1=7 7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49
8x1=8 8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64
9x1=9 9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81
奖池观众:zhangsan,lisi,wangwu
奖池观众名单在name.txt中
共10次投票,使用随机数的方法挑选幸运观众,票数最多获胜
#!/bin/bash
B=0
C=0
D=0
for ((i=1;i<=10;i++))
do
A=$(expr $[RANDOM%3+1])
list=$(cat /opt/name.txt|grep "$A" |awk -F: '{print $2}')
case $list in
zhangsan)
let B++
;;
lisi)
let C++
;;
*)
let D++
esac
echo "$list"
done
[root@localhost opt]# ./luckly.sh
lisi
wangwu
lisi
lisi
wangwu
zhangsan
zhangsan
lisi
lisi
wangwu
zhangsan:2票lisi5票wangwu3票
[root@localhost opt]# ./luckly.sh
zhangsan
wangwu
zhangsan
wangwu
zhangsan
lisi
zhangsan
wangwu
wangwu
wangwu
zhangsan:4票lisi1票wangwu5票
计算1–50的和
通过循环累加的方式计算1–50的和
#!/bin/bash
i=1
S=0
until [ $i -eq 51 ]
do
let S+=$i
let i++
done
echo "$S"
[root@localhost opt]# ./jisuan.sh
1275
为指定用户发送在线消息
#!/bin/bash
username=$1
#判断格式参数是否为空
if [ $# -lt 1 ]
then
echo "Usage:`basename $0` []"
exit 1
fi
#判断账号是否存在
if grep "^$username:" /etc/passwd &> /dev/nell;then :
else
echo "用户不存在"
exit 2
fi
#判断用户是否在线
until who | grep "$username" &> /dev/null
do
echo "用户不在线,正在尝试连接"
sleep 3
done
mes=$*
echo "$mes" | write "$username"
[root@localhost opt]# ./mes.sh
Usage:mes.sh []
[root@localhost opt]# ./mes.sh wangwu
用户不存在
[root@localhost opt]# ./mes.sh stu1
用户不在线,正在尝试连接
用户不在线,正在尝试连接
^C
其中,return返回的是状态码,需要使用$?调取
echo 返回的是值,使用变量调用
传参:指位置变量
可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
两个数字求个
#!/bin/bash
#sum=0
function A (){
read -p "请输入第一个数字:" B
read -p "请输入第二个数字:" C
sum=`expr $B + $C`
echo "$B + $C = $sum"
return 3
}
#echo $sum
A $B $C
[root@localhost opt]# ./han.sh
请输入第一个数字:4
请输入第二个数字:2
4 + 2 = 6
[root@localhost opt]# echo $?
3
[root@localhost opt]# echo $?
0
获取数组长度
使用for循环获取具体信息,使用下标或索引标记数组中数据的位置
可以存放多种数据,如:整型,长整形,浮点型(单精度,双精度),字符串等
获取元素长度
遍历元素
元素切片
元素替换
元素删除
…
注意,忌讳数组越界,
数组下标从0开始算
数组长度从1开始算
长度为4,数组长度表示为1,2,3,4;数组下标表示为0,1,2,3
shell中数组是可变长的
方法一:
基本格式
数组名=(value0 value1 value2...)
例如
ABC=(11 22 33...)
方法二:
基本格式
数组名=([0]=value [1]=value [2]=value...)
例如
ABC=([0]=11 [1]=22 [2]=33...)
方法三:数组元素之间使用空格隔开
基本格式
列表名=“value0 value1 value2”
数组名=($列表名)
例如
AAA=“11 22 33...”
ABC=($列表名)
方法四:
基本格式
数组名[0]=“value”
数组名[1]=“value”
数组名[2]=“value”
...
例如
AAA[0]=“11”
AAA[1]=“22”
AAA[2]=“33”
...
数值类型
字符类型
数组只可存放数值或字符
获取数组长度
基本格式
${#数组名[@/*]}
例如
[root@localhost opt]# abc=(10 20 30)
[root@localhost opt]# echo ${abc[*]}
10 20 30
[root@localhost opt]# echo ${#abc[*]}
3
读取某下标赋值
基本格式
${数组名[下标]}
例如
[root@localhost opt]# echo ${abc[1]}
20
[root@localhost opt]# echo ${abc[0]}
10
[root@localhost opt]# echo ${abc[1]}
20
[root@localhost opt]# echo ${abc[2]}
30
#!/bin/bash
for ((i=1;i<=5;i++));do
read -p "请输入第$i个数字:" num
abc[$i-1]=$num
done
max=${abc[0]}
for ((k=1;k<=${#abc[*]}-1;k++));do
if [ $max -lt ${abc[$k]} ];then
max=${abc[$k]}
fi
done
echo "最大值是:$max"
[root@localhost opt]# chmod +x max.sh
[root@localhost opt]# ./max.sh
请输入第1个数字:2
请输入第2个数字:3
请输入第3个数字:66
请输入第4个数字:33
请输入第5个数字:111
最大值是:111