Linux Shell编程及自动化运维实现 第2章 判断

目录

 

Shell 条件测试

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

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

===字符串比较 [ "字符串" = "字符串" ]

and 和 or 

流程控制:if

单分支结构

双分支结构

多分支结构

嵌套结构

实用脚本

一、case 语法结构

案例1:简单的模式匹配

案例2:简单的JumpServer

案例3:系统管理工具箱

阶段总结

 


Shell 条件测试

格式

格式1: test 条件表达式

格式2: [ 条件表达式 ]

格式3: [[ 条件表达式 ]]

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

操作符种类(了解)

-f filename : 当filename 存在时返回真
-b filename : 当filename 存在并且是块文件时返回真(返回0)
-d pathname : 当pathname 存在并且是一个目录时返回真
-h filename : 当filename 存在并且是符号链接文件时返回真 (或 -L filename)
-u pathname : 当由pathname 指定的文件或目录存在并且设置了SUID 位时返回真

-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 时返回真
-t fd       : 当fd 是与终端设备相关联的文件描述符时返回真
-w pathname : 当由pathname 指定的文件或目录存在并且可写时返回真
-x pathname : 当由pathname 指定的文件或目录存在并且可执行时返回真
-O pathname : 当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母O 大写)
-G pathname : 当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真
file1 -nt file2 : file1 比file2 新时返回真
file1 -ot file2 : file1 比file2 旧时返回真
“!”取反

示例1

-d:这是一个目录
[[email protected] ~]# test -d /home
[[email protected] ~]# echo $?
0                                                               //  返回值是0为真
[[email protected] ~]# test -d /home11111
[[email protected] ~]# echo $?
1                                                           //不为0为假
[[email protected] ~]# [ -d /home ]

注意中括号里的两个空格

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

操作符

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

示例

[[email protected] ~]# [ 1 -gt 10  ];echo $?

Linux Shell编程及自动化运维实现 第2章 判断

[[email protected] ~]# [ 1 -lt 10  ];echo $?

Linux Shell编程及自动化运维实现 第2章 判断

C语言风格(了解)需要加 (()) 

[[email protected] ~]# ((1<2));echo $?
0
[[email protected] ~]# ((1==2));echo $?
1
[[email protected] ~]# ((1>2));echo $?
1
[[email protected] ~]# ((1>=2));echo $?
1
[[email protected] ~]# ((1<=2));echo $?
0
[[email protected] ~]# ((1!=2));echo $?
0
[[email protected] ~]# ((`id -u`>0));echo $?
1
[[email protected] ~]# (($UID==0));echo $?
0
Linux Shell编程及自动化运维实现 第2章 判断

===字符串比较 [ "字符串" = "字符串" ]

=,==,等于

例:

猜测你的用户名是root

[[email protected] ~]# [ "$USER" = "root" ];echo $?
0
[[email protected] ~]# [ "$USER" == "root" ];echo $?
0
 

!=,不等于

猜测你的用户名不是root

[[email protected] ~]# [ "$USER" != "root" ];echo $?
1


-z:判断字符长度是为0(了解)
-n: 判断字符长度不是为0

定义三个变量,一个有值,一个,没值,一个没有定义。

[[email protected] ~]# var1=123
[[email protected] ~]# var2=
          /var3变量没有定义
-z:判断长度是0
[[email protected] ~]# [ -z "$var1" ];echo $?
1
[[email protected] ~]# [ -z "$var2" ];echo $?
0
[[email protected] ~]# [ -z "$var3" ];echo $?
0
-n:判断长度不是0
[[email protected] ~]# [ -n "$var1" ];echo $?
0
[[email protected] ~]# [ -n "$var2" ];echo $?
1
[[email protected] ~]# [ -n "$var3" ];echo $?
1   

或者

[[email protected] ~]# echo ${#var1}              
3                                                                  //变量位数长度
[[email protected] ~]# echo ${#var2}
0
[[email protected] ~]# echo ${#var3}
0

小结:变量为空 或 未定义: 长度都为0

 

and 和 or 

逻辑的(and)与(or)

