shell中的各种测试语句

变量测试

表达式 解释
${var:-word} | 若var存在且非空,则值为$var;若var未定义或为空值,则值为word,但var的值不变
${var:=word} | 若var存在且非空,则值为$var;若var未定义或为空值,则值为word,且var被赋值word
${var:?word} | 若var存在且非空,则值为$var;若var未定义或为空值,则输出信息word,并终止脚本
${var:+word} 若var存在且非空,则值为word;否则返回空值,但var的值不变

例子:

#赋值变量
$ abc=11111
$ echo ${abc}
11111
#变量有值输出值
$ echo ${abc:-222}
11111
$ unset abc
#没值输出后面的值
$ echo ${abc:-222}
222
#原变量依然没有值
echo ${abc}


#赋值
$ abc=11111
$ echo ${abc:=222}
11111
#取消变量
$ unset abc
$ echo ${abc:=222}
222
#原值已经改变
$ echo ${abc}
222

#赋值
$ abc=11111
#有值输出值
$ echo ${abc:?"变量未定义!"}
11111
$ unset abc
#没值则将后面的信息显示在错误提示中
$ echo ${abc:?"变量未定义!"}
-bash: abc: 变量未定义!
#原变量不会改变
$ echo ${abc}


abc=11111
#有值则会输出后面的值
$ echo ${abc:+222}
222
$ unset abc
#无值则什么都不会输出
$ echo ${abc:+222}

#原值不会改变
$ echo ${abc}

${!varprefix*}${!varprefix@}都是匹配之前所有以varprefix开头进行声明的变量,将变量名显示出来

$ echo ${!P@}
PATH PIPESTATUS PPID PS1 PS2 PS4 PWD

条件测试

判断某需求是否满足,需要由测试机制来实现
专用的测试表达式需要由测试命令辅助完成测试过程

评估布尔声明,以便用在条件性执行中
若真,则返回0
若假,则返回1

测试命令:
格式1:test EXPRESSION
格式2:[ EXPRESSION ]
格式3:[[ EXPRESSION ]]
注意:EXPRESSION前后必须有空白字符

说明:

  • 格式1 和 格式2 是等价的,格式3是扩展的 test 命令
  • [[ ]] 中可以使用通配符进行模式匹配
  • &&, ||, <, 和>能够正常存在于[[ ]]中,但不能在 [] 中出现
  • [[[之后的字符必须为空格]]]之前的字符必须为空格
  • 要对整数进行关系运算也可以使用 (()) 进行测试

字符串测试

比较字符串:
= 是否等于
> ascii码是否大于ascii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
-z "STRING" 字符串是否为空,空为真,不空为假 测试是否为空
-n "STRING" 字符串是否不空,不空为真,空为假 测试是否为非空

"STRING" 与加-n同样效果

#通过正则表达式判断变量是否为数字
n=213;[[ "$n" =~ ^[0-9]+$  ]] && echo '是个数字'
是个数字
#判断文件是否为shell脚本
n=ada.sh;[[ "$n" =~ \.sh$ ]]&& echo '是shell脚本'||echo '不是shell脚本'
是shell脚本

n=adash;[[ "$n" =~ \.sh$ ]]&& echo '是shell脚本'||echo '不是shell脚本'
不是shell脚本
[ -z "1"  ]&& echo '为空'|| echo '非空'
非空

[ -n "1"  ]&& echo '为空'|| echo '非空'
为空

[ "1"  ]&& echo '为空'|| echo '非空'
为空

检查空值

[ "$name" = "" ]
[ -z "$name" ]
[ ! "$name" ]
[ "X${name}" = "X" ]

检查非空值

[ "$name" != "" ]
[ -n "$name" ]
[ "$name" ]
[ "X${name}" != "X" ]

例子

#判断某个文件是否为空
$ [ -z `cat 1` ] && echo '为空' || echo "非空"
非空

数字测试

比较数字:
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于

命令 解释
[[ int1 -eq int2 ]] int1 等于 int2 返回真
[[ int1 -ne int2 ]] int1 不等于 int2 返回真
[[ int1 -gt int2 ]] int1 大于 int2 返回真
[[ int1 -ge int2 ]] int1 大于或等于 int2 返回真
[[ int1 -lt int2 ]] int1 小于 int2 返回真
[[ int1 -le int2 ]] int1 小于或等于 int2 返回真

整数测试也可以使用 let 命令或(())

双小括号就可以直接使用数学运算符号来比较

相应的操作符为:

==!=>>=<<=

命令 解释
((int1 == int2)) int1 等于 int2 返回真
((int1 != int2)) int1 不等于 int2 返回真
((int1 > int2)) int1 大于 int2 返回真
((int1 >= int2)) int1 大于或等于 int2 返回真
((int1 < int2)) int1 小于 int2 返回真
((int1 <= int2)) int1 小于或等于 int2 返回真

例子

#可以使用算数表达式
$ x=1; let "$x == 1"; echo $?
$ x=1; (($x+1>= 2 )); echo $? 

两种测试方法的区别

使用的操作符不同

  • let 和 双圆括号中可以使用算术表达式,而中括号不能
  • let 和 双圆括号中,操作符两边可以不留空格

利用条件测试判断硬盘使用率

