赞
踩
第二章:判断
shell条件测试
无论什么编程语言都离不开条件判断(流控),shell也不例外。
例如:用户输入的密码不够长时提示用户,太短了。
例如:用户输入了备份的目录,如果目录存在,继续备份,如果没有目录创建目录。
shell条件测试:
1)数值比较
2)文件测试
3)字符串测试
4)and or
控制流程:if
1)单分支
2)双分支结构
3)多分支结构
4)嵌套结构(了解)
5)调试脚本
6)注意
模式匹配case
-gt 大于:[ 20 -gt 10 ]
-lt 小于:[ 10 -lt 20 ]
-eq等于:[ 10 -eq 10 ]
-ne不于:[ 1 -ne 10 ]
-ge大于等于:[ 20 -ge 10 ]
-le小于等于:[10 -le 10 ]
过渡:
变量长度:如何查看变量长度
[root@localhost ~]# pass=12345678
[root@localhost ~]# echo ${#pass} //查看变量长度
8
测试语法:
格式一:
test 条件表达:
在这里插[root@localhost ~]# pass=12345678
[root@localhost ~]# test ${#pass} -ge 7 //ge 表示大于等于
[root@localhost ~]# echo $? //长度为8大于7执行成功
0
[root@localhost ~]# pass=123
[root@localhost ~]# test ${#pass} -ge 7 //ge表示大于等于
[root@localhost ~]# echo $? //长度为3小于7执行失败
1入代码片
格式二:
[条件表达式]:
[root@localhost ~]# [ ${#pass} -ge 7 ]
[root@localhost ~]# echo $?
1
注意:中括号和字符之间要有空格
格式三:
[[条件表达式]]
[root@localhost ~]# [[ ${#pass} -ge 7 ]]
[root@localhost ~]# echo $?
1
注意:中括号和字符之间要有空格
if语法结构:
then 那么 完成指令1 …
else 否则 完成指令2…
fi 结束
脚本:
#!/bin/bash
read -p "please input your passwd:" passwd //请输入你的密码
if test ${#passwd} -lt 7 //如果输入的密码小于7位
then
echo "reset your passwd" //就输出重置密码
else
exit 0 //若密码大于7位,则退出,验证码为0
fi
测试:
root@localhost ~]# bash 1.sh
please input your passwd:123244
reset your passwd //当前密码小于7位,重新设置密码代码片
[root@localhost ~]# bash 1.sh
please input your passwd:12345678
[root@localhost ~]# echo $?
0 //当前密码长度大于7位,验证码为1
$? 为0 表示语句执行成功
$? 为1-255 表示语句执行失败
-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 时返回真
-t fd : 当fd 是与终端设备相关联的文件描述符时返回真
-w pathname : 当由pathname 指定的文件或目录存在并且可写时返回真
-x pathname : 当由pathname 指定的文件或目录存在并且可执行时返回真
-O pathname : 当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母O 大写)
-G pathname : 当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真
#!/bin/nash
read -p "please input your diectory:" diectory //请输入的你目录
if [ -d $diectory ];then //如果目录存在
echo "The diectory is exit!you can copy it"//输出目录已经存在,你可以备份
else
echo "please create a new diectory" //请新建一个新的目录
fi
测试:
[root@localhost ~]# bash 2.sh
please input your diectory:/tmp
The diectory is exit!you can copy it //tmp目录存在
[root@localhost~]# bash 2.sh
please input your diectory:/etc/passwd //etc下passwd目录不存在
please create a new diectory
=等于:需求:邀请用户确认,yes升级装备,no不升级装备
脚本:
#!/bin/bash
read -p "are you sure updating this equipment:[yes/no] " select
if [ "$select" = "yes" ];then//如果输入等于yes,就输出升级装备
echo "shenjizhuangbei"
else
echo "bushengjizhuangbei"
fi
测试:
[root@localhost ~]# bash select.sh
are you sure updating this equipment:[yes/no] yes
shenjizhuangbei
[root@localhost ~]# bash select.sh
are you sure updating this equipment:[yes/no] no
bushengjizhuangbei
常见错误:字符串未加引号。
!=不等于:注意谈好和等号之间没有空格
#!/bin/bash
read -p "are you sure updating this equipment:[yes/no] " select
if [ "$select" != "yes" ];then //如果输入不等于yes,就输出升级装备
echo "shenjizhuangbei"
else
echo "bushengjizhuangbei"
fi
测试:
[root@localhost ~]# vim select.sh
[root@localhost ~]# bash select.sh
are you sure updating this equipment:[yes/no] no
shenjizhuangbei
[root@localhost ~]# bash select.sh
are you sure updating this equipment:[yes/no] yes
bushengjizhuangbei
-z:判断字符长度是为0(了解)
[root@localhost ~]# BBB="" ;test -z $BBB;echo $? //BBB长度为0
0
[root@localhost ~]# BBB="234" ;test -z $BBB;echo $?//BBB长度不为0
1
-n:判断字符长度不是为0
[root@localhost ~]# BBB="234" ;test -n $BBB;echo $?///BBB长度不为0
0
当条件测试比较复杂时,需要多个条件同时成立,就需要混合条件测试了。
逻辑的(and)与(or)
&&:逻辑的AND的意思。 -a,两个条件同时成立为真。
||:逻辑的OR的意思。-o,两个条件一个成立,为真。
示例:猜测用户输入密码是否满足如下条件:
1.长度大于等于7位
2.包含字母大写
3.包含字母小写
4.包含符号“@L”
#!/bin/bash
read -p "please input your passwd:" pass
if [ ${#pass} -gt 7 ] &&[[ ${pass} =~ [a-z] ]] && [[ ${pass} =~ [A-Z] ]] && [[ ${pass} =~ @_! ]] ;then
echo "your passwd is safe"
else
echo "your passwd is too short,please change it"
fi
=~:模糊查询,包含于的意思
这里使用了正则表达式:
匹配括号内内容 :[ ]
匹配小写字母:[:lower:] [a-z]
匹配大写字母:[A-Z] [:upper:]
匹配字母(不分大小写):[:alpha:]
匹配字母数字字符:[:alnum:]
匹配数字:[:digit:] [0-9]
测试:
[root@localhost ~]# bash testpass.sh
please input your passwd:123456aA@_!
your passwd is safe
多种表达方式(了解):
在这里插[root@localhost ~]#[ 1-lt 2 -a 5 -gt 10] //1小于2并且5大于等于10
[root@localhost ~]# [ 1 -lt 2 -a 5 -gt 10 ]
[root@localhost ~]# echo $?
1
[root@localhost ~]#[ 1-lt 2 -o 5 -gt 101小于2或者5大于等于10
[root@localhost ~]# [ 1 -lt 2 -o 5 -gt 10 ]
[root@localhost ~]# echo $?
0入代码片
单分支结构:
if [ command/test ] ; then
符合该条件执行的语句
fi
需求:编写脚本,由用户输入用户名,如果用户不存在,则创建该用户
先了解一下$?变量
如果为真 echo $?为0
如果为假``echo$?为1
脚本:
#/bin/bash
read -p "please input your username :" name
id $name &> /dev/null
if [ $? -ne 0 ]; then //如果上一句执行不成功$?为0,则创建用户
useradd $name
echo "$name is created"
fi
测试:
[root@localhost ~]# bash userdaa.sh
please input your username :root //root用户已经存在不做任何的反应
[root@localhost ~]# bash userdaa.sh
please input your username :66889 //66889用户不存在,重新创建
66889 is created
双分支结构:
if 条件测试
then
命令序列
else
命令序列
fi
示例1:写脚本,由用户输入用户名,如果用户不存在,则创建该用户,否则提示已经存在,
脚本:
#/bin/bash
read -p "please input your username :" name
id $name &> /dev/null
if [ $? -ne 0 ]; then
useradd $name
echo "$name is created"
else
echo "user is already exist"
fi
测试:
[root@localhost ~]# bash userdaa.sh
please input your username :root
user is already exist
示例2:写脚本,由用户输入用户名,如果用户不存在,则创建该用户,否则提示已经存在,并且设置密码为123456
脚本:
#/bin/bash
read -p "please input your username :" name
if id $name &> /dev/null; then
echo "user is already exist"
else
useradd $name
echo "123456" | passwd--stdin $name &>/dev/null
echo "$name is created passwd is 123456"
fi
测试:
[root@localhost ~]# bash userdaa.sh
please input your username :root
user is already exist //用户已经存在
[root@localhost ~]# bash userdaa.sh
please input your username :98705
98705 is created passwd is 123456 //用户不存在,创建用户,并且设置密码为123456
多分支结构:
if 条件测试1 then 命令序列 elif 条件测试2 then 命令序列 elif 条件测试3 then 命令序列 ..... else 命令序列 fi
需求:编写脚本,取出系统时间的小时,对数字进行判断
6-10:this is moring
11-13:this is noon
14 -18:this is afternoon
其他:this is night
脚本:
#!/bin/bash
time=`date +%H`
if [ $time -ge 6 -a $time -le 10 ];then
echo " this is morning "
elif [ $time -ge 11 -a $time -le 13 ];then
echo " this is noon "
elif [ $time -ge 14 -a $time -le 18 ];then
echo "this is afternoon"
else
echo "this is night"
fi
~
测试:
[root@localhost ~]# bash time.sh
this is night
还可以将time.sh放入开机文件:
[root@localhost ~]# vim ~/.bash_profile
export /root/time.sh //在最后一行加入
在开机时就会显示
嵌套结构(了解):
if 条件测试1 then 命令序列
if 条件测试1 then 命令序列
else 命令序列
fi
else 命令序列
fi
示例:
read -p "Input username: " name id $name &> /dev/null if [ $? -eq 0 ];then? echo "$name 存在" else useradd $name echo "$name create finished" read -p "请输入用户密码: " pass if [ ${#pass} -ge 7 ];then echo "$pass" | passwd --stdin $name echo "$name 用户密码是 $pass" else echo "密码不合格" fi fi
调试脚本:
方法:#sh-n 02.sh仅调试脚本中的语法错误
#sh-vx 02.sh 以调试的方式执行,查询整个执行过程
测试:
第一种:
#!/bin/bash
time=`date +%H`
if [ $time -ge 6 -a $time -le 10 ];then
echo " this is morning "
elif [ $time -ge 11 -a $time -le 13 ];then
echo " this is noon "
elif [ $time -ge 14 -a $time -le 18 ];then
echo "this is afternoon"
else
echo "this is night"
#fi
把最后一行fi给注释掉,会出现语法错误
[root@localhost ~]# bash -n time.sh
time.sh: line 12: syntax error: unexpected end of file
第二种:
这些是调试信息:背后运行的过程
[root@localhost ~]# bash -vx time.sh #!/bin/bash time=`date +%H` date +%H ++ date +%H + time=19 if [ $time -ge 6 -a $time -le 10 ];then echo " this is morning " elif [ $time -ge 11 -a $time -le 13 ];then echo " this is noon " elif [ $time -ge 14 -a $time -le 18 ];then echo "this is afternoon" else echo "this is night" fi + '[' 19 -ge 6 -a 19 -le 10 ']' //目前时间是19:39,19是否大于6,小于10 + '[' 19 -ge 11 -a 19 -le 13 '']' //19是否大于11,小于13 + '[' 19 -ge 14 -a 19 -le 18 ']' //19是否大于14,小于18 + echo 'this is night' this is night
注意:1、[ ]表示条件测试。注意这里的空格很重要。要注意在’[‘后面和’]'前面都必须要有空格
2、在shell中,then和fi是分开的语句。如果要在同一行里面输入,则需要用分号将他们隔开。
3、注意if判断中对于变量的处理,需要加引号,以免一些不必要的错误。没有加双引号会在一些含空格等的字符串变量判断的时候产生错误。比如[ -n “$var” ]如果var为空会出错。
4、判断是不支持浮点值的。
5、如果只单独使用>或者<号,系统会认为是输出或者输入重定向,虽然结果显示正确,但是其实是错误的,因此要对这些符号进行转意。
6、默认,运行if语句中的命令,所产生的错误信息。仍然出现在脚本的输出结果中
7、使用-z或者-n来检查长度的时候,没有定义的变量也为0
8、空变量和没有初始化的变量可能会对shell脚本测试产生灾难性的影响,因此在不确定变量的内容的时候,在测试号前使用-n或者-z测试一下
9、$? 变量包含了之前执行命令的退出状态(最近完成的前台进程)(可以用于检测退出状态)
案例1:
邀请用户输入待删除用户名。
询问用户,确定要继续删除吗 yes/no: " y
if写法:
#!/bin/bash
read -p "please input a username:" user
read -p "Do you wang to delete it?[yes/no]:" option
if [ "$option" = "yes" ];then
userdel -r $user
else
echo "Thank you"
fi
测试:
[root@localhost ~]# bash user.sh
please input a username:lili
Do you wang to delete it?[yes/no]:yes
语法结构:
case 变量 in 模式1) 命令序列1 ;; 模式2) 命令序列2 ;; 模式3) 命令序列3 ;; *) 无匹配后命令序列 ;; esac
case写法:
#!/bin/bash
read -p "please input a username:" user
read -p "Do you wang to delete it?[yes/no]:" option
case "$option" in
yes)
userdel -r $user
echo "$user is delete"
;;
*)
echo "Thank you"
;;
esac
测试:
测试:
[root@localhost ~]# bash user.sh
please input a username:jack
Do you wang to delete it?[yes/no]:yes
jack is delete
案例2:
1、显示如下菜单:
cpu) show cpu info;
mem) show memory info;
quit) quit
Enter your option:
2、如果用户选择cpu,则显示文件/proc/cpuinfo的信息;
3、如果用户选择mem,则显示文件/proc/meminfo的信息;
4、如果用户选择quit,则退出,且退出码为5;
脚本:
#!/bin/bash cat <<EOF cpu) show cpu info; mem) show memory info; quit) quit EOF read -p "please inout your select:" select case "$select" in cpu) cat /proc/cpuinfo ;; mem) cat /proc/meminfo ;; *) exit 5 ;; esac
测试:输入CPU
[root@localhost ~]# bash server.sh cpu) show cpu info; mem) show memory info; quit) quit please inout your select:cpu processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 94 model name : Intel(R) Core(TM) i5-6300HQ CPU @ 2.30GHz stepping : 3 microcode : 0xcc cpu MHz : 2302.824 cache size : 6144 KB physical id : 0 siblings : 1 core id : 0 cpu cores : 1 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 22 wp : yes
测试:输入quit
[root@localhost ~]# bash server.sh
cpu) show cpu info;
mem) show memory info;
quit) quit
please inout your select:quit
[root@localhost ~]# echo $?
5
案例3:
linux提供的丰富的管理命令,用户管理,内存管理,磁盘管理,进程管理,日志管理,文件管理,软件管理,网络管理等等数十个工具包。
如果你能通过shell编程,把他们编写到一个程序里。想用某些功能,只需要按回车,就能完成。
Command action
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
Command (h for help): m
total used free shared buffers cached
Mem: 7628 840 6788 0 29 378
Swap: 2047 0 2047
-EOF:支持tab
#!/bin/bash #print list cat <<EOF please choose your tools: h.help information f.disk information d.file system m.memory information u.xitongfuzaiixinxi q.exit EOF read -p "your choose:" option case $option in h) echo "please input alpha entry the box" ;; f) fdisk -l ;; d) mount ;; m) free -m ;; u) uptime ;; q) echo"Thank you" exit ;; esac
测试:
输入h
root@localhost ~]# bash manager.sh
please choose your tools:
h.help information
f.disk information
d.file system
m.memory information
u.xitongfuzaiixinxi
q.exit
your choose:h
please input alpha entry the box
输入f
[root@localhost ~]# bash manager.sh please choose your tools: h.help information f.disk information d.file system m.memory information u.xitongfuzaiixinxi q.exit your choose:f Disk /dev/sda: 107.4 GB, 107374182400 bytes, 209715200 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk label type: dos Disk identifier: 0x000e2890 Device Boot Start End Blocks Id System /dev/sda1 * 2048 411647 204800 83 Linux /dev/sda2 411648 25593855 12591104 8e Linux LVM Disk /dev/mapper/centos-root: 10.7 GB, 10737418240 bytes, 20971520 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes
多加练习才能掌握,大家可以参考我写的案例,动手练一练。
最后:由于我的xshell不支持中文输入,所以有些指示写的我蹩脚的英文,请见谅。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。