如果想要判断一个目录是否存在,可以使用命令ls搭配数据流重定向,再配合$?来决定后续的命令进行与否。
但是还有跟简单的方式开进行“条件判断”。他们是"test"命令和判断符合[]「中括号」
1.利用test命令的测试功能
当检测系统上面某些文件或者相关的属性时,利用test这个命令的效果非常令人满意。
当我要检查“/test”是否存在时,使用:
执行的结果不会显示任何信息,但是通过$?、&&、||来显示结果呢?如下:
最终的结果可以告诉我们“exist”和“not exist”。test命令的参数如下表:
测试的标志 | 代表意义 |
关于某个文件名”文件类型“判断,如test -e filename表示存否 | |
-e | 该文件名是否存在(常用) |
-f | 该文件名是否存在且为文件(常用) |
-d | 该文件名是否存在且为目录(directory)(常用) |
-b | 该文件名是否存在且为一个block device设备 |
-c | 该文件名是否存在且为一个character device设备 |
-S | 该文件名是否存在且为一个Socket文件 |
-p | 该文件名是否存在且为一个FIFO(pipe)文件 |
-L | 该文件名是否存在且为一个连接文件 |
关于文件权限的检测,如test -r filename表示可读否(root权限除外) | |
-r | 检测该文件名是否存在且具有”可读“的权限 |
-w | 检测该文件名是否存在且具有”可写“的权限 |
-x | 检测该文件名是否存在且具有”可执行“的权限 |
-u | 检测该文件名是否存在且具有”SUID“的属性 |
-g | 检测该文件名是否存在且具有”SGID“的属性 |
-k | 检测该文件名是否存在且具有”Sticky bit“的属性 |
-s | 检测该文件名是否存在且为”非空白文件“ |
两个文件之间的比较,如test file1 -nt file2 | |
-nt | (newer than)判断file1是否比file2新 |
-ot | (older than)判断file1是否比file2旧 |
-ef | 判断file1与file2是否为同一个文件,可用在判断hard link的判定上。主要意义在于判定两个文件是否均指向同一个inode |
关于两个整数之间的判定,例如test n1 -eq n2 | |
-eq | 两数值相等(equal) |
-ne | 两数值不等(not equal) |
-gt | n1大于n2(greater than) |
-lt | n1小于n2(less than) |
-ge | n1大于等于n2(greater than or equal) |
-le | n1小于等于n2(less than or equal) |
判断字符串的数据 | |
Test -z string | 判断字符串是否为0,若string为空字符串,则为true |
Test -n string | 判断字符串是否非为0,若string为空字符串,则false,注:-n也可省略 |
test str1 = str2 | 判定str1 是否等于str2,若相等,则回传true |
test str1 != str2 | 判定str1是否不等于str2,若相等,则回传false |
多重条件判定;例如:test -r filename -a -x filename | |
-a | 两个条件同时成立!例如test -r file -a -x file,则file同时具有r与x权限时,才回传true |
-o | 任何一个条件成立!例如test -r file -o -x file,则file具有r或x权限时,就可回传true |
! | 反向状态,如test ! -x file,当file不具有x时,则回传true |
栗子:1. 判断文件是否存在,若不存在则给予一个"Filename does not exist"的信息,并中断程序
2. 如果这个文件存在,则判断它是个文件或目录,结果输出"Filename is regular file"或“Filename is directory”
3. 判断一下,执行者的身份对这个文件或目录所拥有的权限,并输出权限数据
如下:
#!/bin/bash
# Program:
# User input a filename,program will check the flowing:
# 1.) exist? 2.) file/directory? 3.) file permissions
# History:
# 2018/11/16 steve First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 1. 让用户输入文件名,并且判断用户是否真的输入字符串
echo -e "Please input a filename,I will check the filename's type and \ permission. \n\n"
read -p "Input a filename:" filename
test -z $filename && echo "You MUST input a filename." && exit 0
# 2. 判断文件是否存在,如不存在则显示并结束脚本
test ! -e $filename && echo "The filename '$filename' DO NOT exit" && exit 0
# 3. 开始判断文件的类型和属性
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm execuable"
# 4. 开始输出信息!
echo "The filename: $filename is a $filetype"
echo "And the permission are: $perm"
2. 利用判断符号[]
除了上面的test之外,还可以利用判断符号“[]”(也就是中括号)来进行数据的判断!
栗子:如果想要知道$HOME这个变量是否为空,可以这样做:
[root@www ~] [ - z "$HOME"] ; echo $?
使用中括号需要特别注意:由于中括号可以在很多地方使用,比如通配符和正则表达式等,因此要在bash的语法中使用中括号作为shell的判断式时,必须要注意中括号的两端需要有空格符来分隔。假设“□”来表示空格符,下面的地方都需要有空格键:
[□"$HOME"□==□"$MALL"□]
为此,使用[]作为判断时,需要注意如下三点:
- 在中括号[]内的每个组件都需要有空格键来分隔;
- 在中括号内的变量,最好都以双引号括起来;
- 在中括号内的常量,最好都以单或双引号括起来。
中括号的使用方法和test几乎一样。只是中括号比较常用在条件判断式if...then...fi的情况下。
栗子:
- 执行一个程序,该程序会让用户现在Y或N;
- 如果用户输入Y或y时,就显示“OK continue”;
- 如果用户输入N或n时,就显示“Oh,interrupt!”
- 如果不是Y/y/N/n之内的其他字符,就显示“i don't now know what your choice is”
利用中括号、&&和||;
#!/bin/bash
# Program:
# This program shows the user's choice
# History:
# 2018/11/17 steve First release
PATH=/bin:/sbin/:/usr/bin:/usr/sbin:/usr/local/bin/:/usr/local/sbin:~/bin
export PATH
read -p "Please input (Y/N): " yn
[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK,continue" && exit 0
[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh,interrupt!" && exit 0
echo "I don't know what your choice is" && exit 0
~
由于输入正确(Yes)的方法有大小写之分,不论输入大写Y或小写y都是可以的,因此判断式内就得要有两个判断才行!由于是任何一个成立即可(大小或小写y),所以这里使用-o(或)连接两个判断。