shell编程循环语句,数组


一:for循环语句
1.1:for循环语句应用案例
1.1.1:根据用户列表批量添加用户
1.1.2:判断192.168.10.0/24网段中主机状态
二:while循环语句
2.1:while语句应用案例
2.1.1:批量添加规律编号的用户
三:until循环语句
3.1:until语句应用案例
3.1.1:为指定用户发送在线消息
四:shell函数
4.1:函数变量的作用范围
4.2:函数的参数
4.3:递归函数
五:shell数组
5.1:获取数组的长度
5.2:获取数组的某一个下标
5.3:数组的遍历
5.4:数组的切片
5.5:数组的替换
5.6:删除数组
六:shell脚本调试
一:for循环语句
使用 for 循环语句时,需要指定一个变量及可能的取值列表,针对每个不同的取值重复执行相同的命令序列,直到变量值用完退出循环。在这里,“取值列表”称为 for 语句的执行条件,其中包括多个属性相同的对象,需要预先指定(如通讯录、IP 黑名单)。

for 循环语句的第一种语法结构如下所示:

for 变量名 in 取值列表
do
命令序列
done

for 循环语句的第二种语法结构如下所示:

for ((初始变量值;结束循环条件;运算))
do
命令序列
done

1.1:for循环语句应用案例
1.1.1:根据用户列表批量添加用户
[root@server data]# vim addusers.sh 
#!/bin/bash
list="tom harry jerry"
for i in $list
do
  useradd $i
  echo "123123" | passwd --stdin $i
done
[root@server data]# bash addusers.sh 

1.1.2:判断192.168.10.0/24网段中主机状态
[root@server data]# vim status.sh

#!/bin/bash
for ((i=1;i<=254;i++))
do
  ping -c2 -i0.2 -w3 192.168.10.$i &> /dev/null
  if [ $? -eq 0 ];then
    echo "192.168.10.$i is up"
  else
    echo "192.168.10.$i is down"
  fi
done

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

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

2.1:while语句应用案例
2.1.1:批量添加规律编号的用户
[root@server data]# vim addusers2.sh

#!/bin/bash
#批量添加stu1--stu20的用户
i=1
while [ $i -le 20 ]
do
  useradd stu$i
  echo "123123" | passwd --stdin $stu$i
  let i++
done

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

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

3.1:until语句应用案例
3.1.1:为指定用户发送在线消息
若用户不在(未登录系统),则每10s钟试一次,直至用户登录系统后在发送消息
用户名与消息通过位置参数传递给脚本

[root@server data]# vim until.sh
#!/bin/bash
username=$1
#格式参数不能为空
if [  $# -lt 1 ];then
  echo "usage:`basename $0` <username> [<message>]"
  exit 1
fi
#验证是否属于系统用户
if grep '^$username' /etc/passwd &> /dev/null;then :
else  
  echo "not user"
  exit 2
fi
#测试用户是否在线,如果不在线,每10s钟联系一次
until who | grep '$username' &> /dev/null;do
  echo "$username not login"
  sleep 10
done
#发送消息
echo "$2" | write "$username"
[root@server data]# bash until.sh tom hello

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

[function] 函数名() {undefined
命令序列
[return x]
}

“function”关键字表示定义一个函数,可以省略
“{”符号表示函数执行命令的入口,该符号可以与函数名同行也可以在函数名下一行 的句首
“}”符号表示函数体结束,两个大括号之间{ }是函数体
“命令序列”部分可以是任意的 Shell 命令,也可以调用其他函数
“return”表示退出函数返回一个退出值,通过返回值判断执行是否成功,也可以使用 exit 终止整个 Shell 脚本
Shell 函数调用的方法为:函数名 [参数 1] [参数 2]。

4.1:函数变量的作用范围
在 Shell 脚本中函数的执行并不会开启一个新的子 Shell,而是仅在当前定义的 Shell 环境中有效。如果 Shell 脚本中的变量没有经过特殊设定,默认在整个脚本中都是有效的。在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令 local 来实现。函数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响。

4.2:函数的参数
函数的参数的用法如下:

函数名称 参数 1 参数 2 参数 3 …

在使用函数参数时,函数名称在前参数在后,函数名和参数之间用空格分隔,可以有多个参数,参数使用$1、$2、3 … … 的 方 式 表 示 。 以 此 类 推 , 从 第 10 个 参 数 开 始 , 调 用 方 法 为 3……的方式表示。以此类推,从第 10 个参数开始,调用方法为3……的方式表示。以此类推,从第10个参数开始,调用方法为{10},不加大括号无法调用成功。

4.3:递归函数
Shell 也可以实现递归函数,就是可以调用自己本身的函数。在 Linux 系统上编写 Shell 脚本的时候,经常需要递归遍历系统的目录,列出目录下的文件和目录,逐层递归列出,并 对这些层级关系进行展示。
案例:递归列出/var/log目录下的所有目录

[root@server data]# vim hashu.sh

#!/bin/bash
function list_files(){
for v in `ls $1`
do
  #判断是否为目录
  if [ -d $1/$v ];then
    echo "$2$v"
    #递归调用
    list_files "$1/$v" " $2"
  else
    echo "$2$v"
  fi
done
}
list_files "/var/log" " "
[root@server data]# bash hashu.sh

五: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”

5.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

5.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

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.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

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

六:shell脚本调试
在 Shell 脚本开发中,经常碰到一些规范方面的问题,例如忘了使用引号或在 if 语句末尾处忘记加 fi 结束。要注意把复杂的脚本简单化,要思路清晰,并且分段实现。当执行脚本时出现错误后,不要只看那些提示的错误行,而是要观察整个相关的代码段。
为避免编写的脚本出错,除了在编写脚本时注意书写规范,排除语法错误,更重要的是 利用调试脚本工具来调试脚本。echo 命令是最有用的调试脚本工具之一,一般在可能出现问题的脚本中加入 echo 命令,采用的是分段排查的方式。
除了 echo 命令之外,bash Shell 也有相应参数可以调试脚本。使用 bash 命令参数调试,命令的语法为:

sh [-nvx] 脚本名

-n:不会执行该脚本,仅查询脚本语法是否有问题,如果没有语法问题就不显示任 何内容,如果有问题会提示报错
-v:在执行脚本时,先将脚本的内容输出到屏幕上然后执行脚本,如果有错误,也 会给出错误提示
-x:将执行的脚本内容输出到屏幕上,这个是对调试很有用的参数
 

#!/bin/bash
set -x    #开启调试模式
read -p "请输入您的分数(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]  then
  echo "$GRADE 分!优秀"
  set +x    #关闭调试模式
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ]  then
  echo "$GRADE 分,合格"
else
  echo "$GRADE 分,不合格"
fi

总结

for语句的结构

while语句的结构

until语句的结构

Shell函数定义方法

数组使用方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值