&&   逻辑的 AND 的意思, -a 也是这个意思,两个条件同时成立,为真。

||  逻辑的 OR 的意思, -o 也是这个意思,两个条件一个成立,为真。

示例

猜测用户输入的成绩是否优秀(61~79)之间

[[email protected] ~]# num=59;[ $num -gt 60 -a $num -lt 80  ];echo $?
1
[[email protected] ~]# num=81;[ $num -gt 60 -a $num -lt 80  ];echo $?
1
[[email protected] ~]# num=60;[ $num -gt 60 -a $num -lt 80  ];echo $?
1
[[email protected] ~]# num=61;[ $num -gt 60 -a $num -lt 80  ];echo $?
0                                   

多种表达方法(了解)


[[email protected] ~]# [ 1 -lt 2 -a 5 -gt 10 ];echo $?    //     两个条件同时成立,为真。
1
[[email protected] ~]# [ 1 -lt 2 -o 5 -gt 10 ];echo $?     //两个条件一个成立,为真。
0
注意:&&调用正则时,请使用双中括号。
[[email protected] ~]# [[ 1 -lt 2 && 5 -gt 10 ]];echo $? 
1
[[email protected] ~]# [[ 1 -lt 2 || 5 -gt 10 ]];echo $? 
0

或者
[[email protected] ~]# [ 1 -lt 2 ] && [ 11 -gt 10 ];echo $? 
0

流程控制:if

 

单分支结构

语法:单分支结构
if 条件测试
then 命令序列
fi

示例

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

#!/bin/bash

read -p "请输入您要创建的用户名: " name

id $name &> /dev/null


if [ $? -ne 0 ]; then
        useradd $name
        echo "123456" | passwd --stdin $name &> /dev/null
        echo "$name 创建成功。密码是:123456"
fi


演示2:关于取反的一种用法

#!/bin/bash

read -p "请输入您要创建的用户名: " name

if   ! id $name &> /dev/null
 then
        useradd $name
        echo "123456" | passwd --stdin $name &> /dev/null
        echo "$name 创建成功。密码是:123456"
fi

Linux Shell编程及自动化运维实现 第2章 判断

双分支结构

语法:

if 条件测试
then 
命令序列
else 
命令序列
fi

示例1

需求:编写脚本,由用户输入用户名,
        如果用户存在,提示用户已经存在

        否则,则创建该用户,并设置密码为123456;

#!/bin/bash
 read -p "请输入您要创建的用户名:"  name
 id $name &> /dev/null
  if [ $? -eq 0   ]
then
      echo " 该用户已存在  "
else
read -p "请您设置密码: " pass
     useradd $name
     echo "$pass" | passwd --stdin $name &> /dev/null
    echo "$name创建成功,密码是:$pass  "
 fi

 

Linux Shell编程及自动化运维实现 第2章 判断

需求:编写脚本,由用户输入用户名,判断该用户的uid及gid,如果相同,则显示Good user; 
否则显示Bad user.

#!/bin/bash

read -p "请输入您的用户名: " name

user_id=`id -u $name`
group_id=`id -g $name`

if [ $user_id -eq $group_id ];then
        echo "Good user."
else
        echo "Bad user."
fi

Linux Shell编程及自动化运维实现 第2章 判断

多分支结构

语法:多分支结构
if 条件测试1
then 命令序列

elif 条件测试2
then 命令序列

elif 条件测试3 
then 命令序列...

else 命令序列
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 morning"
elif [ $hour -ge 11 -a $hour -le 13 ];then
    echo "This is noon"
elif [ $hour -ge 14 -a $hour -le 18 ];then
    echo "This is afternoon"
else
    echo "This is night"
fi

Linux Shell编程及自动化运维实现 第2章 判断

嵌套结构

语法

嵌套结构
if 条件测试1    then 命令序列
    if 条件测试1    then 命令序列

    else 命令序列
    fi
    
else 命令序列
fi
示例

Linux Shell编程及自动化运维实现 第2章 判断

#!/bin/bash
 read -p "请输入您要创建的用户名:"  name
 id $name &> /dev/null
  if [ $? -eq 0   ]
then
      echo " 该用户已存在  "
