3.1 for循环语句
3.1.1 for语句的结构
使用 for 循环语句时,需要指定一个变量及可能的取值列表,针对每个不同的取值重复执行相同的命令序列,直到变量值用完退出循环。在这里,“取值列表”称为 for 语句的执行条件,其中包括多个属性相同的对象,需要预先指定。
语法结构:
for i in(取值列表)
do
命令序列
done
特点:
有一个取值列表
不会进入死循环
上述语句结构中,for 语句的操作对象为用户指定名称的变量,并通过 in 关键字为该变量预先设置了一个取值列表,多个取值之间以空格进行分隔。位于 do…done 之间的命令序列称为循环体,其中的执行语句需要引用变量以完成相应的任务。
for 语句的执行流程:首先将列表中的第一个取值赋给变量,并执行 do…done 循环体中的命令序列;然后将列表中的第二个取值赋给变量,并执行循环体中的命令序列……依此类推,直到列表中的所有取值用完,最后将跳至 done 语句,表示结束循环。
操作:
(1)批量创建账号、删除账号
1、创建取值列表,要做到一行一个参数
2、开始写脚本
注:前面加#号不一定都是注释,有可能是声明
3.批量删除
(2)巡检,检查网络状态以及服务器的开启状态(巡检小程序)
1、先编辑主机列表
2、编辑脚本
3、测试
注:
3.2使用 while 循环语句
3.2.1 while 语句的结构
使用 while 循环语句时,可以根据特定的条件反复执行一个命令序列,直到该条件不再满足时为止。在脚本应用中,应该避免出现死循环的情况,否则后边的命令操作将无法执行。因此,循环体内的命令序列中应包括修改测试条件的语句,以便在适当的时候使测试条件不再成立,从而结束循环。
语法结构:
while 条件测试的语句
do
命令序列
done
特点:
不需要取值列表
容易进入死循环
while 语句的执行流程:首先判断 while 后的条件测试操作结果,如果条件成立,则执行 do…done 循环体中的命令序列;返回 while 后再次判断条件测试结果,如果条件仍然成立,则继续执行循环体;再次返回到 while 后,判断条件测试结果……如此循环,直到 while后的条件测试结果不再成立为止,最后跳转到 done 语句,表示结束循环。
使用 while 循环语句时,有两个特殊的条件测试操作,即 true(真)和 false(假)。使用 true 作为条件时,表示条件永远成立,循环体内的命令序列将无限执行下去,除非强制终止脚本(或通过 exit 语句退出脚本);反之,若使用 false 作为条件,则循环体将不会被执行。这两个特殊条件也可以用在 if 语句的条件测试中。
操作:
(1)创建一批用户,但这批用户并不是根据用户的名字来写用户的名字的,而是name1、name2、name3等,有一定的规律性
1 创建脚本
2 执行、查看
问题测试:
注:判断语句写的不合理,会一直创建,进入到死循环
3.批量删除账户:
(2)猜价格的游戏
1、写脚本
定义一个随机数32768(0-32767)
echo $RANDOM
expr $RANDOM % 1000
expr $RANDOM % 100
注:用expr与RANDOM做取余运算,缩小随机数的范围
2.测试
3.3until循环语句
3.3.1until 语句的结构
until 循环与 while 循环类似,while 循环能实现的脚本 until 同样也可以实现,但区别是while 循环在条件为真是继续执行循环,而 until 则是在条件为假时执行循环。
语法结构
until 测试语句
do
命令序列
done
until 语句的执行流程:首先判断 until 后的条件测试操作结果,如果条件不成立,则执行 do…done 循环体中的命令序列;返回 until 后再次判断条件测试结果,如果条件仍然不成立,则继续执行循环体;再次返回到 until 后,判断条件测试结果……如此循环,直到 until后的条件测试结果成立为止,最后跳转到 done 语句。
操作:
(1)计算1-100的和
1、写脚本
2、测试
加到1000
加到10000
3.4 shell的函数
3.4.1 函数的用法(代码的重用)
Shell 函数可用于存放一系列的指令。在 Shell 脚本执行的过程中,函数被置于内存中,每次调用函数时不需要从硬盘读取,因此运行的速度比较快。在 Shell 编程中函数并非是必须的元素,但使用函数可以对程序进行更好的组织。将一些相对独立的代码变成函数,可以提高程序可读性与重用性,避免编写大量重复代码。
Shell 函数定义的方法
[function] 函数名() {
命令序列[return x]
}
“function”关键字表示定义一个函数,可以省略;
“{”符号表示函数执行命令的入口,该符号可以与函数名同行也可以在函数名下一行的句首;
“}”符号表示函数体结束,两个大括号之间{ }是函数体;
“命令序列”部分可以是任意的 Shell 命令,也可以调用其他函数;
“return”表示退出函数返回一个退出值,通过返回值判断执行是否成功,也可以使用 exit 终止整个 Shell 脚本。Shell 函数调用的方法为:函数名 [参数 1] [参数 2]。
操作:
(1)
(2)指定参数
注:参数的传递,传参
3.4.2 函数变量的作用范围
在 Shell 脚本中函数的执行并不会开启一个新的子 Shell,而是仅在当前定义的 Shell环境中有效。如果 Shell 脚本中的变量没有经过特殊设定,默认在整个脚本中都是有效的。在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令 local 来实现。函数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响。
操作:
(1)函数内定义变量
注:函数内的变量取值是全局性质的,就覆盖了函数外的变量取值;要想函数外的生效,加“local”
3.4.3 递归函数
Shell 也可以实现递归函数,就是可以调用自己本身的函数。在 Linux 系统上编写 Shell脚本的时候,经常需要递归遍历系统的目录,列出目录下的文件和目录,逐层递归列出,并对这些层级关系进行展示。
3.5 Shell 数组
在 Shell 脚本中,数组是一种常见的数据结构,主要的应用场景包括:获取数组长度、获取元素长度、遍历元素、元素切片、元素替换、元素删除等等。Shell 中的数组与 Java、C、Python 不同,只有一维数组,没有二维数组。数组元素的大小与限制,也不需要事先定义。Shell 数组用括号()来表示,元素用空格分隔,元素的下标与大部分编程语言类似从 0 开始
注:列表与数组的写法非常类似
数组常用定义方法包括以下几种。
方法一:数组名=(value0 value1 value2 ...)
方法二:数组名=([0]=value [1]=value [2]=value ...)
方法三:列表名=”value0 value1 value2 ...” 数组名=($列表名)
方法四:数组名[0]=”value” 数组名[1]=”value” 数组名[2]=”value
操作:
(1)数组切片
*/@的区别
注:如果没有加引号,*/@输出的结果都是一样的;加了引号,结果就不一样了;
如果显示在了一行,代表“1 2 3 4 5 6 ”是同一个值,是一个整体
如果不是在同一行,以便利的方式把数字显示出来,每一行都是一个独立的结构;
故,显示数组的结果,用*/@视觉上是一样的,区别还是有的
总结:
(2)属组替换
注:替换仅仅是输出时替换,内容本身并没有替换
总结:
(3)数组的删除
3.6 Shell 脚本调试
在 Shell 脚本开发中,经常碰到一些规范方面的问题,例如忘了使用引号或在 if 语句末尾处忘记加 fi 结束。要注意把复杂的脚本简单化,要思路清晰,并且分段实现。当执行脚本时出现错误后,不要只看那些提示的错误行,而是要观察整个相关的代码段。
为避免编写的脚本出错,除了在编写脚本时注意书写规范,排除语法错误,更重要的是利用调试脚本工具来调试脚本。echo 命令是最有用的调试脚本工具之一,一般在可能出现问题的脚本中加入 echo 命令,采用的是分段排查的方式。除了 echo 命令之外,bash Shell 也有相应参数可以调试脚本。使用 bash 命令参数调试,命令的语法为:sh [-nvx] 脚本名
-n:不会执行该脚本,仅查询脚本语法是否有问题,如果没有语法问题就不显示任何内容,如果有问题会提示报错。
-v:在执行脚本时,先将脚本的内容输出到屏幕上然后执行脚本,如果有错误,也会给出错误提示。
-x:将执行的脚本内容输出到屏幕上,这个是对调试很有用的参数
当脚本文件较长时,可以使用 set 命令指定调试
操作: