微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

shell语句

 
本节内容
 
1. shell流程控制
2. for语句
3. while语句
4. break和continue语句
5. case语句
6. shell编程高级实战
 
shell流程控制
 
流程控制是改变程序运行顺序的指令。linux shell有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case)。下面我将通过例子介绍下,各个语句使用方法
 
if语句
 
格式:
格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi
 
1.1 单分支
 
if 条件表达式; then
命令

例.1
╭─[email protected] ~
╰─? cat test1.sh 130 ↵
#!/bin/bash
if [ 1 -eq 1 ];then
echo "true"
fi
 ╭─[email protected] ~
╰─? bash test1.sh
true
例.2
╭─[email protected] ~
╰─? cat test2.sh
#!/bin/bash
systemctl restart network
if [ $? -eq 0 ];then
echo "重启网卡成功"
fi
╭─[email protected] ~
╰─? bash test2.sh
重启网卡成功
例.3
[email protected] ~
╰─? cat test2.sh
#!/bin/bash
if systemctl restart network;then
echo "重启网卡成功"
fi
╭─[email protected] ~
╰─? bash test2.sh
重启网卡成功

例子.4
 ╭─[email protected] ~
╰─? cat test2.sh
#!/bin/bash
if systemctl restart ndfetwork &>/dev/null;then
echo "重启网卡成功"
fi
╭─[email protected] ~
╰─? bash test2.sh
1.2 双分支
 
if 条件表达式; then
命令
else
命令
fi
 
例1:
╭─[email protected] ~
╰─? cat test2.sh
#!/bin/bash
systemctl restart network &>/dev/null
if [ $? -eq 0 ];then
echo "重启网卡成功"
else
echo "由于其他原因重启网卡失败"
fi
╭─[email protected] ~
╰─? bash test2.sh
重启网卡成功
例.2
╭─[email protected] ~
╰─? cat test3.sh
#!/bin/bash
mun=$(ps aux | grep "crond" | grep -c -v "grep")
if [ $mun -eq 1 ] ;then
echo "计划任务开启"
else
echo "计划任务关闭"
fi
╭─[email protected] ~
╰─? bash test3.sh
计划任务关闭
 
实例2:判断crond进程是否正在运行
-v: 表示取反
-c: 即count,取代通常的输出显示行数

 
实例3:检查主机是否在线
-c:表示发送几次包
-w:表示等待时间。当试图检测不可达主机时此选项很有用。
例.1
╭─[email protected] ~
╰─? cat test4.sh
#!/bin/bash
ip=$1
if ping -c 1 -i 1 $ip &>/dev/null ;then
echo "$ip在线"
else
echo "$ip不在线"
fi
例子2
╭─[email protected] ~
╰─? bash test4.sh 192.168.126.6
192.168.126.6在线
#!/bin/bash
ip=$1
ping -c 1 -i 1 $1 &>/dev/null
if [ $? -eq 0 ] ;then
echo "$ip在线"
else
echo "$ip不在线"
fi

if 语句可以直接对命令状态进行判断,就省去了获取$?这一步!
 
1.3 多分支
 

if 条件表达式; then
命令
elif 条件表达式; then
命令
else
命令
fi

当不确定条件符合哪一个时,就可以把已知条件判断写出来,做相应的处理。
 
实例1:
$1:表示接受用户输入参数
#!/bin/bash
mun=$RANDOM
if [ $mun -lt 500 ] ;then
echo "$mun恭喜中一奖"
elif [ $mun -ge 500 -a $mun -lt 2000 ];then
echo "$mun恭喜中二等奖"
elif [ $mun -ge 2000 -a $mun -lt 10000 ];then
echo "$mun恭喜中三等奖"
elif [ $mun -ge 10000 -a $mun -lt 100000 ];then
echo "$mun恭喜中纪念奖"
else
echo "恭喜中特等奖"

fi
╭─[email protected] ~
╰─? bash test5.sh
5325恭喜中三等奖

如果第一个条件符合就不再向下匹配。
 
shell编程之if语句实战案例
 
需求:
1. 完成用户输入文件或者目录的自动复制,并可以实现用户指定复制目标位置。
2. 用户体验佳。
 

#!/bin/bash
read -p "pls enter a file you want to copy:" file
if [ -f $file -o -d $file ];then
read -p "do you want to copy the $file?(y/n)" sure
confirm=$(echo ${sure} | tr A-Z a-z)
if [ "$confirm" == "y" ];then
read -p "where do you want to copy?" dire
if [ -d $dire ];then
cp -a $file $dire
echo "the $file copied to $dire"
else
echo "the $dire is not exists"
exit 1
fi
elif [ "$confirm" == "n" ];then
echo "bye"
else
echo "pls input y or n"
fi
else
echo "the $file is not exists"
fi

 
练习题1:尝试写一个shell简单的计算器,实现加减乘除。
请输入一个数字: 7
请输入运算符:+
请输入第二个数字:7
7+7=14
 
