shell编程之循环语句与函数

一 、for循环语句

1.for循环语句意义

for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理。当要处理的数据有范围时,使用for循环语句就再适合不过了。

2.for循环语句结构

使用 for 循环语句时,需要指定一个变量及可能的取值列表,针对每个不同的取值重复 执行相同的命令序列,直到变量值用完退出循环。在这里,“取值列表”称为 for 语句的执行条 件,其中包括多个属性相同的对象,需要预先指定(如通讯录、IP 黑名单)。 for 循环语句的语法结构如下所示。

for 变量名 in 取值列表

do

命令序列

done

上述语句结构中,for 语句的操作对象为用户指定名称的变量,并通过 in 关键字为该变 量预先设置了一个取值列表,多个取值之间以空格进行分隔。位于 do…done 之间的命令序 列称为循环体,其中的执行语句需要引用变量以完成相应的任务。

for 语句的执行流程:首先将列表中的第一个取值赋给变量,并执行 do…done 循环体 中的命令序列;然后将列表中的第二个取值赋给变量,并执行循环体中的命令序列……依此 类推,直到列表中的所有取值用完,最后将跳至 done 语句,表示结束循环,如图所示

 3.for循环语句应用实例

根据人事部门给出的员工姓名的拼音列表,在 Linux 服务器中添加相应的用户账号,初 始密码均设置为“123456”。其中,员工姓名列表中的账号数量并不固定,而且除了要求账号 名称是拼音之外,并无其他特殊规律。

针对上述要求,可先指定员工列表文件 users.txt,然后编写一个名为 userfor.sh Shell 脚本,从 users.txt 文件中读取各用户名称,重复执行添加用户、设置初始密码的相关操作。

[root@localhost ~]# vim /root/users.txt                //用做测试的列表文件

chenye

dengchao

zhangjie

[root@localhost ~]# vim uaddfor.sh                //批量添加用户的脚本

#!/bin/bash

ULIST=$(cat /root/users.txt)

for UNAME in $ULIST

do

useradd $UNAME

echo "123456" | passwd --stdin $UNAME &>/dev/null

done

[root@localhost ~]# chmod +x uaddfor.sh

[root@localhost ~]# ./uaddfor.sh                 //测试并确认执行结果

[root@localhost ~]# tail -3 /etc/passwd                //查询最后三个账户名称信息

chenye:x:1005:1005::/home/chenye:/bin/bash

dengchao:x:1006:1006::/home/dengchao:/bin/bash

zhangjie:x:1007:1007::/home/zhangjie:/bin/bash

若要删除 uaddfor.sh 脚本所添加的用户,只需参考上述脚本代码,将 for 循环体中添加用户的命令序列改为删除用户的操作即可。例如,建立一个名为udelfor.sh 的脚本如下所示。

[root@localhost ~]# vim udelfor.sh                 //批量删除用户的脚本

#!/bin/bash

ULIST=$(cat /root/users.txt)

for UNAME in $ULIST

do

userdel -r $UNAME &>/dev/null

done

[root@localhost ~]# chmod +x udelfor.sh

[root@localhost ~]# ./udelfor.sh                 //测试并确认执行结果

[root@localhost ~]# id chenye

id: chenye: no such user                 //提示无此用户

二、while循环语句

1.while循环语句的意义

重复测试某个条件,只要条件成立,则反复执行

2.while循环语句的结构

使用 while 循环语句时,可以根据特定的条件反复执行一个命令序列,直到该条件不再 满足时为止。在脚本应用中,应该避免出现死循环的情况,否则后边的命令操作将无法执行。 因此,循环体内的命令序列中应包括修改测试条件的语句,以便在适当的时候使测试条件不 再成立,从而结束循环。 while 循环语句的语法结构如下所示。

while 条件测试操作

do

命令序列

done

while 语句的执行流程:首先判断 while 后的条件测试操作结果,如果条件成立,则执 行 do…done 循环体中的命令序列;返回 while 后再次判断条件测试结果,如果条件仍然成 立,则继续执行循环体;再次返回到 while 后,判断条件测试结果……如此循环,直到 while 后的条件测试结果不再成立为止,最后跳转到 done 语句,表示结束循环,如图所示。

