第12章 学习Shell Scripts
第十二章 学习Shell Scripts
12.1.3 撰写shell scripts的良好习惯建立
建议你一定要养成良好的script撰写习惯,在每个script的文件头处记录好:
- script的功能;
- script的版本信息;
- script的作者与联络方式;
- script的History(历史记录);
- script内较特殊的指令,使用【绝对路径】的方式来下达;
- script运作时需要的环境变量预先宣告与设定。
12.2 简单的shell script练习
12.2.2 script的执行方式差异(source,sh script,./script)
- 利用直接执行的方式来执行script
- 利用source来执行脚本:在父程序中执行
12.3 善用判断式
在第十章中,我们提到过$?这个变量所代表的意义,此外,也透过&&及||来作为前一个指令执行回传值对于后一个指令是否要进行的依据。第十章的讨论中,如果想要判断一个目录是否存在,是否有更简单的方式可以来进行【条件判断】呢?有的~那就是【test】这个指令。
12.3.1 利用test指令的测试功能
- 关于某个档名的【文件类型】判断,如
test -e filename
表示存在否。
测试的标志 | 代表意义 |
---|---|
-e | 该档名是否存在 |
-f | 该档名是否存在且为文件 |
-d | 该文件名是否存在且为目录 |
-b | 该档名是否存在且为一个block device装置 |
-c | 该档名是否存在且为一个character device装置 |
-S | 该档名是否存在且为一个Socket文件 |
-p | 该档名是否存在且为一个FIFO文件 |
-L | 该档名是否存在且为一个连接档 |
- 关于文件的权限侦测,如test -r filename表示可读否
测试的标志 | 代表意义 |
---|---|
-r | 侦测该档名是否存在且具有【可读】的权限? |
-w | 档名是否存在且具有【可写】权限 |
-x | 档名是否存在且具有【可执行】权限 |
-u | 档名是否存在且具有【SUID】属性 |
-g | 档名是否存在且具有【SGID】的属性 |
-k | 档名是否存在且具有Sticky bit的属性 |
-s | 侦测该档名是否存在且为【非空白文件】 |
- 两个文件之间的比较,如:
test file1 -nt file2
测试的标志 | 代表意义 |
---|---|
-nt | 判断file1是否比file2新 |
-ot | 判断file1是否比file2旧 |
-ef | 判断file1与file2是否为同一文件,可用在判断hard link的判定上。 |
- 关于两个整数之间的判定,例如:
test n1 -eq n2
测试的标志 | 代表意义 |
---|---|
-eq | 两数值相等 |
-ne | 两数值不等 |
-gt | n1大于n2 |
-lt | n1小于n2 |
-ge | n1大于等于n2 |
-le | n1小于等于n2 |
- 判定字符串的数据
测试的标志 | 代表意义 |
---|---|
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 | (and)两状况同时成立! |
-o | (or)两状况任何一个成立 |
! | 反相状态 |
12.3.2 利用判断符号[]
使用中括号必须要特别注意,因为中括号用在很多地方,包括通配符与正规表示法等,所以要在bash的语法中使用中括号作为shell的判断式时,必须要注意中括号的两端需要有空格符来分隔喔!
- 在中括号[]内的每个组件都都要有空格键来分隔;
- 在中括号内的变数,最好都以双引号括号起来;
- 在中括号内的常数,最好都以单或双引号括号起来;
12.3.3 Shell script的默认变数($0,$1...)
其实script针对参数已经有设定好一些变量名称了!执行的脚本档名为$0这个变量,第一个接的参数就是$1啊~,所以,只要我们在script里面善用$1的话,就可以很简单的立即下达某些指令功能了!除了这些数字的变量之外,我们还有一些较为特殊的变量可以在script内使用来呼叫这些参数喔!
- $#:代表后接的参数【个数】
- $@: 代表【"$1" "$2" "$3" "$4"】之意,每个变量是独立的(用双引号括起来)
- $*:代表【"$1c$2c$3c$4"】,其中c为分隔符,默认为空格键。
12.4 条件判断式
12.4.1 利用if...then...
-
单层、简单条件判断式
如果你只有一个判断式要进行,那么我们可以简单的这样看:if [ 条件判断式 ]; then 当条件判断式成立时,可以进行的指令工作内容 fi
-
多重、复杂条件判断式
if [ 条件判断式 ]; then 当条件判断成立时,可以进行的指令工作内容 else 当条件判断式不成立时,可以进行的指令工作内容 fi
如果考虑更复杂的情况,则可以使用这个语法:
if [ 条件判断式一]; then 当条件1成立时,可以进行的指令 elif [ 条件判断式二]; then 当条件二成立时,可以进行的指令 else 当条件一与条件 二均不成立时,可以进行的指令 fi
12.4.2 利用 case.....esac 判断
case $变量内容 in
"第一个变量内容")
程序段
;;
"第二个变量内容")
程序段
;;
*)
不包含第一与第二个变量内容的其他程序执行段
exit 1
;;
esac
12.4.3 利用function功能
什么是函数(function)功能啊?其实,函数可以在shell script当中做出一个类似自定义指令的东西,最大的功能是,可以简化我们很多的程序代码~。function的语法是这样的:
function fname(){
程序段
}
12.5 循环(loop)
12.5.1 while do done,until do done(不定循环)
一般来说,不定循环最常见的就是底下这两种状态了:
while [ condition ]
do
程序段落
done
另外一种不定循环的方式:
until [ condition ]
do
程序段落
done
12.5.2 for... do...done(固定循环)
for这种语法,是【已经知道要进行几次循环】的状态!他的语法是:
for var in con1 con2 con3 ...
do
程序段
done
12.5.3 for...do...done的数值处理
除了上述的方法之外,for循环还有另外一种写法!语法如下:
for ((初始值; 限制值; 执行步阶))
do
程序段
done
这种语法适合于数值方式的运算当中,在for后面的括号内的三串内容意义为:
- 初始值:某个变量在循环当中的起始值,直接以类似i=1设定好;
- 限制值:当变量的值在这个限制值的范围内,就继续进行循环;
- 执行步阶:每作一次循环时,变量的变化量。例如i=i+1。
12.6 shell script的追踪与debug
script在执行之前,最怕的就是出现语法的错误的问题了!那么我们如何debug呢?有没有办法不需要透过直接执行该scripts就可以判断是否有问题呢?呵呵!当然是有的!我们就直接以bash的相关参数来进行判断吧!
sh [-nvx] scripts.sh
选项与参数:
-n: 不要执行script,仅查询语法的问题
-v: 在执行script前,先将scripts的内容输出到屏幕上
-x: 将使用到的script内容显示到屏幕上,这是很有用的参数!