#!/bin/bash
read -p "数字1: " mnu1
read -p "符号{+|-|*|/}: " mnu2
read -p "数字2: " mnu3
if [ -n "$mnu1" -a -n "$mnu2" -a -n "$mnu3" ];then
if [ "$mnu2" == "+" ];then
echo "${mnu1}${mnu2}${mnu3}=$((${mnu1}${mnu2}${mnu3}))"
elif [ "$mnu2" == "-" ];then
echo "${mnu1}${mnu2}${mnu3}=$((${mnu1}${mnu2}${mnu3}))"
elif [ "$mnu2" == "*" ];then
echo "${mnu1}${mnu2}${mnu3}=$((${mnu1}${mnu2}${mnu3}))"
elif [ "$mnu2" == "/" ];then
echo "${mnu1}${mnu2}${mnu3}=$((${mnu1}${mnu2}${mnu3}))"

else
echo "请输入一个符号{+|-|*|/}"
fi

else
echo "请输入一个数字!"
fi

[email protected] ~
╰─? bash test6.sh
数字1: 7
符号{+|-|*|/}: +
数字2: 7
7+7=14

练习题2:输入一个用户,用脚本判断判断该用户是否存在。
 #!/bin/bash
Read -p “请出入一个用户” user
If id $user &>/dev/null ;then
Echo "$user存在"
Else
Echo "$user不存在"
F i
╭─[email protected] ~
╰─? bash test8.sh
请出入一个用户:z
z不存在
╭─[email protected] ~
╰─? bash test8.sh
请出入一个用户:zhao
zhao存在


for语句
 
格式:for name [ [ in [ word ... ] ] ; ] do list ; done

for 变量名 in 取值列表; do
命令
done

或者
  for 变量名 in 取值列表
  do
命令
  done

 
实例1:
#!/bin/bash
for i in `seq 10`
do
useradd user$i
pass=`echo $RANDOM | md5sum | cut -c 1-6`
echo "$pass" | passwd --stdin user$i
echo -e "用户:user$i \n 密码:$pass " >> /root/test


done

 
实例2:计算100以内偶数和
╭─[email protected] ~
╰─? cat test10.sh
#!/bin/bash
sum=0
for i in `seq 2 2 100`
do
let sum+=$i
done
echo $sum

shell编程之for语句实战案例
 
需求:
1. 批量检查当前教室主机是否在线
╭─[email protected] ~
╰─? cat test11.sh
#!/bin/bash
ip=192.168.126.
for i in `seq 10`
do
if ping -c 1 -w 1 $ip$i &> /dev/null;then
echo "$ip$i在线"
sleep 1
else
echo "$ip$i不在线"
sleep 1
fi

done

练习题1:计算100以内的奇数和
╭─[email protected] ~
╰─? cat test12.sh
#!/bin/bash
sum=0
for i in `seq 1 2 100`
do
let sum+=$i
done
echo "$sum"

[email protected] ~
╰─? bash test12.sh
2500

练习题2:判断/root目录下面的文件类型
#!/bin/bash
for i in `ls -ld /root/* | cut -c 1`
do
type1=$i
if [ "$type1" == "-" ];then
echo "$i 文件"
elif [ "$type1" == "d" ];then
echo "$i目录"
elif [ "$type1" == "l" ];then
echo "$链接文件"
else
echo "无效文件"
fi
done
~


 
while语句
 
条件为真就进入死循环;条件为假就退出循环
格式:while list; do list; done
while 条件表达式; do
命令
done
 
实例1:

#!/bin/bash
while true
do
mun=`free -h | grep Mem | cut -d "G" -f 3 | cut -d "M" -f 3 | tr -d " " `
echo "$(date "+%F_%T")" $mun >> /root/nohup.out
sleep 3
done


当条件表达式为 false 时,终止循环。
 
实例2:条件表达式为 true,将会产生死循环
#!/bin/bash
while [ 1 -eq 1 ]; do
echo "yes"
done
 
也可以条件表达式直接用 true:
#!/bin/bash
while true; do
echo "yes"
done
 
死循环有什么作用那?
可以用来后台运行检测脚本,如下是是一个检测脑裂的脚本
我们只需要在命令行中输入 nohup bash naolie.sh & 即可在后台持续运行该脚本
例子1:检测脑裂

