shell script

Shell Script

最简单的功能就是将许多指令汇整写在一起,去处理复杂的动作

数组、循环、条件与逻辑判断等功能

  • 自动化管理的重要依据
  • 追踪和管理系统的重要工能
  • 简单入侵检测功能
  • 连续指令单一化
  • 简易的数据处理
  • 跨平台支持与学习历程较短

注意:shell script 处理数据的速度不太理想,所以通常利用shell script 处理服务器的侦测,倒是没有进行大量运算的需求

脚本执行的方式决定了bash的环境,其中涉及了父进程和子进程的概念。source和小数点来执行的话,是在父进程中执行脚本

判断式

test

测试的标志 代表意义
1、关于某个档名的 文件类型 判断,如 test -e filename 表示存在否
-e 该 档名 是否存在
-f 该 档名 是否存在且为文件(file)
-d 该 文件名 是否存在且为目录
-b 该 档名 是否存在且为一个block device 装置
-c 该 档名 是否存在且为一个 character device 装置
-S 该 档名 是否存在且为一个 Socket 文件
-p 该档名 是否存在且为一个FIFO(pipe)文件
-L 该 档名 是否存在且为一个连结档
2、关于文件的权限侦测,如 test -r filename 表示可读否(但root权限常有例外)
-r 侦测该档名是否存在且具有可读的权限
-w 侦测该档名是否存在且具有可写的权限
-x 侦测该档名是否存在且具有可执行的权限
-u 侦测该档名是否存在且具有 SUID 的属性
-g 侦测该文件是否存在且具有 SGID 的属性
-k 侦测该文件名是否存在且具有 Sticky bit 的属性
-s 侦测该档名是否存在且为 非空白文件
3、两个文件之间的比较,如 test file1 -nt file2
-nt (new than)判断file1 是否比 file2 新
-ot (older than)判断 file1 是否比file2旧
-ef 判断file1与file2是否为同一文件,可用于判断 hard link 的判定上。主要意义在判定,两个文件是否均指向同一个inode里
4、关于两个整数之间的判定,如 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)
5、判定字符串的数据
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
6、多重条件判定,如 test -r filename -a -x filename
-a (and)两状况同时成立,如 test -r filename -a -x file ,则file同时具有r 与 x 的权限,才回传true
-o (or)
! 反向状态,如 test ! -x file ,当file 不具有x,回传true

判断符号 []

注意:要在bash的语法中使用中括号作为shell的判断式时,必须要注意中括号的两端需要有空格符来分隔

  • 在中括号[]内的每一个组件都需要有空格符来分隔
  • 在中括号内的变数,最好都以双引号括号起来
  • 在中括号内的常数,最好都以单或双引号括号起来

中括号的使用方法与test 几乎一模一样,只是中括号比较常用在条件判断式 if then fi的情况

默认变数($0,$1…)

  • $0 执行的脚本档名
  • $1 第一个接的参数
  • $2…
  • $# 代表后面接的参数个数
  • $@ 代表 ["$1” “$2” “$3” “$4”]之意,,每个变量是独立的(用双引号括起来)
  • $* 代表[“$1c$2c$3c$4”],其中c为分隔字符,默认为空格键,所以本例中代表[“$1 $2 $3 $4”]之意

shift 参数变量号码偏移

shift 会移动变量,而且shift 后面可以接数字,代表拿掉最前面的几个参数的意思

条件判断式

单层、简单条件判断式

if [ 条件判断式 ]; then
    当条件判断式成立时,可以进行的指令
fi

可以将多个条件写入一个中括号中,也可以有多个中括号隔开,中括号与中括号之间,则以&&或|| 隔开

多重、复杂条件判断式

if [ 条件判断式 ]; then
    当条件判断式成立时,可以进行的指令
else
    当条件不成立时,可以进行的指令
fi
if [ 条件判断式1 ]; then
    当条件判断式1成立时,可以进行的指令
elif [ 条件判断式2 ]; then
    当条件判断式2成立时,可以进行的指令
else
    当条件1、2都不成立时,可以进行的指令
fi

利用 case esac 判断

case $变量名称 in
    "第一个变量内容")
        程序段
        ;;
    "第二个变量内容")
        程序段
        ;;
    *)
        不包含第一个变量内容与第二个变量内容的其他程序执行段
        exit 1
        ;;
esac

$变量名称 变量内容有两种取得方式:

  • 直接下达式:$1
  • 交互式:read命令

function 功能

function 的设定一定要在程序的最前面

function fname(){
    程序段
}

也可以像命令行参数一样给函数传参,在函数内部使用$1、$2…来使用传递的参数。注意:这里的$1 与命令行的参数并不是同一个变量

循环 loop

while do done , until do done (不定循环)

while [ condition ]
do
    程序段落
done
untill [ condition ]
do
    程序段落
done

for do done (固定循环)

for var in con1 con2 con3 ...
do
    程序段
done
$(seq 1 100)
# seq 是 sequence(连续)缩写之意,会产生1-100的整数之意
{1..100} # 1-100
{a..g} # a-g

for do done 的数值处理

for (( 初始值;限制值;执行步阶 ))
do
    程序段
done

搭配随机数与数组的实验

透过随机数、数组、循环与条件判断,你可以做出很多很特别的东西。还不用写传统编程语言~

脚本的追踪与 debug

sh [-nvx] scripts.sh
选项与参数:
-n:不要执行script,仅查询语法的问题
-v:在执行script前,先将scripts的内容输出到屏幕上
-x:将使用到的script内容显示到屏幕上,这是很有用的参数

熟悉sh的用法,将可以使你在管理linux的过程中得心应手。至于在shell scripts的学习方法上,需要多看、多模仿、并加以修改成自己的样式 是最快的学习手段

另外,我们linux系统本来就有很多的服务启动脚本,如果你想要知道每个script所代表的功能是什么,你可以直接以vim进入该script去查阅一下, 通常立刻就知道该script的目的了

重点回顾

  • shell script 是利用 shell 的功能所写的一个程序(program),这个程序是使用纯文本文件,将一些shell的语法与指令(含外部指令) 写在里面,搭配正则表达式、管道命令与数据流重定向等功能,已达到我们所想要的处理目的
  • shell script 用在系统管理上面是很好的一项工具,但是用在处理大量数值运算上,就不够好了,因为shell script 的速度很慢,且使用CPU资源较多,造就主机资源的分配不良
  • 在shell script 的文件中,指令的执行时从上而下、从左而右的分析和执行
  • shell script 的执行,至少需要有r的权限,若需要直接下达指令下达,则需要拥有r与x的权限
  • 良好的程序撰写习惯中,第一行要宣告shell(#!/bin/bash),第二行以后则宣告程序的用途、版本、作者等
  • 对谈式脚本可用read指令达到
  • 要建立每次执行脚本有不同结果的数据,可使用date指令利用日期达到
  • script 的执行若以source来执行,代表在父程序的bash内执行之意
  • 若需进行判断式,可使用test或中括号来处理
  • 在script内,$0,$1,2...,@是有特殊意义的
  • 条件判断式可使用 if then 来判断,若是固定变量内容的情况下,使用case $var in esac 来处理
  • 循环主要分为不定循环(while,until)以及固定循环(for),配合do ,done来达到所需任务
  • 我们可使用 sh -x script.sh 来进行程序的 debug