$ vim lsdf.sh
#阈值设置为15%
v=15
#取出硬盘使用率
s=`df -h |grep ^/dev/sd|tr -s ' ' %|cut -d% -f5`
#与阈值作比较,如果超过了,就闪烁红色显示硬盘已经超过阈值,如果没超过,就绿色显示没超过
[ $s -ge $v ] && echo -e "\033[1;5;31m硬盘使用已超过${v}%!!\033[0m"|| echo -e '\033[1;32m硬盘使用并未超过阈值!请放心使用\033[0m'

#判断ip是否合法
ip='123.4.5.6';[[ "$ip" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))$ ]] && echo 'ip合法'|| echo 'ip不合法'
ip合法

ip='1223.4.5.6';[[ "$ip" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))$ ]] && echo 'ip合 法'|| echo 'ip不合法'
ip不合法

Bash的文件测试

测试文件时,文件名需要添加双引号

存在性测试

-a FILE:同 -e
-e FILE: 文件或目录存在性测试,存在为真,否则为假

存在性及类别测试

-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE是否存在且为目录文件
-f FILE是否存在且为普通文件
-h FILE-L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件

Bash的文件权限测试

文件权限测试

-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行

文件特殊权限测试

-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限

文件大小测试

-s FILE: 检测文件是否为空(文件大小是否大于0),不为空返回true

文件是否打开

-t fd: fd 文件描述符是否在某终端已经打开
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组

双目测试

FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2

Bash的组合测试(逻辑测试)条件

第一种方式

EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION

必须使用测试命令进行,只支持单[],不支持[[ ]] ,不要随便加()

$ [ 1 -lt  2 -a 3 -eq 2 ]

第二种方式

COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN
COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR ELSE
! COMMAND
如:[ -f "$FILE" ] && [[ "$FILE"=~ .*\.sh$ ]]

作为通用的,可以用模式匹配的方法来逻辑判断,这种只能用[[]]

命令 解释
[[ pattern1 && pattern2 ]] 逻辑与
`[[ pattern1
[[ ! pattern ]] 逻辑非

如果仅整型的话,可以使用(())

命令 解释
(( expr1 && expr2 )) 逻辑与
`(( expr1
(( ! expr )) 逻辑非

shell脚本添加用户

功能,需要携带用户名和密码两个参数,用户已存在需要提示,不存在就创建用户

vim /data/useradd.sh
#!/bin/bash
[ -z "$1" -o -z "$2"  ] && ( echo -e "\033[1;31m缺少用户名或密码\033[0m") ||  ( id -u $1 &> /dev/null  && echo -e "\033[1;31m$1 用户已存在!\033[0m" || (useradd $1;echo $2 | passwd --stdin $1 &>/dev/null;echo -e "\033[1;32m$1用户创建成功!\033[0m" ))

#改进版   只用输入用户名,自动生成临时密码,并在登陆时强制需要重置密码
#生成八位随机密码
passwd=`cat /dev/urandom | tr -dc [:alnum:]|head -c 8`
#检测名字是否存在,不存在就新建用户,并设置用户的密码有效时间为0
[ -z "$1"  ] && ( echo -e "\033[1;31m缺少用户名\n请输入形如:`basename $0` YOURNAME\033[0m") ||  ( id -u $1 &> /dev/null  && echo -e "\033[1;31m$1 用户已存在!\033[0m" || (useradd $1;echo $passwd | passwd --stdin $1 &>/dev/null;chage -d0 $1;echo -e "\033[1;32m$1用户创建成功!\n你的临时密码:$passwd\n登录是请重设密码!\033[0m" ))

#也可以借助exit 退出,passwd=`cat /dev/urandom | tr -dc [:alnum:]|head -c 8`
[ -z "$1"  ] && echo -e "\033[1;31m缺少用户名\n请输入形如:`basename $0` YOURNAME\033[0m" && exit 2                                                                                  
 id -u $1 &> /dev/null  && echo -e "\033[1;31m$1 用户已存在!\033[0m" && exit 3
 useradd $1
 echo $passwd | passwd --stdin $1 &>/dev/null
 chage -d0 $1
 echo -e "\033[1;32m$1用户创建成功!\n你的临时密码:$passwd\n登录是请重设密码!\033[0m"
 
 #对脚本的强壮性进行加强
passwd=`cat /dev/urandom | tr -dc [:alnum:]|head -c 8`
[ -z "$1"  ] && echo -e "\033[1;31m缺少用户名\n请输入形如:`basename $0` YOURNAME\033[0m" && exit
 id -u $1 &> /dev/null  && echo -e "\033[1;31m$1 用户已存在!\033[0m" && exit
 useradd $1 &> /dev/null || { echo -e "\033[1;31m创建$1用户失败,用户名不合法!\033[0m";exit; }                                                                           
 echo $passwd | passwd --stdin $1 &>/dev/null || { echo -e "\033[1;31m用户$1的密码设置出错!\033[0m";exit; }
 chage -d0 $1
 echo -e "\033[1;32m$1用户创建成功!\n你的临时密码:$passwd\n登录是请重设密码!\033[0m"

( exit ) 小括号只能退出子进程,并不会退出脚本

{ exit; } 花括号就是退出整个脚本

posted @ 2023-02-23 14:28  厚礼蝎  阅读(31)  评论(0编辑  收藏  举报