使用 while 循环语句时,有两个特殊的条件测试操作,即 true(真)和 false(假)。使 用 true 作为条件时,表示条件永远成立,循环体内的命令序列将无限执行下去,除非强制终止脚本(或通过 exit 语句退出脚本);反之,若使用 false 作为条件,则循环体将不会被执行。这两个特殊条件也可以用在 if 语句的条件测试中。

3.while语句应用实例

在一些技术培训和学习领域,出于实验或测试的目的,需要批量添加用户账号,这些用 户的名称中包含固定的前缀字串,并按照数字顺序依次进行编号,账号的数量往往也是固定 的。例如,若要添加 20 个用户,名称依次为 stu1stu2stu20,可以参考以下操作。

[root@localhost ~]# vim uaddwhile.sh                 //批量添加用户的脚本

#!/bin/bash

PREFIX="stu"

i=1

while [ $i -le 20 ]

do

useradd ${PREFIX}$i

echo "123456" | passwd --stdin ${PREFIX}$i &> /dev/null

let i++

done

[root@localhost ~]# chmod +x uaddwhile.sh

上述脚本代码中,使用变量 i 来控制用户名称的编号,初始赋值为 1,并且当取值大于 20 时终止循环。在循环体内部,通过语句“let i++”(等同于 i=`expr $i + 1`)来使变量 i 的值 增加 1,因此当执行第一次循环后 i 的值将变为 2,执行第二次循环后 i 的值将变为 3……,依此类推。 测试并确认 uaddwhile.sh 脚本的执行结果如下所示。

[root@localhost ~]# ./uaddwhile.sh

[root@localhost ~]# grep "stu" /etc/passwd | tail -3

stu18:x:1022:1022::/home/stu18:/bin/bash

stu19:x:1023:1023::/home/stu19:/bin/bash

stu20:x:1024:1024::/home/stu20:/bin/bash

若要删除 uaddwhile.sh 脚本所添加的用户,只需参考上述脚本代码,将 while 循环体中添加用户的命令序列改为删除用户的操作即可。

[root@localhost ~]# vim udelwhile.sh                 //批量删除用户的脚本

#!/bin/bash

PREFIX="stu"

i=1

while [ $i -le 20 ]

do

userdel -r ${PREFIX}$

let i++

done

[root@localhost ~]# chmod +x udelwhile.sh

[root@localhost ~]# ./udelwhile.sh                 //测试并确认执行结果

[root@localhost ~]# id stu20

id: stu20:无此用户                 //提示无此用户

三、until循环语句

1.until循环语句的意义

重复测试某个条件,只要条件不成立则反复执行

2.until语句的结构

until 循环与 while 循环类似,while 循环能实现的脚本 until 同样也可以实现,但区别是 while 循环在条件为真是继续执行循环,而 until 则是在条件为假时执行循环。until 循环语句的语法结构如下所示。

until 条件测试操作
do
    命令序列
done

until 语句的执行流程:首先判断 until 后的条件测试操作结果,如果条件不成立,则执行 do…done 循环体中的命令序列;返回 until 后再次判断条件测试结果,如果条件仍然不成立,则继续执行循环体;再次返回到 until 后,判断条件测试结果……如此循环,直到 until后的条件测试结果成立为止,最后跳转到 done 语句,表示结束循环,如图所示。

3.until 语句应用示例

在一些科学计算领域,经常会用到各种数的计算,自然数的求和操作是最简单的。本例中计算从 1 50 的和,从 1 开始相加,采用循环的方式,每次循环后加 1,将得到的值加入计算的和中,数字运算采用的是 let 方式,直到加到 50 为止,具体的操作参考如下。

[root@localhost ~]# vim sum1to50_until_v1.sh

#!/bin/bash

i=0;s=0

until [ $i -eq 50 ]

do

let "i=$i+1";let "s=$s+$i"

done

echo 'sum(1..50)='$s

[root@localhost ~]# chmod +x sum1to50_until_v1.sh

[root@localhost ~]# ./sum1to50_until_v1.sh

sum(1..50)=1275

上述代码中,在 i 的值小于 50 之前,每次循环 i 的值加 1,并且求出 s 的值。

