第十二章 学习Shell Scripts

发布时间 2023-07-31 11:13:09作者: Evan-whc

第十二章 学习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指令的测试功能

  1. 关于某个档名的【文件类型】判断,如test -e filename表示存在否。
测试的标志 代表意义
-e 该档名是否存在
-f 该档名是否存在且为文件
-d 该文件名是否存在且为目录
-b 该档名是否存在且为一个block device装置
-c 该档名是否存在且为一个character device装置
-S 该档名是否存在且为一个Socket文件
-p 该档名是否存在且为一个FIFO文件
-L 该档名是否存在且为一个连接档
  1. 关于文件的权限侦测,如test -r filename表示可读否
测试的标志 代表意义
-r 侦测该档名是否存在且具有【可读】的权限?
-w 档名是否存在且具有【可写】权限
-x 档名是否存在且具有【可执行】权限
-u 档名是否存在且具有【SUID】属性
-g 档名是否存在且具有【SGID】的属性
-k 档名是否存在且具有Sticky bit的属性
-s 侦测该档名是否存在且为【非空白文件】
  1. 两个文件之间的比较,如:test file1 -nt file2
测试的标志 代表意义
-nt 判断file1是否比file2新
-ot 判断file1是否比file2旧
-ef 判断file1与file2是否为同一文件,可用在判断hard link的判定上。
  1. 关于两个整数之间的判定,例如:test n1 -eq n2
测试的标志 代表意义
-eq 两数值相等
-ne 两数值不等
-gt n1大于n2
-lt n1小于n2
-ge n1大于等于n2
-le n1小于等于n2
  1. 判定字符串的数据
测试的标志 代表意义
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
  1. 多重条件判定,例如: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内容显示到屏幕上,这是很有用的参数!