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; } 花括号就是退出整个脚本
本文来自博客园,作者:厚礼蝎,转载请注明原文链接:https://www.cnblogs.com/guangdelw/p/17147865.html