bash中如何实现条件断?
条件测试类型:
整数测试
字符测试
文件测试
条件测试的表达式
[ expression ],命令测试法
[[ expression ]],关键字测试法
test expression,test命令测试法
如何进行测试:
整数测试
-eq:测试两个整数是否相等,相等为真,不等为假,如[ $a -eq $b ] ,如果相等,则执行状态返回值一定为0,否则为1-255之间的任何一个值.
-ne:测试两个整数是否不相等,相等为假,不等为真
-gt:测试一个数是否大于另一个数,大于为真,否则为假
-lt:测试一个数是否小于另一个数,小于为真,否则为假
-ge:测试一个数是否大于等于另一个数,大于等于为真,否则为假
-le:测试一个数是否小于等于另一个数,小于等于为真,否则为假
命令之间逻辑关系测试
逻辑与:如果其中一个为假,则结果一定为假,短路测试,第一个条件为假时,不执行第二个条件;第一个条件为真时,第二个条件必须执行
如:查询用户存在并显示信息
[root@station01 ~]# id user9 &>/dev/null && echo "user9 exist."
user9 exist.
如:查询用户不存在就添加
! id user9 && useradd user9
id user9 || useradd user9
如:判断一个文件的行数,如果大于100,则显示为大文件件
1)方法一
[user9@station01 ~]$ [ `wc -l /etc/inittab |cut -d' ' -f1 ` -gt 100 ] && echo "/etc/inittab is a large file." || echo "A small file."
A small file.
2)方法二
文件test2.sh内容如下:
[root@station01 ~]# cat test2.sh #!/bin/bash # Linenum=`wc -l /etc/inittab | cut -d ' ' -f1 ` #echo $Linenum [ $Linenum -gt 100 ] && echo "/etc/inittab is a large file." || echo "/etc/inittab is a small file."
逻辑或:如果其中一个为真,则结果一定为真,短路测试
引用一个命令的执行结果,需要用命令替换
变量命名规则:变量只能包含字母、数字和下划线,不能以数字开头;并且不可以与系统中已有的环境变量名称相同;见名知义
如查用户已存在,显示此用户存在,否则添加此用户
id user9 && echo "user9 exist." || useradd user9
如查用户不存在,添加用户,否则显示用户已存在
! id user9 && useradd user9 || echo "user9 exsit."
如果用户不存在,添加并设置密码,否则显示已存在
!id user9 && useradd user9 && echo "user9" | passwd --stdin user9 || echo "user9 exist"
如果用户不存在,添加用户并设置与用户名相同的密码,如已存在显示用户已存;最后显示系统中总共有多少个用户
test3.sh文件内容如下:
[root@station01 ~]# cat test3.sh #!/bin/bash # ! id user1 &>/dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &>/dev/null || echo "user1 is exist." ! id user2 &>/dev/null && useradd user2 && echo "user2" | passwd --stdin user2 &>/dev/null || echo "user2 is exist." USERS=`wc -l /etc/passwd | cut -d' ' -f1` echo "$USERS users."
执行结果如下:
[root@station01 ~]# ./test3.sh
user1 is exist.
user2 is exist.
41 users.
给定一用户,如果id为0,则显示为管理员,否则为普通用户
test4.sh文件内容如下:
[root@station01 ~]# cat test4.sh #!/bin/bash # NAME=user1 [ `id -u $NAME` -eq 0 ] && echo "$NAME is administrator." || echo "$NAME is a common user."
条件判断的控制结构
单分支的if语句:
if 判断条件;then
语句1
语句2
....
fi
如判断给定用户是否存在,如果存在则显示已存在
[root@station01 ~]# cat test5.sh #!/bin/bash # NAME=user1 if id $NAME &>/dev/null;then echo "$NAME is esist." fi
双分支的if语句:
if 判断条件;then
语句1
语句2
...
else
语句1
语句2
...
fi
如判断给定用户是否存在,如果存在则显示已存在,否则显示不存在
[root@station01 ~]# cat test5.sh
#!/bin/bash # NAME=user1 if id $NAME &>/dev/null;then echo "$NAME is esist." else echo "$NAME is not exist." fi
如判断给定用户是否存在,如果存在则显示已存在,否则显示不存在,添加用户并设置与用户名相同的密码,并显示添加成功
[root@station01 ~]# ./test5.sh user12 is esist. [root@station01 ~]# cat test5.sh #!/bin/bash # NAME=user12 if id $NAME &>/dev/null;then echo "$NAME is esist." else useradd $NAME echo $NAME |passwd --stdin $NAME &>/dev/null echo "Add $NAME is successfully." fi
多分支的if语句
if 判断语句;then
语句1
语句2
...
elif判断语句2;then
语句1
语句2
...
elif判断语句3;then
语句1
...
...
else
语句1
...
fi
测试脚本是否有语法错误
bash -n 脚本名
bash -x 脚本名,单步执行
条件判断分为执行状态和执行结果判断
引用一个命令的执行结果,要使用命令引用;引用一个命令的执行状态结果,一定不能用引用
如判断当前系统上是否有用户的默认shell为bash,如有则显示有多少此类用户,否则显示没有。
[root@station01 ~]# cat test6.sh #!/bin/bash # grep "\/dev/null RETVAL=$? if [ $RETVAL -eq 0 ];then USERS=`grep "\ 如判断当前系统上是否有用户的默认shell为bash,如有则显示其中一个用户名,否则显示没有。
[root@station01 ~]# cat test7.sh #!/bin/bash # grep "\/dev/null RETVAL=$? if [ $RETVAL -eq 0 ];then USERS=`grep "\ 如:给定一个文件,判断是否有空白行,如有则显示有多少行,否则显示没有空白行
[root@station01 ~]# cat test8.sh #!/bin/bash # FILES=/etc/inittab grep "^$" $FILES &>/dev/null RETVAL=$? if [ $RETVAL -eq 0 ];then LINES=`grep "^$" $FILES |wc -l` echo "The total of $LINES line is blank." else echo "No such blank line." fi如:给定一用户,判定其UID是否等于GID,如一样,则显示SAME,否则显示NOT THE SAME
1)方法一
[root@station01 ~]# cat test9.sh #!/bin/bash # USERNAME=user1 if [ `id -u $USERNAME` -eq `id -g $USERNAME` ];then echo "The ${USERNAME}'s UID equal GID." else echo "Not the same" fi2)方法二
[root@station01 ~]# cat test10.sh #!/bin/bash # USERNAME=user6 if [ `grep "^\<$USERNAME\>" /etc/passwd | cut -d: -f3` -eq `grep "^\<$USERNAME\>" /etc/passwd | cut -d: -f4` ];then echo "The ${USERNAME}'s UID equal GID." else echo "Not the same" fiSHELL中如何进行算术运算
1、定义变量时为字符型,运算时用let命令;
let 算术运算表达式,let CC=$AA+$BB
如:
[root@station01 ~]# AA=1 [root@station01 ~]# BB=2 [root@station01 ~]# let CC=$AA+$BB [root@station01 ~]# echo $CC 32、$[算术运算表达式]
CC=$[$AA+$BB]3、$((算术运算表达式))
CC=$(($AA+$BB))4、expr 算术运算表达式,表达式中各操作数及运算符之间有空格,而且要使用命令引用
CC=`expr $AA + $BB`退出当前进程命令
exit:退出脚本,用于定义执行状态结果的命令。用法:exit 0-255之间的任一数值,如脚本未定义脚本退出码,则最后一条命令执行的即为脚本的退出码。
如判断用户是否存在,如已存在则提前退出脚本,否则执行
[root@station01 ~]# cat test5.sh #!/bin/bash # NAME=user12 if ! grep "^$NAME/>" /etc/passwd &>/dev/null;then echo "$NAME is exsit" exit 23 fi if id $NAME &>/dev/null;then echo "$NAME is esist." else useradd $NAME echo $NAME |passwd --stdin $NAME &>/dev/null echo "Add $NAME is successfully." fi执行结果:
[root@station01 ~]# ./test5.sh user12 is exsit [root@station01 ~]# echo $? 23
例:给定一用户,获取其密码使用期限和密码剩余期限,判断用户密码剩余期限是否小于警告期限,如小于则提示“Warning”,否则“OK”
密码使用期限=当前时间-密码修改时间
密码剩余期限=密码最长使用期限-密码使用期限
/etc/shadow文件说明:
Linux /etc/shadow文件中的记录行与/etc/passwd中的一一对应,它由pwconv命令根据/etc/passwd中的数据自动产生。它的文件格式与/etc/passwd类似,由若干个字段组成,字段之间用“:”隔开。这些字段是:
登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志
1)“登录名”是与/etc/passwd文件中的登录名相一致的用户账号
2)“口令”字段存放的是加密后的用户口令字,长度为13个字符。如果为空,则对应用户没有口令,登录时不需要口令;如果含有不属于集合{./0-9A-Za-z}中的字符,则对应的用户不能登录。
3)“最后一次修改时间”表示的是从某个时刻起,到用户最后一次修改口令时的天数。时间起点对不同的系统可能不一样。例如在SCOLinux中,这个时间起点是1970年1月1日。
4)“最小时间间隔”指的是两次修改口令之间所需的最小天数。
5)“最大时间间隔”指的是口令保持有效的最大天数。
6)“警告时间”字段表示的是从系统开始警告用户到用户密码正式失效之间的天数。
7)“不活动时间”表示的是用户没有登录活动但账号仍能保持有效的最大天数。
8)“失效时间”字段给出的是一个绝对的天数,如果使用了这个字段,那么就给出相应账号的生存期。期满后,该账号就不再是一个合法的账号,也就不能再用来登录了。
[root@station01 ~]# cat test12.sh #!/bin/bash # USERNAME="root" WARNING=`grep "$USERNAME\>" /etc/shadow- | cut -d: -f6` CHANGETIME=`grep "$USERNAME\>" /etc/shadow- | cut -d: -f3` LANGDAY=`grep "$USERNAME\>" /etc/shadow- | cut -d: -f5` CURSECOND=`date +%s` #one:第一种算术运算 let CURDAY=$CURSECOND/86400 #two: 第二种算术运算 PASSDAY=`expr $CURDAY - $CHANGETIME` #three:第三种运算 LASTDAY=$[$LANGDAY-$PASSDAY] #four:第四种运算 #LASTDAY=$(($LANGDAY-$PASSDAY)) if [ $LASTDAY -lt $WARNING ];then echo "Waring,....." else echo "OK,......." fi #echo $WARNING #echo $CHANGETIME #echo $CURSECOND #echo $CURDAY #echo $PASSDAY #echo $LASTDAY文件测试
属于单目运算
-e FILE:文件名或文件路径,测试文件是否存在
-f FILE:文件名或文件路径,测试文件是否为普通文件
-d FILE:文件名或文件路径,测试指定路径是否为目录
-r FILE:测试指定文件对当前用户是否有读权限
-w FILE:测试指定文件对当前用户是否有写权限
-x FILE:测试指定文件对当前用户是否有执行权限
如测试文件是否存在
[ -e /etc/inittab ]
测试文件是否有执行权限
[ -x /etc/rc.d/rc.sysinit ]
如测试文件是否存在,并是否有空白行
[root@station01 ~]# cat test8.sh #!/bin/bash # FILES=/etc/inittabaa if [ ! -e $FILES ];then echo "No such file." exit 20 fi grep "^$" $FILES &>/dev/null RETVAL=$? if [ $RETVAL -eq 0 ];then LINES=`grep "^$" $FILES |wc -l` echo "The total of $LINES line is blank." else echo "No such blank line." fi执行结果
[root@station01 ~]# ./test8.sh No such file. [root@station01 ~]# echo $? 20给定一个文件,如是一个普通文件,就显示普通文件,如是一个目录,就显示为目录,否则无法识别,判断文件是否存在,不存在则退出。
[root@station01 ~]# ./test13.sh Common file... [root@station01 ~]# cat test13.sh #!/bin/bash # FILES=/etc/rc.d/rc.sysinit #单分支if语句,判断文件是否存在 if [ ! -e $FILES ];then echo "No such file..." exit 24 fi #多分支的if语句 if [ -f $FILES ];then echo "Common file..." elif [ -d $FILES ];then echo "Directory .." else echo "Unknown." fiGB-2312