您的位置:首页 > 运维架构 > Shell

谢烟客---------Linux之Bash基础特性条件测试&&自定义退出状态码(6)

2017-08-02 19:59 447 查看
条件测试

判断某需求是否满足,需要由测试机制来实现。
根据命令的执行状态结果,表达不同的测试条件

1、根据id命令的执行状态结果,判断用户是否存在
[root@izpo45bh60h6bsz ~]# id root
uid=0(root) gid=0(root) groups=0(root)
[root@izpo45bh60h6bsz ~]# echo $?
0

[root@izpo45bh60h6bsz ~]# id help
id: help: no such user
[root@izpo45bh60h6bsz ~]# echo $?
1


2、根据在/etc/passwd文件中找到root开头的词的执行状态结果,判断用户是否存在
[root@izpo45bh60h6bsz ~]# grep -q '^root\b' /etc/passwd
[root@izpo45bh60h6bsz ~]# echo $?
0
[root@izpo45bh60h6bsz ~]# grep -q '^help\b' /etc/passwd
[root@izpo45bh60h6bsz ~]# echo $?
1


使用测试,在测试时,要使用特殊的测试符
1)test 测试表达式
[root@izpo45bh60h6bsz ~]# test 1 > 3
[root@izpo45bh60h6bsz ~]# echo $?
0
[root@izpo45bh60h6bsz ~]# test 1 -gt 3 # 在数值测试时,用-gt表示 > 符号
[root@izpo45bh60h6bsz ~]# echo $?
1
2)[ 测试表达式 ]

[root@izpo45bh60h6bsz ~]# [1 -lt 3]   # 测试表达示与中括号必须存在空格,否则就会报错。
-bash: [1: command not found

[root@izpo45bh60h6bsz ~]# [ 1 -lt 3 ]  # 在数值测试时,用-lt表示 < 符号
[root@izpo45bh60h6bsz ~]# echo $?
0
3) [[ 测试表达式 ]]
[root@izpo45bh60h6bsz ~]# [[1 -lt 3]]
-bash: [[1: command not found

[root@izpo45bh60h6bsz ~]# [[ 1 -eq 3 ]]  # 在数值测试时,用-eq 表示 = 符号
[root@izpo45bh60h6bsz ~]# echo $?
1


测试符分类
数值测试

-eq 左侧是否等于右侧
-ne 是不等于
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于

1)A -eq B, 测试A所表示的数值是否等于B所表示的数值。等于为真
##测试方法一
# A=1
# B=10
# test $B -eq $A  # 测试变量B内存空间中存储的数据和变量A内存空间中存储的数据是否相等
# echo $?
1

##测试方法二
# [ $B -eq $A ]
# echo $?
1

##测试方法三
# [[ $B -eq $A ]]
# echo $?
1
2)A -ne B, 测试A所表示的数值是否不等于B所表示的数值。不等于为真
##测试方法一
# test $B -ne $A  # 测试变量B内存空间中存储的数据和变量A内存空间中存储的数据是否不相等
# echo $?
0

##测试方法二
# [ $B -ne $A ]
# echo $?
0

##测试方法三
# [[ $B -ne $A ]]
# echo $?
0
3) A -gt B , 测试A所表示的数值是否大于B所表示的数值。大于为真
##测试方法一
# test 10 -gt 3 # 测试10是否大于3
# echo $?
0

##测试方法二
# [ 10 -gt 3 ]
# echo $?
0

##测试方法三
# [[ 10 -gt 3 ]]
# echo $?
0
3) A -ge B , 测试A所表示的数值是否大于等于B所表示的数值。大于等于为真
##测试方法一
# test 10 -ge 3 # 测试10是否大于等于3
# echo $?
0

##测试方法二
# [ 10 -ge 3 ]
# echo $?
0

##测试方法三
# [[ 10 -ge 3 ]]
# echo $?
0
4)A -lt B , 测试A所表示的数值是否小于B所表示的数值。小于为真
##测试方法一
# let 1 -lt 3    # 测试 1 是否小于 3
# echo $?
0

##测试方法二
# [ 1 -lt 3 ]
# echo $?
0