else
read -p "请您设置密码: " pass
     useradd $name
       if [ ${#pass} -ge 7];then
           echo "$pass" | passwd --stdin $name
           echo  echo "$name创建成功,密码是:$pass  "
        else
            echo " 密码长度不足   "   
       fi
fi

Linux Shell编程及自动化运维实现 第2章 判断

Linux Shell编程及自动化运维实现 第2章 判断

实用脚本

一、case 语法结构

case 变量 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
模式3)
命令序列3
;;
*)
无匹配后命令序列
esac

示例

编写脚本,由用户输入字符串,
字符串为linux则显示windows,
为windows则显示Linux否则显示Other 

#!/bin/bash
#

read -p "Input string: " str

case $str in
    windows)
        echo "Linux..."
        ;;
    linux)
        echo "Windows..."
        ;;
    *)
        echo "Other...."
        ;;
esac

Linux Shell编程及自动化运维实现 第2章 判断

案例1:简单的模式匹配

简单的模式匹配
邀请用户输入待删除用户名。
询问用户,确定要继续删除吗 yes/no: " y

#!/bin/bash
read -p "请输入您要删除的用户名 : " user

if [ $? -ne 0 ];then
        echo " $user 用户不存在,无法删除 "
        exit 1
fi
read -p "are you sure?[y/n]: " action

case $action in
Y|y|YES|yes|YEs|yeS|YeS|Yes)
#userdel -r $user
echo "$user 正在删除....."
sleep 3
echo " 删除成功,欢迎下次再来!  "
;;
*)
echo "用户删除取消成功,thank you!"
;;
esac

Linux Shell编程及自动化运维实现 第2章 判断

案例2:简单的JumpServer

跳板主机

1.web1
2.web2
3......
4.help
5.exit

请选择要连接的主机[1-3]: 1
1 定义跳转脚本

#!bin/bash
#1定义主机名
web1=10.8.162.24
web2=10.8.162.124
#跳转菜单不退出
  while :
    do
#打印跳转菜单
 cat <<EOF
1.web1
2.web2
3......
4.help
5.exit
EOF
#读取用户输入
read -p "input number:" num
#判断用户选择
case $num in
1)
ssh [email protected]$web1
;;
2)
ssh [email protected]$web2
;;
3)
echo  "........   "
;;
4)
echo "$help"
;;
5)
exit 1
;;
*)
echo "hahha"
esac
done

Linux Shell编程及自动化运维实现 第2章 判断

案例3:系统管理工具箱


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


定义脚本

#!/usr/bin/bash
while :
do
#打印菜单
cat <<-EOF
h. help
f. disk partation
d. filesystem mount
m. memory
u. system load
q.exit
EOF

# 读取用户输入,进行模式匹配

read -p "please input [h for help]: " action
case "$action" in

f)
        fdisk -l
        ;;
d)
        df -hT
        ;;
m)
        free -m
        ;;
u)
        uptime
        ;;
q)
        exit
        ;;
"")
        ;;
*)
        echo "error"
        ;;
esac
done

Linux Shell编程及自动化运维实现 第2章 判断

阶段总结

总结1:符号总结

() 子shell中执行:        (cd /home;ls)
(()) 比较数值,运算 C语言:    ((1<2));echo $?
$() 命令替换,或者反撇``:    touch file$(date)
$(()) 整数运算:            echo $((1+1))

{}集合:            touch file{1..3}
${}字符串的提取和替换。:    echo ${aaa-111}

[] 条件测试:            [ -f file1.txt ]; echo $?
[[]] 条件测试,支持正则 :    [[ 12 =~ [0-9]+$  ]] ;echo $?
$[] 整数运算:            echo $[1+1]

 

总结2:概念总结

执行脚本:
# ./01.sh <需要执行权限> 在子shell中执行
# bash 01.sh 不需要执行权限 在子shell中执行

# . 01.sh 不需要执行权限 在当前shell中执行
# source 01.sh 不需要执行权限 在当前shell中执行
提示:通常修改系统配置文件中如 /etc/profile 的PATH等变量后,使之在当前shell中生效

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