#!/bin/bash
while true
do
ip=`ip a s eth0 | awk -F " +" ‘NR==4{print $3}‘ | awk -F "/" ‘{print $1}‘ | awk -F "." ‘{print $4}‘`1
ping -c 3 -i 1 -W 1 10.220.5.166 &>/dev/null
if [ $? -eq 0 ] && [ $ip = 1001 ];then
echo "happed naolie"
else
echo "everything is ok"
fi
done

 
例子2:检测终端数量

#!/bin/bash
while true
do
num=`who | wc -l`
echo "当前打开终端数量为:$num"
sleep 5
done

 
要想使用 while 循环逐行读取 a.txt 文件,有三种方式:
 
方式 1:
╭─[email protected] ~
╰─? cat test16.sh 130 ↵
#!/bin/bash
cat /etc/passwd | while read line
do
echo "$line"
sleep 2

done

方式2:
╰─? cat test17.sh
#!/bin/bash
while read line
do
echo "$line"
sleep 2
done < /etc/passwd
方式3:
exec < ./a.txt # 读取文件作为标准输出
while read LINE; do
echo $LINE
done
与 while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循环,实际使用中比较少,这里不再讲解。
 

#!/bin/bash
n=0
until [ $n -eq 5 ]
do
let n++
echo "$n"
done

 
break和continue语句
 
break 是终止循环。
continue 是跳出当前循环。
示例 1:在死循环中,满足条件终止循环


#!/bin/bash
num=0
while true
do
let num++
if [ $num -eq 6 ];then
break
fi
echo "$num"
done
~

里面用了 if 判断,并用了 break 语句,它是跳出循环。与其关联的还有一个 continue 语句,它是跳出本次循环。
 
示例 2:举例子说明 continue 用法
#!/bin/bash
num=1
while true
do
let num++
if [ $num -eq 6 ];then
continue
fi
echo "$num"
done
当变量 N 等于 3 时,continue 跳过了本次循环,没有执行下面的 echo。
注意:continue 与 break 语句只能循环语句中使用。
 

[[email protected] ~]# cat test.sh
#!/bin/bash
st=0
while true
do
let st++
if [ $st -eq 5 ];then
continue
elif [ $st -eq 10 ];then
break
else
echo "$st"
fi

done
[[email protected] ~]# bash test.sh
1
2
3
4
6
7
8
9

 
 
case语句
 
case 语句一般用于选择性来执行对应部分块命令。

case 模式名 in
模式 1)
命令
;;
模式 2)
命令
;;
*)
不符合以上模式执行的命令
esac

 
每个模式必须以右括号结束,命令结尾以双分号结束,最后一个模式不需要添加;;。
 
示例1:根据位置参数匹配不同的模式

#!/bin/bash
case $1 in
start)
echo "start."
;;
stop)
echo "stop."
;;
restart)
echo "restart."
;;
*)
echo "Usage: $0 {start|stop|restart}"
esac
# bash test.sh
Usage: test.sh {start|stop|restart}
# bash test.sh start
start.
# bash test.sh stop
stop.
# bash test.sh restart
restart.

 
实例2:

#!/bin/bash
case $1 in
[0-9])
echo "match number."
;;
[a-z])
echo "match letter."
;;
‘-h‘|‘--help‘)
echo "help"
;;
*)
echo "Input error!"
exit
esac
# bash test.sh 1
match number.
# bash test.sh a
match letter.
# bash test.sh -h
help
# bash test.sh --help
help

模式支持的正则有:*、?、[ ]、[.-.]、|。后面有章节单独讲解 Shell 正则表达式。
 
shell编程高级实战
 
实战1:写一个猜数字的小游戏
要求:
1. 猜对退出
2. 数字随机
3. 使用体验佳

#!/bin/bash
clear
num=`echo $RANDOM`
count=0
while true
do
let count++
read -p "pls enter a num you guess:" guessnum
if [ $guessnum -lt $num ]; then
echo "the num is so smaller!"
elif [ $guessnum -gt $num ];then
echo "the num is so bigger!"
elif [ $guessnum -eq $num ];then
echo "right!wonderful! "
break
else
echo "good bye"
exit
fi
done
echo -e "\033[36myou guess $count times\033[0m" #-e允许对下面列出的加反斜线转义的字符进行解释.

 
实战2:检测当前教室在线IP地址
要求:
1.显示美观

#!/bin/bash
. /etc/init.d/functions
ip=172.20.10.
for i in {1..255}
do
if ping -c 1 $ip$i &>/dev/null ;then
echo -n "$ip$i" #-n表示不输出行尾的换行符
success
echo ""
else
echo -n "$ip$i"
failure
echo ""
fi
done

 
实战3:检查软件包是否安装
要求:
1.用户输入软件名即可进行查询


#!/bin/bash
read -p "请出入一个软件名:" Y
if rpm -q $Y ;then
echo "$Y已安装版本"
else
echo "$Y未安装"
fi
~
~

 
实战4:打印九九乘法表
#!/bin/bash
for i in `seq 9`
do
for l in `seq 9`
do
if [ $l -le $i ];then
echo -n " $l*$i=$(($i*$l))"
fi
done
echo " "
done

 
补充练习题
 
1.实现简单计算器(加减乘除)
 
#!/bin/bash
read -p "数字:" A
read -p "符号(+|-|*|/):" B
read -p "数字:" C
if [ -n "$A" -a -n "$B" -a -n "$C" ];then
if [ "$B" == "+" ] ;then
echo "$A$B$C=$(($A$B$C))"
elif [ "$B" == "-" ];then
echo "$A$B$C=$(($A$B$C))"
elif [ "$B" == "*" ] ;then
echo "$A$B$C=$(($A$B$C))"
elif [ "$B" == "/" ];then
echo "$A$B$C=$(($A$B$C))"
else
echo"请输入有效符号"
fi


else
echo "请输入有效数字"
 
2. 批量创建100个以数字开头的文件,并每隔一秒钟输出到终端

#!/bin/bash
for i in {1..100}
do
touch ${i}.txt
echo "${i}.txt"
sleep 1
done

 
3.动态持续监测本机linux系统内存剩余量(仅显示数值),并在终端输出

#!/bin/bash
while true
do
mem=`free -h | grep "Mem" | cut -d "M" -f 4 | tr -d " "`
echo $mem
sleep 1
done
Nohup bash
 
课后练习题

一个脚本: 实现自动化一键部署NFS服务器端和客
户端
#!/bin/bash
pack_num=`ls /mnt | wc -l`
if [ $pack_num -eq 0 ] ;then
mount /dev/cdrom /mnt &>/dev/null
fi
if yum install nfs-utils rpcbind -y &>/dev/null ;then
echo "下载成功"
else
exit
fi
mkdir /test &>/dev/null
echo "/test *(rw)" >> /etc/exports
if systemctl restart nfs rpcbind ;then
echo "重启成功"
else
exit
fi
Setenforce 0 &>/dev/null
Systemctl stop firewalld &>/dev/null

客户端
#!/bin/bash
mount /dev/cdrom /mnt &>/dev/null
yum insatall nfs-utils -y
mkdir /zxw &>/dev/null
mount -t nfs 192.168.126.8:/test /zxw
df -h
~


第二个脚本:实现批量化检测当前教室主机在线状况,在线主机保存至一个文件
#!/bin/bash
. /etc/init.d/functions
ip=192.168.126.
for i in `seq 10`
do
if ping -c 1 -w 1 $ip$i >>/dev/null;then
echo -n "$ip$i"
success
echo ""
echo "$ip$i" >>/root/ip
else

echo -n "$ip$i"
failure
echo ""

fi

 

done

 


第三个脚本:实现批量化创建100个用户,并创建8位随机密码,且可登陆
#!/bin/bash
for i in `seq 100`
do
useradd yonghu$i
mima=$(echo $RANDOM | md5sum | cut -c 1-8)
echo "$mima" | passwd --stdin yonghu$i
echo -e "用户:yonghu$i \n 密码:$miman " >>/root/test


done

 

 

第四个脚本:找出系统中含有某个关键词的文件,并输出到终端,关键词用户输入指定
#!/bin/bash
read -p "请输入关键字 :" X
for i in `find /etc/ -type "f"`
do
if grep $X $i &>/dev/null;then
echo "$i--$X"
fi

done

 


第五个脚本:批量判断当前目录下所有文件类型
 
#!/bin/bash
for i in `ls /var`
do
cd /var
X=`ls -ld $i | cut -c 1`
if [ "$X" == "-" ];then
echo " $i------是文件"
elif [ "$X" == "d" ];then
echo "$i------目录"
elif [ "$X" == "l" ];then
echo "$i------链接文件"
else
echo "$i------无效文件"
fi
done

~
shell练习题
 
 
 
 
参考答案:
 1. 每一秒钟输出/root下的文件至屏幕
#!/bin/bash
for file in `ls /root`
do
echo $file
sleep 1
done
 
2.
2. 打印出包含某个关键词的文件(关键词执行脚本时接收)小,输出

#!/bin/bash
key=$1
for file in `find / -type f`
do
grep "$key" $file &>/dev/null
if [ $? -eq 0 ];then
echo $file
sleep 1
fi
done

 
3.
3. 统计系统中以.sh结尾的文件总大结果以kb为单位
 

#!/bin/bash
sum=0
for size in `find /root -name "*.sh" -exec ls -l {} \; | cut -d " " -f 5`
do
let sum+=$size
done
echo "$((sum/1024))kb"

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