##测试方法三
# [[ 1 -lt 3 ]]
# echo $?
0
5)A -le B , 测试A所表示的数值是否小于等于B所表示的数值。小于等于为真
##测试方法一
# let 1 -le 3    # 测试 1 是否小于 3
# echo $?
0

##测试方法二
# [ 1 -le 3 ]
# echo $?
0

##测试方法三
# [[ 1 -le 3 ]]
# echo $?
0

字符测试 (所有的操作数,都应该使用引用)

== 等值测试
> 是否大于, ASCII码的比较
< 是否小于
!= 是否不等于
A =~ PATTERN 左侧字符串是否能够被右侧的(正则表达式)PATTERN所匹配到。一般用于 ` ` 中,PATTERN不能加引号
-z "STRING" 测试字串是否为空,空为真
-n "STRING" 是否不空
1) A == B ,A所表示的字符和B所表示的字符是否相等

##测试方法一
# test "obama" == "obama"  # 测试左侧字符串,是否与右侧字符串相等
# echo $?
0

# test "obama" == "Obama"   # 可见字符串,必须完成相等
# echo $?
1

# A=obama
# B=jerry
# test "$A" == "$B"     # 测试A变量内存空间存储的数据(字符型或数值型)是否与B变量中存储的数据相等
# echo $?
1

##测试方法二
# [ "obama" == "obama" ]
# echo $?
0

# A=obama
# B=jerry
# [ "$A" == "$B" ]
# echo $?
1

##测试方法三
# [[ "obama" == "obama" ]]
# echo $?
0

# [[ "$A" == "$B" ]]
# echo $?
1
2) A > B ,A所表示的字符是否大于B所表示的字符
3) A < B ,A所表示的字符是否小于B所表示的字符
4) A != B ,A所表示的字符和B所表示的字符是否不相等
##测试方法一
# test "obama" != "obama"  # 测试左侧字符串,是否与右侧字符串不相等
# echo $?
1

# test "$B" != "$A"
# echo $?
0

##测试方法二
# [ "obama" != "obama" ]
# echo $?
1

# [ "$B" != "$A" ]
# echo $?
0

##测试方法三
# [[ "obama" != "obama" ]]
# echo $?
1

# A=obama
# B=jerry
# [[ "$A" != "$B" ]]
# echo $?
0
5) A =~ B ,A所表示的字符能否被B所表示的(正则表达式)模式所匹配。
# test "obama" =~ "^o.*"
-bash: test: =~: binary operator expected
# test "obama" =~ ^o.*
-bash: test: =~: binary operator expected

# [ "obama" =~ "^o.*" ]
-bash: [: =~: binary operator expected
# [ "obama" =~ ^o.* ]
-bash: [: =~: binary operator expected

# [[ "obama" =~ "^o.*" ]]
# echo $?
1

# [[ "obama" =~ ^o.* ]] #模式不能加引号
# echo $?
0
6)-z "B", 测试B所表示的字符串是否为空,空为真
##测试方法一
# test -z "obama"
# echo $?
1

A=
# test -z "$A"  # A变量为空时,测试其结果
# echo $?
0

A=jerry
# test -z "$A"  # A变量不空时,测试其结果
# echo $?
1

##测试方法二
# [ -z "how are you?" ]
# echo $?
1

A=
# [ -z "$A" ]
# echo $?
0

##测试方法三
# [[ -z "how are you?" ]] # 测试字串是否为空
# echo $?
1

A=
# [[ -z "$A" ]]  # 测试变量中存储的字串,是否为空
# echo $?
0
7) -n "B", 测试B所表示的字符串是否为不空,不空为真
##测试方法一
# test -n "obama"
# echo $?
0

A=
# test -n "$A"  # A变量为空时,测试其结果
# echo $?
1

A=jerry
# test -n "$A"  # A变量不空时,测试其结果
# echo $?
0

##测试方法二
# [ -n "how are you?" ]
# echo $?
0

A=
# [ -n "$A" ]
# echo $?
1

##测试方法三
# [[ -n "how are you?" ]] # 测试字串是否为空
# echo $?
1

