Shell学习 | 流程控制
内容纲要

Shell条件测试

数值比较[整数1 操作符 整数2]

[ 20 -gt 10 ]大于
[1 -lt 10] 小于
[1 -eq 1] 等于
[1 -ne 10 ] 不等于
[20 -ge 10] 大于等于
[10 -le 10]小于等于

注意:
1 操作付中操作数以及中括号之间必须有空格符合
2 可用$?来返回逻辑判断结果。1为false,0为true

文件测试[操作符 文件或目录]

[ -f /root/file1.txt ];echo $? 测试root目录下面是否存在file1.txt,存在则返回0.不存在返回1
[ -h /dev/cdrom ];echo $? 测试/dev/下面的cdrom是否是一个软连接

-f filename : 当filename 存在时返回真
-b filename : 当filename 存在并且是块文件时返回真(返回0)
-d pathname : 当pathname 存在并且是一个目录时返回真
-h filename : 当filename 存在并且是符号链接文件时返回真 (或 -L filename)
-c filename : 当filename 存在并且是字符文件时返回真
-e pathname : 当由pathname 指定的文件或目录存在时返回真
-g pathname : 当由pathname 指定的文件或目录存在并且设置了SGID 位时返回真
-k pathname : 当由pathname 指定的文件或目录存在并且设置了"粘滞"位时返回真
-p filename : 当filename 存在并且是命名管道时返回真
-r pathname : 当由pathname 指定的文件或目录存在并且可读时返回真
-s filename : 当filename 存在并且文件大小大于0 时返回真
-S filename : 当filename 存在并且是socket 时返回真
-w pathname : 当由pathname 指定的文件或目录存在并且可写时返回真
-x pathname : 当由pathname 指定的文件或目录存在并且可执行时返回真
-O pathname : 当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母O 大写)
-G pathname : 当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真

字符串比较

= 等于
!= 不等于
-z 判断字符长度是为0
-n 判断字符长度不是0

read -p "是否升级装备:" select ; [ "yes" = "$select" ] ; echo $? 测试字符串是否相等
[ -z "yes" ]; echo $? 测试yes长度是不是0。长度位。返回1,为假

and和or

[ 1 -lt 2 -a 5 -lt 10 ]; echo $? 前后条件同时成立才成立
[ 1 -lt 2 -o 5 -gt 10 ];echo $ 前后只需要一条件成立则成立

流程控制:if

  • 单分支结构

需求:由用户输入用户名,如果用户不存在,则创建该用户

#!/bin/bash
read -p "Input username: " name
id $name &> /dev/null
if [ $? -ne 0 ]; then
useradd $name
fi
  • 双分支机构

需求:编写脚本,由用户输入用户名,如果用户不存在,则创建该用户,并设置密码为123456;否则,提示用户已经存在

#!/bin/bash
read -p "Input username: " name
#id $name &> /dev/null
#if [ $? -ne 0 ] ;then
if id $name &> /dev/null;
then
        echo "$name already exist"
else
        useradd $name
        echo "123456" | passwd --stdin $name &> /dev/null
        echo "$name create finished,the password is 123456"
fi
  • 多分支结构

编写脚本,取出系统时间的小时,对数字进行判断
6--10 this is morning
11-13 this is noon
14-18 this is afternoon
其他 this is night

#!/bin/bash
hour=`date +%H`
if [ $hour -ge 6 -a $hour -le 10 ]
then
        echo "this is moring"
elif [ $hour -ge 11 -a $hour -le 13 ]
then
        echo "this is moon"
elif [ $hour -ge 14 -a $hour -le 18 ]
then
        echo "this is afternoon"

else
        echo "this is night"
fi
  • 嵌套结构

需求:

file

#!/bin/bash
read -p "请输入用户的姓名: " name
id $name &> /dev/null
if [ $? -eq 0 ];then
        echo "$name 存在"
else
        useradd $name
        echo "$name 已经创建成功"
        read -p "请输入用户密码:" pass

        if [ ${#pass} -ge 7 ];
        then
                echo "$pass" | passswd --stdin $name
                echo "$name 用户密码是 $pass"
        else
                echo "密码不合格"
        fi
fi
  • 调试脚本

sh -n 02.sh 仅调试脚本中的语法错误。
sh -vx 02.sh 以调试的方式执行,查询整个执行过程

匹配模式:case

  • 简单的模式匹配

需求:邀请用户输入待删除用户名。询问用户,确定要继续删除吗 yes/no: " y

#!/bin/bash
#name
#time
#1请输入删除的用户名:
read -p "please input a username : " user
#2请用户确认是否删除
read -p "确认删除吗?[yes/no] " action
#3 case 流控写法
case "$action" in
Y|y|YES|yes|Yes|YeS|YEs)
userdel -r $user
echo "$user is deleted!"
;;
*)
echo "thank you"
;;
esac
  • 简单的JumpServer

需求:由于工作中,我们需要管理N多台服务器。那么访问服务器就是一件繁琐
的事情。通过shell编程,编写跳板程序。当我们需要访问服务器时,看一
眼服务器列表名,按一下数字,就登录成功了。岂不美哉。
跳板主机,运行跳板脚本。弹出数十台服务器名的菜单
1)mysql1
2)mysql2
3)bj-web1
........
h) help
q) exit

#!/bin/bash
web1=192.168.152.133
web2=192.168.152.137
web3=192.168.152.138

cat <<EOF
目标服务器列表:
1.web1
2.web2
3.web3
4.web4
5.mysql1
6.mysql2
7.mysql3
8.docker1
q.quit
EOF

read -p "请输入服务器序号:" num

case $num in
1)
ssh root@$web1
;;
2)
ssh root@$web2
;;
3)
ssh root@$web3
;;
q)
echo "谢谢再见"
;;
esac
  • 系统管理工具箱

需求:
Command action
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序

#!/bin/bash
cat <<EOF
超超的工具箱
f.磁盘管理工具
d.系统挂载工具
m.内存管理工具
u.系统负载工具
q.退出
EOF

read -p "请输入工具序号【h进入帮助】:" action
case "$action" in
f)
fdisk -l
;;
d)
df -hT
;;
m)
free -m
;;
u)
uptime
;;
q)
exit
;;
h)
echo "该工具解释权归小超超所有."
;;
*)
echo "输入错误."
;;
esac
下一篇