Shell编程
编写shell脚本
Shell脚本命令的工作方式有两种:交互式和批处理。
交互式(Interactive):用户每输入一条命令就立即执行。
批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令。
一、编写简单的脚本
SHELL脚本编写:
声明:#!/bin/bash(用来告诉系统使用哪种Shell解释器来执行该脚本)
注释: #xxxxxx(是对脚本功能和某些命令的介绍信息,使得自己或他人在日后看到这个脚本内容时,可以快速知道该脚本的作用或一些警告信息)
命令:xxxxxx
例1:查看当前所在工作路径并列出当前目录下所有的文件及属性信息:
注:Shell脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将.sh后缀加上,以表示是一个脚本文件。
执行上述脚本:
执行方式:
1、bash解释器命令直接运行Shell脚本文件;
2、通过输入完整路径的方式来执行。但默认会因为权限不足而提示报错信息,此时只需要为脚本文件增加执行权限即可。
二、接收用户的参数
上述脚本程序只能执行一些预先定义好的功能,为了让Shell脚本程序更好地满足用户的一些实时需求,以便灵活完成工作,必须要让脚本程序能够像之前执行命令时那样,接收用户输入的参数。
当用户执行某一个命令,加或不加参数的输出结果是不同的。就是说,命令不仅要能接收用户输入的内容,还要有能力进行判断区别,根据不同的输入调用不同的功能。
Linux系统中的Shell脚本语言已经内设了用于接收参数的变量,变量之间使用空格间隔。
例如:
$0指当前Shell脚本程序的名称;
$#:指总共有几个参数;
$*:指所有位置的参数值;
$?:指显示上一次命令的执行返回值;
$1、$2、$3……则分别对应着第N个位置的参数值,如下图所示:
效果如下:
三、判断用户的参数
Shell脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字0,否则便返回非零值。
注:条件表达式两边均应有一个空格。
按照测试对象来划分,条件测试语句可以分为4种:
文件测试语句;
逻辑测试语句;
整数值比较语句;
字符串比较语句。
1、文件测试:即使用指定条件来判断文件是否存在或权限是否满足等情况的运算符,具体的参数如下表:
文件测试所用的参数
操作符 | 作用 |
---|---|
-d | 测试文件是否为目录类型 |
-e | 测试文件是否存在 |
-f | 判断是否为一般文件 |
-r | 测试当前用户是否有权限读取 |
-w | 测试当前用户是否有权限写入 |
-x | 测试当前用户是否有权限执行 |
例1:判断/etc/fstab是否为一个目录类型的文件,通过Shell解释器的内设$?变量显示上一条命令执行后的返回值。返回值为0,则目录存在。
2、逻辑测试语句:对测试结果进行逻辑分析;
&&:逻辑“与”,表示当前面的命令执行成功后才会执行它后面的命令;
||:逻辑“或”,表示当前面的命令执行失败后才会执行它后面的命令;
!:逻辑“非”,表示把条件测试中的判断结果取相反值。如果原本测试的结果是正确的,则将其变成错误的;原本测试错误的结果则将其变成正确的。
例:判断/dev/cdrom文件是否存在,若存在则输出Exist字样。
例:结合系统环境变量USER来判断当前登录的用户是否为非管理员身份。
注:叹号应该加到判断语句的前面,代表对整个的测试语句进行取反值操作,不应该写成“$USER != root”,因为!=代表的是不等于符号≠。
3、整数值比较语句:不能将数字与字符串、文件等内容一起操作,可用的整数比较运算符如下表所示:
操作符 | 作用 |
---|---|
-eq | 是否等于 |
-ne | 是否不等于 |
-gt | 是否大于 |
-lt | 是否小于 |
-le | 是否等于或小于 |
-ge | 是否大于或等于 |
例:使用free -m命令查看内存使用量情况(单位为MB),然后通过grep Mem:命令过滤出剩余内存量的行,再用awk ‘{print $4}’命令只保留第四列:
注:字母无法与数字进行大小比较,例如,“a是否大于等于3”是完全错误的,无法比较大小。
4、字符串比较语句:用于判断测试字符串是否为空值,或两个字符串是否相同。经常用来判断某个变量是否未被定义(即内容为空值)。
常见的字符串比较运算符:
操作符 | 作用 |
---|---|
= | 比较字符串内容是否相同 |
!= | 比较字符串内容是否不同 |
-z | 判断字符串内容是否为空 |
例:通过判断String变量是否为空值,进而判断是否定义了这个变量:
例:结合逻辑运算符,当用于保存当前语系的环境变量值LANG不是英语(en.US)时,则会满足逻辑测试条件并输出“Not en.US”(非英语)的字样:
四、流程控制语句
1、if条件测试语句:分为单分支结构、双分支结构、多分支结构;
例:单分支的if条件语句来判断/media/cdrom目录是否存在,若不存在就创建这个目录,反之则结束条件判断和整个Shell脚本。
例:使用双分支的if条件语句来验证某台主机是否在线:通过-c参数来规定尝试的次数,并使用-i参数定义每个数据包的发送间隔,以及使用-W参数定义等待超时时间。
注:**/dev/null 黑洞文件**,把输出信息重定向到这个文件等同于删除数据(类似于没有回收功能的垃圾箱),可以让用户的屏幕窗口保持简洁。
例:使用多分支的if条件语句来判断用户输入的分数在哪个成绩区间内。
read是用来读取用户输入信息的命令,能够把接收到的用户输入信息赋值给后面的指定变量,-p参数用于给予用户一些提示信息。
2、for条件循环语句
例:使用for循环语句从列表文件中读取多个用户名,然后为其逐一创建用户账户并设置密码。首先创建用户名称的列表文件users.txt,每个用户名称单独一行。
例:让脚本从主机列表文件ipaddrs.txt中自动读取IP地址,通过判断ping命令执行后的返回值来逐个测试主机是否在线。
3、while条件循环语句
例:编写一个用来猜测数值大小的脚本。该脚本使用**$RANDOM变量来调取出一个随机的数值(范围为0~32767),将这个随机数对1000进行取余操作,并使用expr命令**取得其结果,再用这个数值与用户通过read命令输入的数值进行比较判断。
while条件循环语句中的条件测试始终为true,因此判断语句会无限执行下去,直到用户输入的数值等于expr命令取得的数值后,这两者相等之后才运行exit 0命令,终止脚本的执行。
4、case条件测试语句
例:在脚本中组合使用case条件测试语句和通配符,提示用户输入一个字符并将其赋值给变量KEY,然后根据变量KEY的值向用户显示其值是字母、数字还是其他字符。