[Linux Shell学习系列六]Shell的条件执行——1条件测试

Shell脚本可以使用条件逻辑,使脚本根据参数、Shell变量或其他条件的值采取不同的行动。

1. 使用test命令

test命令可以做各种测试并每当测试成功或失败时设置它的退出状态码为0(真)或1(假)。

test命令可以用于:

文件属性测试;

字符串测试;

算术测试。

语法:test EXPRESSTION或[EXPRESSION]

$ test -d "$HOME"; echo $? #文件属性的测试,使用-d操作符测试变量$HOME值,是否为目录且存在
0 #0表示是目录且存在

$ [ "abc" != "def" ];echo $? #字符串比较
0 #0表示为真,两个字符串不想等

$ test 7 -gt 3 && echo True || echo False #算数比较
True #7大于3则打印真,否则打印假

 

1)文件属性操作符示例

#1.使用-e选项,如果文件存在为真
$ test -e /bin/cp && echo "The command $_ found." || echo "The command $_ not found."  
The command /bin/cp found.

#2.使用-f选项,文件为常规文件且存在时为真
$ test -f /etc/resolv.conf && echo "The file $_ found." || echo "The file $_ not found." 
The file /etc/resolv.conf found.

#3.使用-d选项,文件为目录且存在时为真
$ test -d /local && echo "The directory $_ found." || echo "The directory $_ not found." 
The directory /local not found.

#4.使用-c选项,文件为特殊字符文件且存在时为真
$ test -c /dev/zero && echo "The file $_ is a character spetial." || echo "The file $_ is not a character spectial." 
The file /dev/zero is a character spetial.
$ test -c /bin/ls && echo "The file $_ is a character spetial." || echo "The file $_ is not a character spectial." 
The file /bin/ls is not a character spectial.

#5.使用-b选项,文件为特殊块文件且存在时为真
$ test -b /dev/sda && echo "The file $_ is a block spetial." || echo "The file $_ is not a block spectial." 
The file /dev/sda is not a block spectial.
$ test -b /bin/cp && echo "The file $_ is a block spetial." || echo "The file $_ is not a block spectial." 
The file /bin/cp is not a block spectial.

#6.使用-p选项,文件为命名管道且存在时为真
$ test -p /dev/initctl && echo "The file $_ is a named pipe." || echo "The file $_ is not a named pipe." 
The file /dev/initctl is a named pipe.
$ test -p /bin/grep && echo "The file $_ is a named pipe." || echo "The file $_ is not a named pipe." 
The file /bin/grep is not a named pipe.

#7.使用-S选项,文件为套接字文件且存在时为真
$ test -S /dec/log && echo "The file $_ is a socket." || echo "The file $_ is a socket." 
The file /dec/log is a socket.

#8.使用-L选项,文件为符号链接且存在时为真(与-h相同)
$ ls -ll /bin/sh
lrwxrwxrwx. 1 root root 4 Nov 26 06:24 /bin/sh -> bash
$ test -L /bin/sh && echo "The file $_ is a symbolic link." || echo "The file $_ is a symbolic link." 
The file /bin/sh is a symbolic link.

#9.使用-h选项,文件为符号链接且存在时为真(与-h相同)
$ test -h /bin/sh && echo "The file $_ is a symbolic link." || echo "The file $_ is a symbolic link." 
The file /bin/sh is a symbolic link.

#10.使用-g选项,文件存在且设置了sgid位时为真
$ test -g /bin/mount && echo "The file $_ has sgid bit." ||echo "The file $_ has no sgid bit."
The file /bin/mount has no sgid bit.

#11.使用-u选项,文件存在且设置了suid位时为真
$ test -u /bin/mount && echo "The file $_ has suid bit." ||echo "The file $_ has no suid bit."
The file /bin/mount has suid bit.

#12.使用-r选项,文件存在且可读时为真
$ test -r /proc/meminfo && echo "The file $_ is readble." ||echo "The file $_ is not readble."
The file /proc/meminfo is readble.

#13.使用-w选项,文件存在且可写时为真
$ test -w /proc/meminfo && echo "The file $_ is writable." ||echo "The file $_ is not writable."
The file /proc/meminfo is not writable.

#14.使用-x选项,文件存在且可执行时为真
$ test -x /bin/cp && echo "The file $_ is excutable." ||echo "The file $_ is not excutable."
The file /bin/cp is excutable.
$ test -x /proc/meminfo && echo "The file $_ is excutable." ||echo "The file $_ is not excutable."
The file /proc/meminfo is not excutable.

#15.使用-s选项,文件存在且不为空时为真
$ test -s /ect/inittab && echo "The file $_ is not empty." || echo "The file $_ is empty." 
The file /ect/inittab is empty.

#16.使用-t选项(test -t <fd>),文件描述符fd已打开且引用了一个终端则为真
(后续介绍)

#17.<FILE1> -nt <FILE2>,FILE1比FILE2新则为真
$ ll
total 12
-rw-rw-r--. 1 user1 user1 19 May 15 10:42 a.txt
-rw-rw-r--. 1 user1 user1 12 May 15 09:36 b.txt
-rw-rw-r--. 1 user1 user1  6 May 15 09:36 c.txt
$ test a.txt -nt b.txt && echo "a.txt is newer than b.txt." || echo "a.txt is older than b.txt."
a.txt is newer than b.txt.

#18.<FILE1> -ot <FILE2>,FILE1比FILE2旧则为真
$ test a.txt -ot b.txt && echo "a.txt is older than b.txt." || echo "a.txt is newer than b.txt."
a.txt is newer than b.txt.

#19.<FILE1> -ef <FILE2>,FILE1有硬链接到FILE2则为真(如果FILE1和FILE2指向相同的设备和节点号则返回为真。)
$ ln a.txt  a.ln
$ ls -l a.txt a.ln
-rw-rw-r--. 2 user1 user1 19 May 15 10:42 a.ln
-rw-rw-r--. 2 user1 user1 19 May 15 10:42 a.txt
$ test a.ln -ef a.txt && echo "True" || echo "False"
True
$ test a.ln -ef b.txt && echo "True" || echo "False"
False

 

2)字符串测试操作符示例

#1.使用-z <STRING>,如果<STRING>为空则为真
$ [ -z "" ]; echo $?
0

#2.使用-n <STRING>,如果<STRING>不为空则为真
$ [ -n "abc" ]; echo $?
0

#3.<STRING1> = <STRING2>,如果相同则为真
$ test "abc" = "abc";echo $?
0
$ test "abc" = "cde";echo $?
1

#4.<STRING1> != <STRING2>,如果不相同则为真
$ test "abc" != "cde";echo $?
0
$ test "abc" != "abc";echo $?
1

#5.<STRING1> < <STRING2>,如果<STRING1>字典序在<STRING2>之前则为真(ASCII码顺序)
$ test "abc" \< "cde";echo $?
0
$ [ "abc" \< "cde" ]; echo $?
0

#6.<STRING1> > <STRING2>,如果<STRING1>字典序在<STRING2>之后则为真(ASCII码顺序)
$ test "abc" \> "cde";echo $?
1

 

3)算术测试操作符示例

#1.<INTEGER1> -eq <INTEGER2> <INTEGER1>等于<INTEGER2>为真
$ test 5 -eq 5 && echo Yes || echo No
Yes
$ [ 5 -eq 5 ] && echo Yes || echo No
Yes

#2.<INTEGER1> -ne <INTEGER2> <INTEGER1>不等于<INTEGER2>为真
$ test 5 -ne 10 && echo Yes || echo No
Yes
$ [ 5 -ne 10 ] && echo Yes || echo No
Yes

#3.<INTEGER1> -le <INTEGER2> <INTEGER1>小于或等于<INTEGER2>为真
$ test 5 -le 10 && echo Yes || echo No
Yes
$ [ 5 -le 10 ] && echo Yes || echo No
Yes

#4.<INTEGER1> -ge <INTEGER2> <INTEGER1>大于或等于<INTEGER2>为真
$ test 5 -ge 10 && echo Yes || echo No
No
$ [ 5 -ge 10 ] && echo Yes || echo No
No

#5.<INTEGER1> -lt <INTEGER2> <INTEGER1>小于<INTEGER2>为真
$ test 5 -lt 10 && echo Yes || echo No
Yes
$ [ 5 -lt 10 ] && echo Yes || echo No
Yes

#6.<INTEGER1> -gt <INTEGER2> <INTEGER1>大于<INTEGER2>为真
$ test 5 -gt 10 && echo Yes || echo No
No
$ [ 5 -gt 10 ] && echo Yes || echo No
No

Bash中还有“[[]]”语法,是[]的提高版本,是一个关键字而不是程序。与[]很多相同点。

语法:[[ EXPRESSION ]] #注意左右要有空格

[[]]和[]的不同
用法 [[]] [] 示例
字符串比较 > \>

[[ a > b ]]

[ a \> b ]

判断字典序a在b后为真

  < \<

[[ a < b ]]

[ a \< b ]

判断字典序a在b前为真

表达式分组 (...)

\(...\)

不建议使用

[[ $var =img* && ($var = *.png || $var = *.jpg ) ]]

判断$var是否以img开头,以png或jpg结尾

格式匹配 = 不可用

[[ $name  =a* ]] 

判断$name以a开头

正则表达式匹配 =~ 不可用

[[ $(date) =~ ^Fri\...\ 13 ]]

判断date输出结果是否符合格式Fri开头" 13"结尾

 

2. if结构的语法格式
if结构用于在Shell脚本中进行判定。

语法:if TEST-COMMANDS; then CONSEQUENT-COMMANDS; fi

if TEST-COMMANDS; then 

  CONSEQUENT-COMMANDS

fi

if TEST-COMMANDS

then 

  CONSEQUENT-COMMANDS

fi

如果TEST-COMMANDS返回0,则CONSEQUENT-COMMANDS被执行,否则跳过,执行fi之后的语句。

$ cat checkpassword.sh 
#!/bin/bash
#2020-05-20

read -sp "Enter password: " pass #读取输入的密码

if test "$pass" == "1" #判断输入是否为1
then
        echo "Password Verified." #为1则执行
        exit 0
fi 

exit 1 # 不为1则执行

$ ./checkpassword.sh 
Enter password: Password Verified. #此处输入1
$ echo $?
0  #退出码为0


$ ./checkpassword.sh 
Enter password: #此处不输入1

$ echo $?
1 #退出码为1

 

3. if...else...fi语句

if...else...fi语句允许脚本根据条件的不同结果,可以采取不同的行动

语法:

if TEST-COMMANDS

then 

  TRUE-COMMANDS

else

  FALSE-COMMANDS

fi

$ cat checkpassword.sh 
#!/bin/bash
#2020-05-20

read -sp "Enter password: " pass

if test "$pass" == "1"
then
        echo -e "\nPassword Verified." #条件为真时执行
        exit 0
else
        echo -e "\nAccess denied." #条件为假时执行
        exit 1
fi 

$ ./checkpassword.sh 
Enter password:  #此处输入1
Password Verified. 
$ echo $?
0
$ ./checkpassword.sh 
Enter password:  #此处不输入1
Access denied.
$ echo $?
1

 

4. 嵌套的if/else语句

语法:

if TEST-COMMANDS

then  

  if TEST-COMMANDS #这里是嵌套的if...else...fi语句,也可以放在else里面

  then 

    CONSEQUENT-COMMANDS

  else

    CONSEQUENT-COMMANDS

  fi

else

  CONSEQUENT-COMMANDS

fi

 

5. 多级if...elif...else...fi

语法:

if TEST-COMMANDS

then 

  CONSEQUENT-COMMANDS

elif TEST-COMMANDS #可以有多个elif段落

then

  CONSEQUENT-COMMANDS

elif TEST-COMMANDS

then

  CONSEQUENT-COMMANDS

else #只能有一个else

  CONSEQUENT-COMMANDS

fi

注:文中有示例,这里省略。

 

本节结束

posted @ 2020-05-20 10:12  workingdiary  阅读(391)  评论(0)    收藏  举报