一.流程控制语句
1.基本语法结构
F: false 假
T : true 真
if [ condition ];then
command
command
fi
[ 条件 ] && command
if [ condition ];then
command1
else
command2
fi
[ 条件 ] && command1 || command2
if [ condition1 ];then
command1 结束
elif [ condition2 ];then
command2 结束
else
command3
fi
注释:
如果条件1满足,执行命令1后结束;如果条件1不满足,再看条件2,如果条件2满足执行命令2后结束;如果条件1和条件2都不满足执行命令3结束.
if [ condition1 ];then
command1
if [ condition2 ];then
command2
fi
else
if [ condition3 ];then
command3
elif [ condition4 ];then
command4
else
command5
fi
fi
注释:
如果条件1满足,执行命令1;如果条件2也满足执行命令2,如果不满足就只执行命令1结束;
如果条件1不满足,不看条件2;直接看条件3,如果条件3满足执行命令3;如果不满足则看条件4,如果条件4满足执行命令4;否则执行命令5
2.应用案例
需求1: 判断主机间是否可以ping通
思路:
1. 使用哪个命令实现 ping -c
2. 根据命令的执行结果状态来判断是否通 $?
3. 根据逻辑和语法结构来编写脚本(条件判断或者流程控制)
[root@shell ~]# vim ping.sh
#!/bin/bash
read -p "请输入需要主机IP地址:" IP
# 获取需要ping通主机IP地址(定义变量交互式获取)
ping -c1 $IP &>/dev/nulll
# ping命令测试主机间互通
if [ $? -eq 0 ];then
echo "当前主机与$IP主机间可以ping通"
else
echo "当前主机无法与$IP主机ping通"
fi
[root@shell ~]# source ping.sh
请输入需要主机IP地址:10.1.1.14
当前主机与10.1.1.14主机间可以ping通
[root@shell ~]# source ping.sh
请输入需要主机IP地址:192.168.20.1
当前主机无法与192.168.20.1主机ping通
需求2: 判断一个进程是否存在
思路:
1.查看进程的相关命令 ps -ef pgrep ps auxf pidof
2.根据命令的返回状态值来判断进程是否存在 $?
3.根据逻辑用脚本语言实现
[root@shell ~]# vim process.sh
#!/bin/bash
read -p "请输入需要判断的进程名:" process
# 获取进程名
pgrep $process &>/dev/null
# 通过命令查看进程是否存在
if [ $? -eq 0 ];then
echo "进程$process存在"
else
echo "进程$process不存在"
fi
[root@shell ~]# source process.sh
请输入需要判断的进程名:bash
进程bash存在
[root@shell ~]# source process.sh
请输入需要判断的进程名:httpd
进程httpd不存在
拓展(另一种方法):
[root@shell ~]# vim process2.sh
#!/bin/bash
#!/bin/bash
read -p "请输入需要判断的进程名:" process
# 获取进程名
pgrep $process &>/dev/null
[ $? -eq 0 ] && echo "进程$process存在" || echo "进程$process不存在"
[root@shell ~]# source process2.sh
请输入需要判断的进程名:bash
进程bash存在
pgrep命令:以名称为依据从运行进程队列中查找进程,并显示查找到的进程id
选项
-o:仅显示找到的最小(起始)进程号;
-n:仅显示找到的最大(结束)进程号;
-l:显示进程名称;
-P:指定父进程号;pgrep -p 4764 查看父进程下的子进程id
-g:指定进程组;
-t:指定开启进程的终端;
-u:指定进程的有效用户ID。
需求3:判断网页服务(以nginx为例)是否正常
思路:
1.判断网页是否可以正常访问等方法
[root@shell ~]# vim webtest.sh
#!/bin/bash
curl http://10.1.1.13 &> /dev/null
[ $? -eq 0 ] && echo "该web服务正常" || echo "该web服务异常"
[root@shell ~]# systemctl start nginx
[root@shell ~]# source webtest.sh
该web服务正常
[root@shell ~]# systemctl stop nginx
[root@shell ~]# source webtest.sh
该web服务异常
二.循环语句
1.for循环
语法结构
- 列表循环
列表for循环:用于将一组命令执行已知的次数,下面给出了for循环语句的基本格式:
for variable in {list}
do
command
command
…
done
或者
for variable in a b c
do
command
command
done
例:
[root@shell ~]# for var in {1..10};do echo $var;done
1
2
3
4
5
6
7
8
9
10
[root@shell ~]# for var in {1..10..2};do echo $var;done
1
3
5
7
9
[root@shell ~]# for var in `seq 10 -2 5`;do echo $var;done
10
8
6
- 不带列表循环
不带列表的for循环执行时由用户指定参数和参数的个数,下面给出了不带列表的for循环的基本格式:
for variable
do
command
command
…
done
例:
[root@shell ~]# vim for.sh
#!/bin/bash
for var
do
echo $var
done
echo "脚本后面有$#个参数"
[root@shell ~]# source for.sh 1 2 3
1
2
3
脚本后面有3个参数
- 类c风格的for循环,下面给出了基本格式:
for(( expr1;expr2;expr3 ))
do
command
command
…
done
# expr1:定义变量并赋初值
# expr2:决定是否进行循环(条件)
# expr3:决定循环变量如何改变,决定循环什么时候退出
例:
[root@shell ~]# vim for2.sh
#!/bin/bash
for(( i=1;i<=5;i++))
do
echo $i
done
[root@shell ~]# source for2.sh
1
2
3
4
5
循环控制:
循环体: do…done之间的内容
- continue:继续;表示循环体内下面的代码不执行,重新开始下一次循环
- break:打断;马上停止执行本次循环,执行循环体后面的代码
- exit:表示直接跳出程序
#!/bin/bash
for i in {1..5}
do
test $i -eq 2 && break || touch /tmp/file$i
done
echo done
[root@shell ~]# source for3.sh
done
[root@shell ~]# ll /tmp/
total 0
-rw-r--r-- 1 root root 0 Sep 10 11:39 file1
drwx------ 2 root root 6 Sep 2 14:04 vmware-root_905-4013330159
drwx------ 2 root root 6 Sep 1 17:39 vmware-root_960-2999133023
小练习:
1.批量创建5个用户user1-user5,并设置密码为123
[root@shell ~]# vim user.sh
#!/bin/bash
for i in {1..5}
do
useradd user$i
echo 123|passwd --stdin user$i
done
[root@shell ~]# source user.sh
Changing password for user user1.
passwd: all authentication tokens updated successfully.
Changing password for user user2.
passwd: all authentication tokens updated successfully.
Changing password for user user3.
passwd: all authentication tokens updated successfully.
Changing password for user user4.
passwd: all authentication tokens updated successfully.
Changing password for user user5.
passwd: all authentication tokens updated successfully.
2.将局域网内能ping通的IP和不能ping通的IP分类,
[root@shell ~]# vim pingvc.sh
#!/bin/bash
ip=10.1.1.
# 定义变量
for i in {1..15}
# 循环去ping主机的ip
do
ping -c1 $ip$i &>/dev/null
if [ $? -eq 0 ];then
echo "$ip$i is ok" >> /tmp/ip_up.txt
else
echo "$ip$i is down" >> /tmp/ip_down.txt
fi
done
[root@shell ~]# source pingvc.sh
[root@shell ~]# cat /tmp/ip_up.txt
10.1.1.1 is ok
10.1.1.13 is ok
[root@shell ~]# cat /tmp/ip_down.txt
10.1.1.2 is down
10.1.1.3 is down
10.1.1.4 is down
10.1.1.5 is down
10.1.1.6 is down
10.1.1.7 is down
10.1.1.8 is down
10.1.1.9 is down
10.1.1.10 is down
10.1.1.11 is down
10.1.1.12 is down
10.1.1.14 is down
10.1.1.15 is down
总结
- FOR循环语法结构
- FOR循环可以结合条件判断和流程控制语句
- do …done 循环体
- 循环体里可以是命令集合,再加上条件判断以及流程控制
- 控制循环语句
- continue 继续,跳过本次循环,继续下一次循环
- break 打断,跳出循环,执行循环体外的代码
- exit 退出,直接退出程序
2.while循环
特点:条件为真就进入循环;条件为假就退出循环
语法结构
while 表达式
do
command...
done
while [ 1 -eq 1 ] 或者 (( 1 > 2 ))
do
command
command
...
done
例:
[root@shell ~]# vim while.sh
#!/bin/bash
i=1
while [ $i -le 5 ]
do
echo $i
let i++
done
[root@shell ~]# source while.sh
1
2
3
4
5
3.until循环
语法结构
特点:条件为假就进入循环;条件为真就退出循环
until expression [ 1 -eq 1 ] (( 1 >= 1 ))
do
command
command
...
done
i=1
例
[root@shell ~]# vim until.sh
#!/bin/bash
i=1
until [ $i -gt 5 ]
do
echo $i
let i++
done
[root@shell ~]# source until.sh
1
2
3
4
5