A=
# [[ -n "$A" ]]  # 测试变量中存储的字串,是否为空
# echo $?
1
文件测试

-a 或 -e 测试文件是否存在,存在时状态返回值为0,否则为1-255
# [ -a /tmp/file.txt ] # 测试文件是否存在,存在执行状态结果为0,否则为1-255
# echo $?
0

# [ -e /tmp/file.txt ] # 测试文件是否存在,存在执行状态结果为0,否则为1-255
# echo $?
0
存在且文件为什么类别 (dbc lsp)
-b 是否存在且为 块设备文件,存在则为真
# [ -b /dev/sda ]  #不存在或不为块设备,结果为1.-255
# echo $?
1
# [ -b /dev/vda ]  #存在且为块设备,结果为0
# echo $?
0

# ls -l /dev/sda   #验证结果,不存在
ls: cannot access /dev/sda: No such file or directory
# ls -l /dev/vda   #验证结果,存在
brw-rw---- 1 root disk 253, 0 Jul 31  2017 /dev/vda   ##由b可知为块设备
-c 是否存在 且为字符设备文件
crw-rw-rw- 1 root root      1,   5 Jul 31  2017 zero
crw-rw-rw- 1 root root      1,   3 Jul 31  2017 null

# [ -c /dev/null ] #存在且为字符设备
# echo $?
0

# [ -c /dev/zero ]
# echo $?
0
-d 是否存在 且为目录 文件
# ls -ld /etc
drwxr-xr-x. 111 root root 12288 Jun 11 16:38 /etc
# [ -d /etc ]
# echo $?
0
-f 是否存在 且为普通 文件
# ls -l /var/log/yum.log
-rw------- 1 root root 0 Jun 10 12:26 /var/log/yum.log
# [ -f /var/log/yum.log ]
# echo $?
0
-p 管道
# [ -p /var/log/yum.log ]
# echo $?
1
-h 或 -L 符号链接
# ls -l /etc/system-release
lrwxrwxrwx 1 root root 14 Jul 31  2017 /etc/system-release -> centos-release
# [ -h /etc/system-release ]
# echo $?
0
# [ -L /etc/system-release ]
# echo $?
0
-S 套接字
# ls -l /dev/log
srw-rw-rw- 1 root root 0 Jul 31  2017 /dev/log

# [ -S /dev/log ]
# echo $?
0
存在且有特殊权限:(文件本身)
-g ,拥有sgid权限
# ls -l /etc/passwd
-rw-r--r-- 1 root root 3673 Jun 10 13:22 /etc/passwd
# [ -g /etc/passwd ]
# echo $?
1
-u ,拥有suid权限
# [ -u /etc/passwd ]
# echo $?
1
-k , 拥有sticky权限
# [ -k /tmp ]

# echo $?
0
# ls -ld /tmp
drwxrwxrwt. 13 root root 4096 Jun 12 00:11 /tmp
文件权限: (跟用户相关)
-r 文件存在且可读 cat
# ls -l /etc/shadow a.txt
-rw-r--r-- 1 root root  127 Jun 11 19:25 a.txt
---------- 1 root root 2843 Jun 10 13:24 /etc/shadow

# [ -r a.txt ]
# echo $?
0
# [ -r /etc/shadow ]  ##root用户能读
# echo $?
0

# su - myuser
Last login: Tue Aug  1 18:49:22 CST 2017 on pts/0
$ [ -r /etc/shadow ]  ##对于普通用户不能读
$ echo $?
1
-w 文件存在且可写 修改
# ls -l /etc/shadow a.txt
-rw-r--r-- 1 root root  127 Jun 11 19:25 a.txt
---------- 1 root root 2843 Jun 10 13:24 /etc/shadow
# [ -w /etc/shadow ]
# echo $?
0
# [ -w a.txt ]
# echo $?
0
-x 文件存在且可执行 对于当前用户
# ls -l /bin/ls
-rwxr-xr-x 1 root root 117656 Nov  6  2016 /bin/ls
# [ -x /bin/ls ]
# echo $?
0
-s FILE 文件存在且非空
# touch b.txt
# cat b.txt
# [ -s b.txt ]
# echo $?
1
-t fd 文件描述符 fd是否打开,且与某个终端相关
运行命令
1、终端无关: 与随系统启动
2、终端相关: 手动运行,在交互式接口运行的命令。linux任何一个文件被打开都有一个文件描述符追踪文件

