首页 > 系统相关 >shell编程之循环语句与函数

shell编程之循环语句与函数

时间:2024-05-28 12:31:32浏览次数:26  
标签:语句 arr shell 编程 echo sh done root localhost

一:for循环语句

1:for循环语句的结构

for 变量名 in 取值列表

do

命令序列

done

注意:for循环语句需要有一个取值列表

备注:

for 语句的执行流程:首先将列表中的第一个取值赋给变量,并执行 do…done 循环体

中的命令序列;然后将列表中的第二个取值赋给变量,并执行循环体中的命令序列……依此

类推,直到列表中的所有取值用完,最后将跳至 done 语句,表示结束循环

2:案例 根据姓名列表批量添加用户

(1)创建用户的列表文件

[root@localhost ~]# vim /root/users.txt

zhangsan

lisi

wangwu

(2)编辑批量添加用户的脚本

[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 755 uaddfor.sh

测试并确认执行结果

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

[root@localhost ~]# tail -3 /etc/passwd

(3)编辑批量删除用户的脚本

[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 a+x udelfor.sh

测试并确认执行结果

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

[root@localhost ~]# id zhangsan

3:案例  根据 IP 地址列表检查主机状态

1)创建IP地址列表文件

[root@localhost ~]# vim /root/ipadds.txt

172.16.1.1

172.16.1.111

172.16.1.222

192.168.10.10

2)编辑循环检查各主机的脚本

[root@localhost ~]# vim chkhosts.sh

#!/bin/bash

HLIST=$(cat /root/ipadds.txt)

for IP in $HLIST

do

   ping -c 3 -i 0.2 -W 3 $IP &> /dev/null

   if [ $? -eq 0  ]

   then

      echo "Host $IP is up."

   else

      echo "Host $IP is down."

   fi

done

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

测试并确认执行结果

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

二:使用 while 循环语句

1:while语句的语法结构

while 条件测试操作

do

命令序列

done

备注:

while 语句的执行流程:首先判断 while 后的条件测试操作结果,如果条件成立,则执

行 do…done 循环体中的命令序列;返回 while 后再次判断条件测试结果,如果条件仍然成

立,则继续执行循环体;再次返回到 while 后,判断条件测试结果……如此循环,直到 while

后的条件测试结果不再成立为止,最后跳转到 done 语句,表示结束循环

2:案例  批量添加规律编号的用户

1)批量添加用户脚本

[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 a+x uaddwhile.sh

测试并确认执行结果

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

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

或者

#!/bin/bash

PREFIX="stu"

i=1

while [ $i -le 20 ]

do

    useradd ${PREFIX}$i

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

    i=`expr $i + 1`

done

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

测试并确认执行结果

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

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

2)批量删除用户脚本

[root@localhost ~]# vim udelwhile.sh

#!/bin/bash

PREFIX="stu"

i=1

while [ $i -le 20 ]

do

     userdel -r ${PREFIX}$i

     let i++

done

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

测试并确认执行结果

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

id stu20

3:案例  猜价格游戏

[root@localhost ~]# vim pricegame.sh

#!/bin/bash

PRICE=$(expr $RANDOM % 1000)

TIMES=0

echo "商品实际价格范围为0-999,猜猜看是多少?"

while true

do

    read -p "请输入你猜测的价格数目:" INT

    let TIMES++

    if [ $INT -eq $PRICE ] ; then

        echo "恭喜你答对了,实际价格是 $PRICE"

        echo "你总共猜测了$TIMES 次"

        exit 0

    elif [ $INT -gt $PRICE  ] ; then

        echo "太高了!"

    else

        echo "太低了!"

    fi

done

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

注意:linux中随机数的取值范围是0--32767,和什么数取余,取余后的最大数就是谁,不包含该数字

测试并确认执行结果

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

商品实际价格范围为0-999,猜猜看是多少?

请输入你猜测的价格数目:500

太高了!

......

三:until 循环语句

1:until 语句的结构

until 条件测试操作

do

done

备注:

until 语句的执行流程:首先判断 until 后的条件测试操作结果,如果条件不成立,则执

行 do…done 循环体中的命令序列;返回 until 后再次判断条件测试结果,如果条件仍然不

成立,则继续执行循环体;再次返回到 until 后,判断条件测试结果……如此循环,直到 until

后的条件测试结果成立为止,最后跳转到 done 语句

直到条件满足后才会停止循环

2:until语法案例

(1)案例一

[root@localhost ~]# vim 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

(1)案例二

[root@localhost ~]# vim until_v2.sh

var1=100

until [ $var1 -eq 0 ]

do

        echo $var1

        var1=$[ $var1 - 25 ]

done

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

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

四:Shell 函数

Shell 函数可用于存放一系列的指令。在 Shell 脚本执行的过程中,函数被置于内存中,

每次调用函数时不需要从硬盘读取,因此运行的速度比较快。在 Shell 编程中函数并非是必

须的元素,但使用函数可以对程序进行更好的组织。将一些相对独立的代码变成函数,可以

提高程序可读性与重用性,避免编写大量重复代码。

1:函数的用法

[function] 函数名() {

[return x]

}

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

2:案例  一个简单的函数脚本

[root@localhost ~]# vim exa1.sh

#!/bin/bash

zhangsan() {

echo "my name is zhangsan"

}

lisi() {

echo "my name is lisi"

}

zhangsan

lisi

[root@localhost ~]# sh exa1.sh

3:案例  带有参数的shell函数示例

[root@localhost ~]#vim exa2.sh

#!/bin/bash

name() {

echo "my name is $1"

}

name $1

[root@localhost ~]# sh exa2.sh zhangsan

my name is zhangsan

[root@localhost ~]# sh exa2.sh lisi

my name is lisi

4:案例 函数变量的作用范围

[root@localhost ~]# vim fun_scope.sh

myfun ()

{

local i

i=8

echo $i

}

i=9

myfun

echo $i

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

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

备注:

通过内置命令 local 将变量的值限定在函数内部。

五:Shell 数组

在 Shell 脚本中,数组是一种常见的数据结构,主要的应用场景包括:获取数组长度、

获取元素长度、遍历元素、元素切片、元素替换、元素删除等等。Shell 中的数组与 Java、

C、Python 不同,只有一维数组,没有二维数组。

1:定义数组的方法

数组常用定义方法包括以下几种。

方法一:

数组名=(

value0 value1 value2 ...)

方法二:

数组名=(

[0]=value [1]=value [2]=value ...)

方法三:

列表名=”value0 value1 value2 ...”

数组名=(

$列表名)

方法四:

数组名[0]=”value”

数组名[1]=”value”

数组名[2]=”value”

2:获取数组长度