四、shell函数

1.函数概念

Shell 函数可用于存放一系列的指令。在 Shell 脚本执行的过程中,函数被置于内存中,每次调用函数时不需要从硬盘读取,因此运行的速度比较快。在 Shell 编程中函数并非是必须的元素,但使用函数可以对程序进行更好的组织。将一些相对独立的代码变成函数,可以提高程序可读性与重用性,避免编写大量重复代码。

2.函数定义方法

Shell 函数定义的方法如下所示:

[function] 函数名() {

命令序列

[return x]

}

“function”关键字表示定义一个函数,可以省略;

“{”符号表示函数执行命令的入口,该符号可以与函数名同行也可以在函数名下一行的句首;

“}”符号表示函数体结束,两个大括号之间{ }是函数体;

命令序列部分可以是任意的 Shell 命令,也可以调用其他函数;

“return”表示退出函数返回一个退出值,通过返回值判断执行是否成功,也可以使用 exit 终止整个 Shell 脚本。

Shell 函数调用的方法为:函数名 [参数 1] [参数 2]

3.函数定义用法

两个数求和:使用 Shell 脚本实现两个数相加求和,通过定义函数的方式来完成。sum函数内部通过read 命令接收用户分别输入的两个数,然后做加法运算,最后通过调用函数的方式来输出两个数的和

[root@localhost ~]# vim sum.sh

#!/bin/bash

sum(){

read -p "请输入第一个数:" NUM1

read -p "请输入第二个数:" NUM2

echo “你输入的两个数为: $NUM1 $NUM2.”

SUM=$(( NUM1+$NUM2))

echo “两个数的和为: $SUM”

}

sum

[root@localhost ~]# chmod +x sum.sh

[root@localhost ~]# ./sum.sh

请输入第一个数:2

请输入第二个数:3

你输入的两个数为: 2 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)获取数组长度

[root@localhost ~]# arr_number=(1 2 3 4 5)

[root@localhost ~]# arr_length=${#arr_number[*]}

[root@localhost ~]# echo $arr_length

5

[root@localhost ~]# arr_length_1=${#arr_number[@]}

[root@localhost ~]# echo $arr_length_1

5

2)读取某下标赋值

[root@localhost ~]# arr_index2=${arr_number[2]}                 //第三个元素

[root@localhost ~]# echo $arr_index2

3

3)数组遍历

[root@localhost ~]# vim array_traverse.sh

#!/bin/bash

arr_number=(1 2 3 4 5)

for v in ${arr_number[@]}

do

echo $v

done

[root@localhost ~]# chmod +x array_traverse.sh

[root@localhost ~]# ./array_traverse.sh

1

2

3

4

5

4)数组切片

[root@centos-7 ~]# arr=(1 2 3 4 5)

[root@centos-7 ~]# echo ${arr[@]}                 //输出整个数组

1 2 3 4 5

[root@centos-7 ~]# echo ${arr[@]:0:2}                 //${数组名[@或*]:起始位置:长度}

1 2

[root@centos-7 ~]# echo ${arr[@]:2:3}

3 4 5

将数组切片之后,返回的是字符串,以空格作为分隔符

5)数组替换

[root@centos-7 ~]# arr=(1 2 3 4 5)

[root@centos-7 ~]# echo ${arr[@]/4/66}                 //${数组名[@或*]/查找字符/替换字符}

1 2 3 66 5

[root@centos-7 ~]# echo ${arr[@]}                 //并不会替换数组原有内容

1 2 3 4 5

[root@centos-7 ~]# arr=(${arr[@]/4/66})                 //要实现改变原有数组,可通过重新赋值实现

[root@centos-7 ~]# echo ${arr[@]}

1 2 3 66 5

6)数组删除

[root@centos-7 ~]# arr=(1 2 3 4 5)

[root@centos-7 ~]# unset arr                 //删除数组

[root@centos-7 ~]# echo ${arr[*]}

[root@centos-7 ~]# arr=(1 2 3 4 5)

[root@centos-7 ~]# unset arr[2]                 //删除第三个元素

[root@centos-7 ~]# echo ${arr[*]}

1 2 4 5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值