04 流程控制
set写jio本的用法
没啥屁用,不过有时候有用
set -o errexit
#等价于set -e , 有错误就退出。
set -o nounset
#在扩展一个没有的设置的变量的时候, 显示错误的信息
set -o pipefail
#set -e有一个例外情况,就是不适用于管道命令。所以就要pipefail(土话翻译是管道失败)所谓管道命令,就是多个子命令通过管道运算符(|)组合成为一个大的命令。Bash 会把最后一个子命令的返回值,作为整个命令的返回值。也就是说,只要最后一个子命令不失败,管道命令总是会执行成功,因此它后面命令依然会执行,set -e就失效了。
if判断
语法
if 条件1;then
代码1
代码2
代码3
elif 条件2;then
代码1
代码2
代码3
elif 条件3;then
代码1
代码2
代码3
.......
else
代码1
代码2
代码3
fi
案例
#!/bin/bash
read -p "请输入您的分数: " score
if [ $score -ge 90 ];then
echo "优秀"
elif [ $score -ge 80 ];then
echo "良好"
elif [ $score -ge 70 ];then
echo "一般"
else
echo "很差"
fi
#!/bin/bash
read -p "输入用户名:" inp_user
read -p "输入密码:" inp_pwd
if [ $inp_user = "egon" ] && [ $inp_pwd = "123" ];then
echo "登录成功"
else
echo "用户名或者密码错误"
fi
while循环
语法
while true
do
xxx
xxx
xxx
done
案例一
#!/bin/bash
while true
do
read -p "输入用户名:" inp_user
read -p "输入密码:" inp_pwd
if [ $inp_user = "egon" ] && [ $inp_pwd = "123" ];then
echo "登录成功"
break
else
echo "用户名或者密码错误"
fi
done
案例二
#动态监控
while true;do ifconfig eth0;sleep 0.5;clear; done
案例三
# 语法
while read line #line是一个变量给你用
do
echo $line>>./b.txt
done</etc/passwd #定义的要阅读的文件路径
# 案例
#!/bin/bash/expect
while read line
do
user=`echo $line | awk -F: '{print $1}'` #user
old_pwd=`echo $line | awk -F: '{print $2}'` #old password
new_pwd=`echo $line | awk -F: '{print $3}'` #new password
ip=`echo $line | awk -F: '{print $4}'` #ip
expect << EOF
spawn ssh $user@$ip passwd
expect {
"yes/no" {send "yes\r";exp_continue}
"*assword" {send "$old_pwd\n"}
}
expect {
"*assword" {send "$new_pwd\n";exp_continue}
"*assword" {send "$new_pwd\n"}
}
expect eof
EOF
done</tmp/passwd.txt
for循环
语法
for i in [条件]
do
xxx
xxx
xxx
done
seq
可以把seq理解为一个数数字的命令,相当于python中的range
[root@db01 ~]# seq 1 9
1
2
3
4
5
6
7
8
9
[root@db01 ~]# seq 9 -1 1
9
8
7
6
5
4
3
2
1
案例
方法一
#!/bin/bash
for i in {2..254}
do
ping -c1 1.1.1.$i &>/dev/null
if [ $? -eq 0 ];then
echo "1.1.1.$i ok"
else
echo "1.1.1.$i down"
fi
done
#相当于串行,自上而下的执行,效率很慢
方法二
#!/bin/bash
for i in {2..254}
do
(
ping -c1 1.1.1.$i &>/dev/null
if [ $? -eq 0 ];then
echo "1.1.1.$i ok"
else
echo "1.1.1.$i down"
fi
) &
done
#开了好多的子shell去执行,同时运行,效率高
case
语法
case 变量 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
模式3)
命令序列3
;;
*)
无匹配后命令序列
esac
案例
#!/bin/bash
#jumpserver
lb01=172.16.1.5
lb02=172.16.1.6
web01=172.16.1.7
web02=172.16.1.8
web03=172.16.1.9
nfs=172.16.1.31
backup=172.16.1.41
db01=172.16.1.51
m01=172.16.1.61
zabbix=172.16.1.71
menu(){
cat <<EOF
+-------------------------+
| 1) lb01 |
| 2) lb02 |
| 3) web01 |
| 4) web02 |
| 5) web03 |
| 6) nfs |
| 7) backup |
| 8) db01 |
| 9) m01 |
| 10) zabbix |
| c) clear |
+-------------------------+
EOF
}
#连接函数
connect(){
ping -c 1 -w 1 $1 &>/dev/null
if [ $? -eq 0 ];then
ssh jump@$1
else
echo -e "\033[1;35;40m 别连了,我的哥,$2:$1机都没开连你妈!!!\033[0m"
fi
}
#控制不让输入ctrl+c,z
trap "" HUP INT TSTP
while true
do
menu
read -p "请输入要连接的主机编号:" num
case $num in
1|lb01)
connect $lb01 lb01
;;
2|lb02)
connect $lb02 lb02
;;
3|web01)
connect $web01 web01
;;
4|web02)
connect $web02 web02
;;
5|web03)
connect $web03 web03
;;
6|nfs)
connect $nfs nfs
;;
7|backup)
connect $backup backup
;;
8|db01)
connect $db01 db01
;;
9|m01)
connect $m01 m01
;;
10|zabbix)
connect $zabbix zabbix
;;
c|clear)
clear
;;
爸爸)
break
;;
esac
done
select
select表达式是bash的一种扩展应用,擅长于交互式场合。用户可以从一组不同的值中进行选择
select var in ...
do
...
break
done
baim0手撸版
#!/bin/bash
web01="172.16.1.7"
web02="172.16.1.8"
web03="172.16.1.9"
backup="172.16.1.41"
nfs="172.16.1.31"
lb01="172.16.1.5"
lb02="172.16.1.6"
db01="172.16.1.51"
connect(){
ping -c1 $1 > /dev/null
if [ $? -eq 0 ]; then
ssh root@$1
else
echo "老子没开机呢,滚!"
fi
}
#trap INT QUIT TSTP ""
while [ true ]; do
PS3="请输入连接主机的!!!编号!!!>>"
select item in {"web01","web02","web03","backup","nfs","lb01","lb02","db01"}; do
case ${item} in
"web01")
connect $web01
;;
"web02")
connect $web02
;;
"web03")
connect $web03
;;
"backup")
connect $backup
;;
"nfs")
connect $nfs
;;
"lb01")
connect $lb01
;;
"lb02")
connect $lb02
;;
"db01")
connect $db01
;;
*)
echo "别乱输,小垃圾!"
esac
done
done