1. shell流程控制
2. for语句
3. while语句
4. break和continue语句
5. case语句
6. shell编程高级实战node
流程控制是改变程序运行顺序的指令。linux shell有一套本身的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case)。下面我将经过例子介绍下,各个语句使用方法linux
格式:
格式:if list; then list; [ elif list; then list; ] ... [ else list; ] finginx
-if 条件表达式; then
-命令
-fiweb
实例:正则表达式
#!/bin/bash N=10 if [ $N -gt 5 ]; then echo yes fi # bash test.sh yes
if 条件表达式; then
命令
else
命令
fishell
实例1:编程
#!/bin/bash N=10 if [ $N -lt 5 ]; then echo yes else echo no fi # bash test.sh no
实例2:判断crond进程是否正在运行bash
-v: 表示取反
-c: 即count,取代一般的输出,显示行数服务器
#!/bin/bash NAME=crond NUM=$(ps aux | grep $NAME | grep -vc grep) if [ $NUM -eq 1 ]; then echo "$NAME running." else echo "$NAME is not running!" fi
实例3:检查主机是否在线
-c:表示发送几回包
-w:表示等待时间。当试图检测不可达主机时此选项颇有用。命令行
#!/bin/bash if ping -c 1 192.168.1.1 &>/dev/null; then echo "OK." else echo "NO!" fi
if 语句能够直接对命令状态进行判断,就省去了获取$?这一步!
if 条件表达式; then
命令
elif 条件表达式; then
命令
else 命令
fi
当不肯定条件符合哪个时,就能够把已知条件判断写出来,作相应的处理。
实例1:
$1:表示接受用户输入参数
#!/bin/bash N=$1 if [ $N -eq 3 ]; then echo "eq 3" elif [ $N -eq 5 ]; then echo "eq 5" elif [ $N -eq 8 ]; then echo "eq 8" else echo "no" fi
若是第一个条件符合就再也不向下匹配。
需求:
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
练习题2:输入一个用户,用脚本判断判断该用户是否存在。
格式:for name [ [ in [ word ... ] ] ; ] do list ; done
for 变量名 in 取值列表; do
命令
done
或者
for 变量名 in 取值列表
do
命令
done
实例1:
#!/bin/bash for i in {1..3}; do echo $i done # bash test.sh 1 2 3
实例2:计算100之内偶数和
#!/bin/bash sum=0 for i in `seq 2 2 100` do let sum+=$i done echo "$sum"
例子3:建立100个用户并设置6位随机密码
[root@ken ~]# cat test9.sh
#!/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/passwd done
执行结果:
[root@ken ~]# cat passwd
帐户:user1
密码:69a70a
帐户:user2
密码:444c02
帐户:user3
密码:6b381f
帐户:user4
密码:28d8fd
需求:
1. 批量检查当前教室主机是否在线
#!/bin/bash . /etc/init.d/functions ip=192.168.7. for i in {100..150} do if ping -c 1 -w 1 $ip$i &>/dev/null;then echo -n "$ip$i在线!" success echo "" else echo -n "$ip$i不在线!" failure echo "" fi done
练习题1:计算100之内的偶数和
[root@ken ~]# cat test13.sh
#!/bin/bash sum=0 for i in `seq 2 2 100` do let sum+=$i done echo “$sum”
执行结果:
[root@ken ~]# bash test13.sh
2550
练习题2:判断/root目录下面的文件类型
#!/bin/bash for i in `ls /root` do type1=`ls -ld $i | cut -c 1` if [ “$type1” == “-” ];then echo “$i是普通文件” elif [ “$type1” == “l” ];then echo “$i是链接文件” elif [ “$type1” == “d” ];then echo “$i是目录” else echo “该文件类型没法识别” fi done
执行结果:
[root@ken ~]# bash error.sh
error.sh是普通文件
free_mem是普通文件
ken是目录
nohup.out是普通文件
passwd是普通文件
t是普通文件
test10.sh是普通文件
test11.sh是普通文件
test12.sh是普通文件
test13.sh是普通文件
test15.sh是普通文件
test16.sh是普通文件
test18.sh是普通文件
test19.sh是普通文件
条件为真就进入死循环;条件为假就退出循环
格式:while list; do list; done
while 条件表达式; do
命令
done
实例1:
#!/bin/bash N=0 while [ $N -lt 5 ]; do let N++ echo $N done # bash test.sh 1 2 3 4 5
当条件表达式为 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:持续检测内存剩余量,并每隔1分钟输出至一个文件中
[root@ken ~]# cat test15.sh #!/bin/bash while true do mem=`free -h | grep “Mem” | cut -d “M” -f 4 | tr -d ” “` echo “$(date “+%F %T”) $mem” >> /root/free_mem sleep 2 done
执行结果:
[root@ken ~]# tail -f free_mem
2019-05-31 11:39:11 736
2019-05-31 11:39:13 736
2019-05-31 11:39:15 736
2019-05-31 11:39:17 736
2019-05-31 11:39:19 736
2019-05-31 11:39:21 736
2019-05-31 11:39:23 736
例子2:持续检测内存剩余量,并每隔1分钟输出至一个文件中,并放在后台运行
1.&
[root@ken ~]# bash test15.sh &
这种写法关闭终端以后脚本退出
要想使用 while 循环逐行读取 a.txt 文件,有三种方式:
方式 1:
#!/bin/bash cat ./a.txt | while read LINE; do echo $LINE done
方式2:
#!/bin/bash while read LINE; do echo $LINE done < ./a.txt
方式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 是跳出当前循环。
示例 1:在死循环中,知足条件终止循环
#!/bin/bash N=0 while true; do let N++ if [ $N -eq 5 ]; then break fi echo $N done # bash test.sh 1 2 3 4
里面用了 if 判断,并用了 break 语句,它是跳出循环。与其关联的还有一个 continue 语句,它是跳出本次循环。
示例 2:举例子说明 continue 用法
#!/bin/bash N=0 while [ $N -lt 5 ]; do let N++ if [ $N -eq 3 ]; then continue fi echo $N done # bash test.sh 1 2 4
当变量 N 等于 3 时,continue 跳过了本次循环,没有执行下面的 echo。
注意:continue 与 break 语句只能循环语句中使用。
[root@ken-node1 ~]# 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 [root@ken-node1 ~]# bash test.sh 1 2 3 4 6 7 8 9
两个语句只能用在循环语句中!
break 是终止循环。
continue 是跳出当前循环。
例子1:break
[root@ken ~]# cat test19.sh
#!/bin/bash num=1 while true do let num++ if [ $num -eq 5 ];then break fi echo “$num” done
执行结果:
[root@ken ~]# bash test19.sh
2
3
4
例子2:continue
[root@ken ~]# cat test20.sh
#!/bin/bash num=0 while true do let num++ if [ $num -eq 5 ];then continue fi echo “$num” done
执行结果:
[root@ken ~]# bash test20.sh | head
1
2
3
4
6
7
8
9
10
11
实际用法:
#!/bin/bash while true do num=`ss -tnl | grep “80” | wc -l` if [ $num -eq 0 ];then systemctl restart nginx if [ $? -ne 0 ];then echo “`date ‘+%F %T’` 152.136.127.116腾讯云主机web服务宕机,技术流ken请尽快上线修复!” | mail -s “152.136.127.116腾讯云主机 web宕机” 1614833188@qq.com exit else echo “`date ‘+%F %T’` 152.136.127.116腾讯云主机 web宕机已自动恢复” | mail -s “152.136.127.116腾讯云主机 web宕机恢复” 1614833188@qq.com continue fi fi done
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 正则表达式。
要求:
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容许对下面列出的加反斜线转义的字符进行解释.
要求:
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
要求:
1.用户输入软件名便可进行查询
#!/bin/bash read -p "pls enter a softname:" softname if rpm -q $softname &>/dev/null ;then echo "the $softname is already installed" else echo "the $softname" is not installed fi
#!/bin/bash for i in `seq 9` do for a in `seq 9` do if [ $a -le $i ];then echo -n "$a*$i=$(($i*$a)) " 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+$c=$(($a+$c))" elif [ "$b" == "-" ];then echo "$a-$c=$(($a-$c))" elif [ "$b" == "*" ];then echo "$a*$c=$(($a*$c))" elif [ "$b" == "/" ];then echo "$a/$c=$(($a/$c))" else echo "请输入+—*%" fi else echo "请按照要求输入内容!" fi
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
写一个脚本: 实现自动化一键部署NFS服务器端和客户端
第二个脚本:实现批量化检测当前教室主机在线情况,在线主机保存至一个文件中
第三个脚本:实现批量化建立100个用户,并建立8位随机密码,且可登录
第四个脚本:找出系统中含有某个关键词的文件,并输出到终端,关键词用户输入指定
第五个脚本:批量判断当前目录下全部文件类型
1. 每一秒钟输出/root下的文件至屏幕
2. 打印出包含某个关键词的文件(关键词执行脚本时接收)
3. 统计系统中以.sh结尾的文件总大小,输出结果以kb为单位
参考答案:
#!/bin/bash for file in `ls /root` do echo $file sleep 1 done
#!/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
#!/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"