正是因为我们可以通过程序脚本,设计逻辑交给计算机帮助人类处理问题,才有了如今发展壮大的CS产业。shell script作为一个小程序语言,也是可以加入各种逻辑的,今天学习如何在shell script中加入判断式(很简单的)~~
首先,要学习一些逻辑判断符号:这里通过如下“test指令的测试功能”学习,里面一些逻辑判断(例如-o
,-a
)是不局限于test的,可以在shell中灵活应用。
1.test指令的测试功能
1.1 关于某个档名的“文本类型”判断
如teat -e filename
表示filename存在与否
测试的标志 | 代表意义 |
---|---|
-e | 该档名是否存在? |
-f | 该档名是否存在且为文件(file)? |
-d | 该文件名是否存在且为目录(directory)? |
-b | 该档名是否存在且为一个block device装置? |
-c | 该档名是否存在且为一个character device装置? |
-S | 该档名是否存在且为一个Socket文件? |
-p | 该档名是否存在且为一个FIFO(pipe)文件? |
-L | 该档名是否存在且为一个链接档? |
1.2关于文件的权限侦测
如test -r filename
表示filename是否可读
测试的标志 | 代表意义 |
---|---|
-r | 侦测该档名是否存在且具有可读的权限? |
-w | 侦测该档名是否存在且具有可写的权限? |
-x | 侦测该档名是否存在且具有可执行的权限? |
-u | 侦测该文件名是否存在且具有SUID的属性? |
-g | 侦测该文件名是否存在且具有SGID的属性? |
-k | 侦测该文件名是否存在且具有Sticky bit 的属性? |
-s | 侦测该档名是否存在且为非空白文件? |
1.3 两个文件之间的比较
如 test file1 -nt file2
判断file1是否比file2新
测试的标志 | 代表意义 |
---|---|
- nt | (newer than)判断file1是否比file2新 |
-ot | (older than) 判断file 1 是否比file2 旧 |
-ef | 判断 file1 与 file 2 是否为同一文件,可用在判断hard link的判定上。主要意义在判定,两个文件是否均指向同一个inode。 |
1.4 关于两个整数之间的判定
如 test n1 -eq n2
判断n1是否等于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) |
1.5 判定字符串的数据
测试的标志 | 代表意义 |
---|---|
test -z string | 判定字符串是否为0?若string为空字符串,则为true |
test -n string | 判定字符串是否非?若string为空字符串,则为false(-n亦可省略) |
test str1 == str2 | 判定str1是否等于str2,若相等,则回传true |
test str1 != str2 | 判定str1 是否不等于 str2,若相等,则回传false |
1.6多重条件判定
如 test -r filename -a -x filename
判断filename是否可读且可执行
测试的标志 | 代表意义 |
---|---|
-a | (and) 两状况同时成立,例如 test -r file -a -x file ,则file同时具有r和x权限时,才回传true |
-o | (or)两状况任何一个成立! 例如test -r file -o -x file ,则file具有r或x权限时就可回传ture |
! | 反相状态,如test ! -x file ,当file不具有x时,回传true |
我们写个简单的例子(注意利用test
, ||
, &&
):
- 1)这个文件是否存在,若不存在则给予一个“filename does not exist” 的讯息,并中断程序;
- 2)若这个文件存在,则判断他是文件还是目录?结果输出“filename is a regular file” 或 “filename is directory”;
- 3)判断一下,执行者的身份对这个文件或目录所拥有的权限,并输出权限数据
先看一下这个 low low的写法。。。
#!/bin/bash
read -p "请输入文件名:" filename
test -e ${filename} && echo "exist" || echo "Not exist"
test -f ${filename} && echo "It is a file" || echo "It is not a file"
test -d ${filename} && echo "It is a directory" || echo "It is not a directory"
test -r ${filename} && echo "you can read " || echo "you can not read"
test -w ${filename} && echo "you can write " || echo "you can not write"
test -x ${filename} && echo "you can execute" || echo "you can not execute"
再看一下鸟哥的高端表达~~
vi file_perm.sh
输入如下代码:
#!/bin/bash
#1.让使用者输入档名,并且判断使用者是否真的有输入字符串?
echo -e "Please input a filename, I will check the filename's type and permission"
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 exist" && 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} executable"
#4.开始输出信息
echo "The filename: ${filename} is a ${filetype}"
echo "And the permission for you are : ${perm}"
2. 利用判断括号[ ]
中括号[ ]
学到现在可能有点眼花缭乱了, 因为之前学通配符和正则表达式时都有遇到过。
而在bash的语法中使用它作为shell的判断式时,必须注意中括号的两端要有空格符来分隔!如果空格键用口
来表示。那么,这些地方都应该注意加空格键:
写一段shell来练习:
- 1)当执行一个程序的时候,这个程序会让用户选择Y或N,
- 2)如果用户输入Y或y时,就显示“OK,continue”
- 3)如果用户输入N或n时,就显示“Oh,interrupt!”
- 4)如果不是Y/y/N/n之内的其他字符,就显示"I don't konw what your choice is"
Tip:
-- 这里判断式内要有2个判断才行,因此判断式内的判断连结需要使用-o
-- 同时,巧用exit 0
来控制程序执行
vi ans_yn.sh
输入如下代码:
#!/bin/bash
read -p "Please input 'Y' or 'N' to execute this program:" input
[ "${input}" == "Y" -o "${input}" == "y" ] && echo "OK,continue" && exit 0 #如果输入"Y" 或 “y”,echo输出后便退出程序
[ "${input}" == "N" -o "${input}" == "n" ] && echo "Oh,interrupt!" && exit 0 #如果输入"N" 或 “n”,echo输出后便退出程序
echo "I don't know what your choice is" && exit 0 #如果不是"Y","y","N","n"中的任何一个,程序才会走到这一步(这是前面两步判断式后面加`exit 0`的意义)
3. shell script 的默认变数
3.1 认识shell script 的默认变数($0,$1)
其实script针对参数已经有设定好一些变量名称了
执行的脚本档名为$0这个变量,第一个接的参数就是$1。所以,只要我们在script里面善用$1的话,就可以很简单的立即下达某些指令功能了。
其他一些较为特殊的变量可以在script内使用来呼叫这些参数:
-
$#
代表后接的参数(个数) -
$@
代表 「“$1” “$2” “$3” “$4”」之意,每个变量是独立的(用双括号括起来) -
$*
代表 「“$1c$2c$3c$4”」,其中c为分隔字符,默认为空格键,所以本例中代表「“$1 $2 $3 $4”」之意
还是来实例学习一下吧:执行一个可以携带参数的script,执行脚本后可以显示如下内容
- 1)程序的文件名为何?
- 2)共有几个参数?
- 3)若参数的个数小于2则告知使用者参数数量太少
- 4)全部的参数内容为何
- 5)第一个参数为何
- 6)第二个参数为何
vi how_paras.sh
输入如下代码:
#!/bin/bash
echo "程序的文件名为 ==> "$0""
echo "程序的参数个数 ==> "$#""
[ "$#" -lt 2 ] && echo "参数的个数小于2"
echo "全部的参数内容 ==> "$@""
echo "第一个参数为 ==> "$1""
echo "第二个参数为 ==> "$2""
3.2 shift:造成参数变量号码偏移
shift会移动变量,而且shif 后面可以接数字,代表拿掉最前面的几个参数的意思
还是从例子中理解吧
vim shift_paras.sh
输入如下代码:
#!/bin/bash
echo "程序的参数个数 ==> “$#”"
echo "全部的参数内容 ==> “$@”"
shift #第一次偏移(1个参数)
echo "程序的参数个数 ==> “$#”"
echo "全部的参数内容 ==> “$@”"
shift 3 #第二次偏移(3个参数)
echo "程序的参数个数 ==> “$#”"
echo "全部的参数内容 ==> “$@”"
执行shift_paras.sh
,看鸟哥执行的结果吧