4、shell if case while for
Shell__逻辑结构
一、IF 判断
if ... then ... fi
if [ 条件判断式 ];then
当条件判断式成立时,可以进行的命令。
fi # 结束这个判断语句结构
例:
提示输入一个整数,程序判断输入的值是否大于 18
风格 1
#!/usr/bin/env sh
read -p "请输入一个整数:" num
if [ "$num" -gt 18 ];then
echo "你输入的数值大于 18"
fi
echo "hello..."
风格2
#!/usr/bin/env sh
read -p "请输入一个整数:" num
if [ "$num" -gt 18 ]
then
echo "你输入的数值大于 18"
fi
echo "hello..."
if ... then ... else....fi
多重、复杂条件判断式
如果 是真的 那么 ... 否则 ...
一颗红心,两手准备
if [ 条件判断式 ]; then
当条件判断式成立时,可以进行的指令工作内容;
else
当条件判断式不成立时,可以进行的指令工作内容;
fi
示例:
image.png判断用户输出的字符串
输入 y
就输出文本内容 "script is running..."
否则输出文本内容 "STOP"
if ... elif ... elif ... else ... fi
多个条件判断 (if ... elif ... elif ... else) 分多种不同情况执行
if [ 条件判断式一 ]; then
当条件判断式一成立时,可以进行的指令工作内容;
elif [ 条件判断式二 ]; then
当条件判断式二成立时,可以进行的指令工作内容;
else
当条件判断式一与二均不成立时,可以进行的指令工作内容;
fi
注意
elif 也是个判断式,因此出现 elif 后面都要接 then 来处理!但是 else 已经是最后的没有成立的结果了, 所以 else 后面并没有 then
示例
通过判断输入的整数,判断是什么常用服务
#!/usr/bin/env sh
read -p "请输入一个常用的服务默认端口号:" port
if [ "$port" -eq 80 ];then
echo "http和nginx 服务"
elif [ "$port" -eq 3306 ];then
echo "mysql 服务"
elif [ "$port" -eq 21 ] || [ "$port" -eq 20 ];then
echo "ftp 服务"
elif [ "$port" -eq 22 ];then
echo "sshd 服务"
elif [ "$port" -eq 23 ];then
echo "telnet 服务"
else
echo "未知服务"
fi
实战案例
服务状态检测工具
通过获取目前系统中的服务进程,判断都有那些服务处于运行状态
[root@localhost ~]# sh fuwu.sh
输入一个常用的服务默认端口:80
http和nginx 服务
在判断中支持正则
使用双中括号 [[ ]]
匹配 使用 =~
比如: [[ "$val" =~ [a-z]+ ]]
=~ 表示 匹配
[a-z+] 是正表达式,不需要用任何引号,用了引号就会被识别为普通字符串
不匹配 使用 !
比如: [[ ! "$val" =~ [0-9]+ ]]
示例
#!/usr/bin/env sh
name=shark
if [[ "$name" =~ [a-z]+ ]];then
echo "ok"
fi
if [[ ! "$name" =~ [0-9]+ ]];then
echo "good"
fi
嵌套
#!/usr/bin/env sh
read -p "请输入一个常用的服务默认端口号:" port
if [[ "$port" =~ [0-9]+ ]];then
if [ "$port" -eq 80 ];then
echo "HTTP 服务"
elif [ "$port" -eq 3306 ];then
echo "Mysql 服务"
elif [ "$port" -eq 21 ] || [ "$port" -eq 20 ];then
echo "FTP 服务"
elif [ "$port" -eq 22 ];then
echo "SSHD 服务"
elif [ "$port" -eq 23 ];then
echo "Telnet 服务"
else
echo "未知服务"
fi
else
echo "nmber"
fi
二、 利用 case ..... esac 判断
基本语法
case $变量名称 in <==关键字为 case ,还有变量前有钱字号
"第一个变量的值") <==每个变量内容建议用双引号括起来,关键字则为小括号 )
程序段
;; <==每个类别结尾使用两个连续的分号来处理!
"第二个变量的值")
程序段
;;
*) <==最后一个变量内容都会用 * 来代表所有其他值
不包含第一个变量内容与第二个变量内容的其他程序运行段
exit 1
;;
esac <==反过来写,结束当前语句结构!
运维工具箱
#!/bin/bash
cat << EOF
m|M) show memory usages;
d|D) show disk usages;
q|Q) quit
EOF
read -p "Your choice" choice
case $choice in
m|M)
free -m
;;
d|D)
df -h
;;
q|Q)
exit
;;
*)
echo "Invalid input"
;;
esac
服务端口查询
#!/bin/bash
read -p "输入你想查询的端口号" hao
case $hao in
"80")
echo "httpd和nginx 服务"
;;
"3306")
echo "mksql 服务"
;;
"8080")
echo "tomcat 服务"
;;
"9000")
echo "php 服务"
;;
"22")
echo "sshd 服务"
;;
"21")
echo "ftp 服务"
;;
"23")
echo "telnet 服务"
;;
esac
三、while ... do ... done (不确定的循环)
每次循环体执行完,while 都会检查条件是否为真,为真继续循环,否则终止循环。
计数
n=0
while [ "$n" -lt 5 ]
do
let n++
echo "$n"
done
读文件
while read line
do
echo $line
done < /etc/passwd
每次循环, 都会把 /etc/passwd 中的每一个行内容 赋值给变量 line
四、 for do done (固定的循环)
image.pngfor 循环中 变量的取值方式
1、从一组字符串中取值
for var in one two three four five
do
echo "****************************"
echo '$var is ' $var
done
2、从位置变量中取值
for var
do
echo '-----------------------------'
echo '$var is ' $var
done
执行方式
sh bianliang.sh 1 2
输出结果
------------------------
$var is 1
------------------------
$var is 2
3、累计变化的格式中取值
#!/bin/bash
for ((var=1;var<=10;var++))
do
echo "------------------------"
echo '$var is ' $var
done
d. 从命令结果中取值
#!/bin/bash
for var in $(cat file.txt)
do
echo " ------------------------"
echo '$var is ' $var
done
IFS
修改 for 循环中的分界符,默认是 空格
示例 a.txt 文件的内容
hello world name age
hello world name age
# 先保存原来的值
old_ifs=$IFS
# 设置分界符为 回车
IFS=$'\n'
for line in $(cat a.txt)
do
echo $line
done
# 把变量的值回复成原来的状态
export IFS=$old_ifs
实例
九九乘法表
#!/bin/bash
for i in {1..9}
do
for j in {1..9}
do
if [ $j -le $i ]
then
echo -n " $j*$i=$((j*i)) "
fi
done
echo ""
done
执行结果
[root@localhost ~]# sh chengfa.sh
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
删除指定目录下的空文件
#!/bin/bash
read -p "输入你想要删除的目录" mulu
cd $mulu
for i in `ls`
do
if [ -f $i ]
then
if [ ! -s $i ]
then
rm -rf $i
fi
fi
done
补充:数值运算
➜ ~ n=1
➜ ~ let n++
➜ ~ echo $n
2
➜ ~ (( n++ ))
➜ ~ echo $n
3
➜ ~ a=2
➜ ~ b=3
➜ ~ let f=a+b
➜ ~ echo $n
3
➜ ~ echo $f
5
➜ ~ let f = a + b ==> 错误
zsh: bad math expression: operand expected at `='
➜ ~ let "f = a + b"
➜ ~ echo $f
5
五、break 和 continue
break 就是退出循环,循环不再继续了。假如是嵌套的循环,就是退出当前层级的循环。
continue 是停止本次循环体内的代码,继续进行下一次循环。
1. 单层循环的 break
示例代码
运行结果
2. 单层循环的 continue
示例代码
执行结果
image.png
3. 多层循环的 break
示例代码
执行结果
image.png