[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

备注:

$* 和 $@ 都表示传递给函数或脚本的所有参数,我们已在《Shell特殊变量》一节中进行了演示,本节重点说一下它们之间的区别。

当 $* 和 $@ 不被双引号" "包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。

但是当它们被双引号" "包含时,就会有区别了:

"∗ " 会 将 所 有 的 参 数 从 整 体 上 看 做 一 份 数 据 , 而 不 是 把 每 个 参 数 都 看 做 一 份 数 据 。 " *"会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。 "∗"会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。

"@"仍然将每个参数都看作一份数据,彼此之间是独立的。

比如传递了 5 个参数,那么对于"∗ " 来 说 , 这 5 个 参 数 会 合 并 到 一 起 形 成 一 份 数 据 , 它 们 之 间 是 无 法 分 割 的 ; 而对于"@"来说,这 5 个参数是相互独立的,它们是 5 份数据。

[root@localhost ~]# vim aa

#!/bin/bash

echo "-- \$* 演示 ---"

for i in "$*"; do

echo $i

done

 

echo "-- \$@ 演示 ---"

for i in "$@"; do

echo $i

done

[root@localhost ~]# bash aa 1 2 3

3:读取某下标赋值

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

[root@localhost ~]# echo ${arr_number[2]}

//第三个元素

[root@localhost ~]# echo $arr_index2

3

echo ${aaa[3]}

4:数组遍历

[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

5:数组切片

[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

备注:

切片就是输出数组中指定连续的若干位,从第几位开始的往后几个数

6:数组替换

[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

7:数组删除

[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

标签:语句,arr,shell,编程,echo,sh,done,root,localhost
From: https://blog.csdn.net/weixin_71499831/article/details/139263222

相关文章

  • Shell编程之条件语句
    一:条件测试操作1:文件测试[root@localhost~]#[-d/media/cdrom]              \\-d,测试目录是否存在[root@localhost~]#echo$?0[root@localhost~]#[-d/media/cdrom/Server][root@localhost~]#echo$?0[root@localhost~]#[-d/medi......
  • Shell编程循环语句与函数
    Shell编程之循环语句与函数目录1.1for循环语句1.1.1for语句的结构1.1.2for语句应用示例1.2while循环语句1.3until循环语句1.3.1until语句的结构2.1Shell函数2.1函数应用示例2.2函数的作用范围2.3函数的参数2.4递归函数3.1Shell数组3.2Shell脚本测试一、循......
  • 【微机原理及接口技术】可编程并行接口芯片8255A
    【微机原理及接口技术】可编程并行接口芯片8255A文章目录【微机原理及接口技术】可编程并行接口芯片8255A前言一、8255A的内部结构和引脚1.与外设接口(数据端口)2.与处理器接口二、8255A的工作方式三、8255A的编程1.写入方式控制字:控制字格式2.读写数据端口3.读写端......
  • Java网络编程
    Java网络编程是Java编程中一个非常重要的领域,它为程序员提供了构建网络应用程序的能力。在当今互联网时代,网络应用程序无处不在,从简单的客户端-服务器通信到复杂的分布式系统,Java网络编程都扮演着关键角色。网络模型在探讨Java网络编程之前,让我们先了解一下计算机网......
  • 打开编程世界 跟着Mr.狠人一起学C/C++
    打开编程世界跟着Mr.狠人一起学C/C++自我介绍大家好,我是Mr.狠人。我高中就读于墨尔本,学习的方向是会计,因为疫情我回到国内读大学,大学的专业是国贸,可以说我没有任何的计算机基础。但我在海外研究生阶段毅然决然的选择了计算机专业,我本可以选择金融专业,或是更简单的管理专业......
  • 数据库初始,SQL语句介绍,MySQL数据库安装,SQL语句基础,操作MySQL数据库
    Ⅰ数据库初识【一】存储数据的演变过程【1】文件基于内存保存在早期,随意地存放到一个文件中、数据格式也是千差万别的,完全取决于个人员工管理系统是基于列表或字典(内存)存储数据【2】文件操作用本地的文本文件存储数据有的人喜欢存储到本地的一个文件中有的人喜欢存......
  • 小阿轩yx-Shell 编程规范与变量
    小阿轩yx-Shell编程规范与变量Shell脚本概述可以批量处理自动化地完成一系列维护任务大大减轻管理员的负担Shell的作用 命令解释器,翻译官,介于系统内核与用户之间,负责解释命令行用户登录Shell登录后默认使用的Shell程序,一般为/bin/bash不同Shell的内部指令、运行环境......
  • 关于软件开发模型(什么是结对编程?)
    结对编程是敏捷软件开发中的一种方法,它涉及两个程序员在同一台计算机上共同工作。这种方法的核心在于两个人的紧密协作,通常由一人负责输入代码,而另一人则审查这些代码,确保其正确性和可读性。结对编程它通过促进程序员之间的紧密合作,不仅提高了代码质量,还增强了团队的协作能力和适......
  • 编程语言和编程工具
    我了解和使用一些编程语言和编程工具编程语言:1.Java:Java是一种跨平台的面向对象编程语言,具有强大的生态系统和丰富的开发工具,适用于大型企业级应用和分布式系统开发2.C:C语言作为一种通用的、高效的编程语言,具有广泛的应用领域和良好的性能表现,但在使用时需要注意安全性和复杂......
  • 系统编程练习题----使用消息队列实现两个进程之间的通信
    目录题目思路代码展示进程A进程B结果展示题目要求进程A创建一条消息队列之后向进程B发送SIGUSR1信号,进程B收到该信号之后打开消息队列并写入一段信息作为消息写入到消息队列中,要求进程B在写入消息之后,发SIGUSR2信号给进程A,进程A收到该信号则从消息队列中读取消息并输出消息正文......