-N FILE 文件从上次打开后 是否被修改过? (重定向)
# [ -N a.txt ]
# echo $?
1

# echo "abc" >> a.txt
# [ -N a.txt ]
# echo $?
0
-O FILE 当前有效用户是否为文件的属主
# ls -l a.txt
-rw-r--r-- 1 root root 131 Jun 12 00:37 a.txt
# [ -O a.txt ]
# echo $?
0
-G FILE 当前有效用户是否为文件的属组
# [ -G a.txt ]
# echo $?
0


FILE1 -ef FILE2 refer to 指向 指向同一个设备上的相同inode
FILE1和FILE2是否为互为硬链接
# [ a.txt -ef b.txt ]
# echo $?
1

# ln a.txt a.hl   ##创建硬链接
# ls -li a.txt a.hl
1558766 -rw-r--r-- 2 root root 131 Jun 12 00:37 a.hl   #inode 1558766
1558766 -rw-r--r-- 2 root root 131 Jun 12 00:37 a.txt  #inode 1558766
# [ a.txt -ef a.hl ]
# echo $?
0


FILE1 -nt FILE2 new than 最近一次修改的时间戳FILE1较FILE2更靠近现在
# ls -l /tmp/ntp.conf*
-rw-r--r-- 1 root root 2439 Jun 11 20:46 /tmp/ntp.conf
-rw-r--r-- 1 root root 2439 Jun 12 00:47 /tmp/ntp.conf.bak
# [ /tmp/ntp.conf -nt /tmp/ntp.conf.bak ]
# echo $? ###说明/tmp/ntp.conf.bak更新
1
FILE1 -ot FILE2 old than 最近一次修改的时间戳FILE1较FILE2更远离现在
# [ /tmp/ntp.conf -ot /tmp/ntp.conf.bak ]
# echo $?  ###说明/tmp/ntp.conf  更旧
0


组合测试条件
逻辑运算:
连接命令

COMMAND1 && COMMAND2

COMMAND1 || COMMAND2

! COMMAND

连接条件

[ EXPRESSION ] && [ EXPRESSION ] 相当于 [ EXPRESSION -a EXPRESSION ]

[ EXPRESSION ] || [ EXPRESSION ] 相当于 [ EXPRESSION -o EXPRESSION ]
[ ! EXPRESSION ]

摩根定律
非(P 且 Q) = (非 P) 或 (非 Q)
非(P 或 Q) = (非 P) 且 (非 Q)

例如:

[ ! EXPRESSION ] && [ ! EXPRESSION ] 相当于 [ ! \( EXPRESSION -o EXPRESSION \) ]

$ install -m 000 /etc/issue /tmp
$ ls -l /tmp/issue
---------- 1 myuser myuser 23 Jun 12 05:32 /tmp/issue

$ [ ! -r /tmp/issue ] && [ ! -w /tmp/issue ]
$ echo $?
0

$ [ ! \( -r /tmp/issue -o -w /tmp/issue \) ]
$ echo $?
0

$ [ ! \(-r /tmp/issue -o -w /tmp/issue\) ]
-bash: [: too many arguments
2、bash中自定义退出状态码
exit [#] 在bash脚本中,一旦遇到exit命令就会终止脚本,退出状态码为exit后的数值。
1、exit存在时
# nano helo.sh
#!/bin/bash
printf "hello everyone\n"
exit 1

## 判断脚本执行的状态结果
# bash helo.sh
hello everyone
# echo $?
1
2、exit不存在时
# nano helo.sh
#!/bin/bash
printf "hello everyone\n"

## 判断脚本执行的状态结果
# bash helo.sh
#!/bin/bash
ls /varr
printf "hello everyone\n"
# echo $?   ##返回值为最后一个命令的执行状态结果
0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux