本节内容
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
命令
fi
实例:
- #!/bin/bash
- N=10
- if [ $N -gt 5 ]; then
- echo yes
- fi
- # bash test.sh
- yes
1.2 双分支
if 条件表达式; then
命令
else
命令
fi
实例 1:
- #!/bin/bash
- N=10
- if [ $N -lt 5 ]; then
- echo yes
- else
- echo no
- fi
- # bash test.sh
- no
实例 2: 判断 crond 进程是否正在运行
-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 语句可以直接对命令状态进行判断, 就省去了获取 $? 这一步!
1.3 多分支
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
如果第一个条件符合就不再向下匹配.
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
练习题 2: 输入一个用户, 用脚本判断判断该用户是否存在.
for 语句
格式: 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"
shell 编程之 for 语句实战案例
需求:
1. 批量检查当前教室主机是否在线
- #!/bin/bash
- ip=192.168.7.
- for i in {1..255}
- do
- ping -c 1 -w 1 $ip$i &>/dev/null
- if [ $? -eq 0 ];then
- echo "$ip$i 在线!"
- else
- echo "$ip$i 不在线!"
- fi
- done
练习题 1: 计算 100 以内的奇数和
while 语句
条件为真就进入死循环; 条件为假就退出循环
格式: 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: 检测脑裂
- #!/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:
- #!/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 语句
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 语句只能循环语句中使用.
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 "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
来源: https://www.cnblogs.com/kenken2018/p/10227142.html