shell脚本之until语句和函数

shell脚本之until语句、函数和数组

一、until语句

1.1until语句结构

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

until 条件测试操作

do 命令序列

done

1.2until语句的应用

1.2.1通过循环累加的方式计算1-100的和
[root@localhost ~]# vim sum50.sh

#!/bin/bash
i=1
S=0
until [ $i -gt 100 ]
do
 let S+=$i
 let i++

done
echo "$S"
[root@localhost ~]# sh sum50.sh
5050
1.2.2 为制定用户发在线消息

具体要求

  • 若指定用户不在线(未登陆系统),则每5S试一次,直至用户登录系统后再发送信息
  • 用户名与消息通过为止参数传递给脚本
#!/bin/bash
username=$1
if [ $# -lt 1 ];
        then
        echo "usage:`basename $0` <username> [<message>]"
        exit
fi
if grep "^$username" /etc/passwd &> /dev/null;then :
else
        echo "not user"
        exit 2
fi
until who | grep "$username" &> /dev/null;do
        echo "user not login"
        sleep 5
done
echo "$2"|write "$username"
echo "${username}发送成功
[root@localhost ~]# vim hello.sh
[root@localhost ~]# sh hello.sh
usage:hello.sh <username> [<message>]
[root@localhost ~]# sh hello.sh lisi
not user
[root@localhost ~]# sh hello.sh liu

[root@localhost ~]# sh hello.sh liu
user not login
user not login
user not login
u[root@localhost ~]# sh hello.sh liu
liu发送成功ser not login

二、函数

2.1shell函数概述

  • shell一个非常重要的特性是它可作为一种编程语言来使用。
  • 因为shell是一个解释器,所以它不能对为它编写的程序进行编译,而是在每次从磁盘加载这
  • 程序时对它们进行解释。而程序的加载和解释都是非常耗时的。
  • 针对此问题,许多shell(如BourneAgainShell)都包含shell函数,shell把这些函数放在内存中,这样每次需要执行它们时就不必再从磁盘读入。
  • shell还以一种内部格式来存放这些函数,这样就不必耗费大量的时间来解释它们
  • shell函数将命令序列按格式写在一起
  • 可以方便重复使用命令序列

2.2shell函数定义

[fuction ] 函数名(){

       命令案例

       [return x]  

​ 使用return或者exit可以显示的结束函数

return返回的是状态码,需要使用$?调取

echo 返回的是值,使用变量调用

传参:指位置变量

可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。

参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。

2.3:调用函数的方法

函数名 [参数1($1)] [参数2($2)]
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数, 2 表 示 第 二 个 参 数 … 10 不 能 获 取 第 十 个 参 数 , 获 取 第 十 个 参 数 需 要 10 不 能 获 取 第 十 个 参 数 , 获 取 第 十 个 参 数 需 要 10 不 能 获 取 第 十 个 参 数 , 获 取 第 十 个 参 数 需 要 10 不 能 获 取 第 十 个 参 数 , 获 取 第 十 个 参 数 需 要 10 。 当 n > = 10 时 , 需 要 使 用 2表示第二个参数… 10不能获取第十个参数,获取第十个参数需要10不能获取第十个参数,获取第十个参数需要 10 不能获取第十个参数,获取第十个参数需要10不能获取第十个参数,获取第十个参数需要{10}。当n>=10时,需要使用 21010101010n>=10使{n}来获取参数。

2.4:shell函数应用

  • 两个数字求个

    ​ 通过sum(){}定义函数

    ​ 使用read命令交互输入两个数并求和

#!/bin/bsah
function sum () {
        read -p"请输入第一个整数;" num1
        read -p"请输入第二个整数;" num2
        SUM=$[$num1+$num2]
        echo "和:$SUM"
 }
sum

或者

#!/bin/bsah
function sum () {
        read -p"请输入第一个整数;" num1
        read -p"请输入第二个整数;" num2
        SUM=`expr $num1 + $num2 `
        echo "和:$SUM"
 }
sum

或者

function sum () {
        read -p"请输入第一个整数;" num1
        read -p"请输入第二个整数;" num2
        SUM=$(($num1+$num2))
        echo "和:$SUM"
        return 100
 }
sum   调用上面的函数体
echo $?  输出的是return 返回值100
末尾sum是函数名,作用是调用整个函数体

[root@localhost ~]# sh sum.sh
请输入第一个整数;12
请输入第二个整数;18
和:30
100

下面两个echo $?对比

#!/bin/bsah
function sum () {
        read -p"请输入第一个整数;" num1
        read -p"请输入第二个整数;" num2
        SUM=$(($num1+$num2))
        echo "和:$SUM"
        return 100
 }
number=`sum `  sum是echo返回值“和:$SUM"
        echo $?         输出的是上一条命令“ number=`sum ` ”状态码100
                        “ number=`sum ` ”是调用上面的函数体所有状态码和函数体状态码一样
 echo $number    

[root@localhost ~]# sh sum.sh
请输入第一个整数;12
请输入第二个整数;18
100  
和:30
#!/bin/bsah
function sum () {
        read -p"请输入第一个整数;" num1
        read -p"请输入第二个整数;" num2
        SUM=$(($num1+$num2))
        echo "和:$SUM"
        return 100
 }
number=`sum`
echo $number
echo $?       echo 输出的是上一条命令“echo $number"的执行状态码 

[root@localhost ~]# sh sum.sh
请输入第一个整数;12
请输入第二个整数;18
和:30
0            0表示“echo $number"正常执行

2.5函数的参数

2.5.1函数的用法

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

2.5.2参数的表示方法

$1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}…

2.5.3示例

参数求和

#!/bin/bsah
function sum () {

    SUM=$(($1+$2))
    echo "$SUM"
    return 100

 }
number=`sum 10 20`
let number+=1
echo $number

[root@localhost ~]# vim sum.sh
[root@localhost ~]# sh sum.sh 10 20


31
2.5.4local定义局部变量
#!/bin/bsah
function sum(){
        read -p"请输入第一个整数;" num1
        read -p"请输入第二个整数;" num2
        SUM=$[$num1+$num2]
        echo "$SUM"
         score=100
        echo "函数内$score"
 }
sum
echo "函数外$score"



[root@localhost ~]# sh sum.sh 10 20
请输入第一个整数;10
请输入第二个整数;20
30
函数内100
函数外100
#!/bin/bsah
function sum(){
        read -p"请输入第一个整数;" num1
        read -p"请输入第二个整数;" num2
        SUM=$[$num1+$num2]
        echo "$SUM"
        local score=100
        echo "函数内$score"
 }
sum
echo "函数外$score"
~    

[root@localhost ~]# vim sum.sh
[root@localhost ~]# sh sum.sh 10 20
请输入第一个整数;10
请输入第二个整数;20
30
函数内100
函数外

local定义后只在函数体内生效,函数体外不生效

2.5递归函数

调用自己本身的函数

示例

递归遍历目录

通过定义递归函数list_files来实现

#!/bin/bash
function list_files(){
    for f in `ls $1`
    do
        if [ -d "$1/$f" ];then
        echo "$2$f"
        list_files "$1/$f" " $2"
        else
         echo "$2$f"
        fi
    done

}
list_files "/var/log" " "
~                                                          
~                     

[root@localhost opt]# sh digui.sh
 anaconda
  anaconda.log
  ifcfg.log
  journal.log
  ks-script-B2lEaV.log
  packaging.log
  program.log
  storage.log
  syslog
  X.log
 audit
  audit.log

三、数组

3.1数组的概念

3.1.1数组:

放置相同类型数据的集合 [11,12,22,33,44]

数组实际是在内存中开辟了连续的空间

往往配合循环一起使用

3.1.2数组构成

数组名称 bac=(11,22,33,44)

数组元素11,22,33,44

数组的长度即数组元素个数

3.1.3数组下标

​ bac=(11,22,33,44)

​ 0 1 2 3

3.2数组的类型

  • 数值型
  • 字符型

3.3数组的定义方法

3.3.1方法一
数组名= (元素1 元素2 元素3 元素4)
[root@localhost ~]# num=(11 22 33 44 55)       
[root@localhost ~]# echo ${num[*]}    num 是数组名   *是代表数组的所有下标
11 22 33 44 55
3.3.2方法二
数组名= ([0]=元素1 [1]=元素2 [3]=元素3 [3]=元素4)
[root@localhost ~]# num=([0]=66 [1]=77 [2]=88 [3]=99)
[root@localhost ~]# echo ${num[*]}
66 77 88 99
[root@localhost ~]# echo ${num[@]}  *和@作用一样
66 77 88 99
3.3.3方法三

先定义给列表,再把列表元素赋予给数组

列表名=“元素1 元素2 元素3 元素4”

数组名=($列表名)  
[root@localhost ~]# list="1 2 3 4"
[root@localhost ~]# num=($list)
[root@localhost ~]# echo ${num[*]}
1 2 3 4
3.3.4方法四
数组名[0]=“元素"

数组名[1]=“元素

数组名[2]=“元素

主要用于替换,替换其中的元素

[root@localhost ~]# echo ${num[*]}
1 2 3 4
[root@localhost ~]# num[1]=80
[root@localhost ~]# echo ${num[*]}
1 80 3 4

3.3示例

3.3.1示例1

创建1-100的数组

#!/bin/bash
for ((i=0;i<=99;i++));do
 list[$i]=$[$i+1]
done
echo ${list[*]}

[root@localhost ~]# sh 100.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
3.3.2示例2

创建存放1-100奇数数组

#!/bin/bash
for ((i=0;i<=99;i+=2));do
 list[$i]=$[$i+1]
done
echo ${list[*]}
 [root@localhost ~]# sh 100.sh

1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99      

方法二

#!/bin/bash
k=0
j=1
for ((i=0;i<=99;i+=1));do
     k=$[$i+$j]
     let j++
     if [ $k -le 100 ];then
       jishu[$i]=$k
     fi
done
echo ${jishu[*]}
3.3.3示例3
创建任意数字及长度的数组,根据客户需求加入元素

#!/bin/bash
i=0
while true
do
  read -p"是否存入元素(yes/no):" choose
  if [ $choose == "no" ];then
     break
  fi
  read -p "请存入第$[$i+1]个元素;" key
  num[$i]=$key
    let i++
done
echo ${num[*]}

[root@localhost ~]# sh test05.sh
是否存入元素(yes/no):yes
请存入第1个元素;22
是否存入元素(yes/no):yes
请存入第2个元素;77
是否存入元素(yes/no):yes
请存入第3个元素;88
是否存入元素(yes/no):yes
请存入第4个元素;45
是否存入元素(yes/no):no
22 77 88 45

3.4数组操作长度

${数组名[*/@]}

[root@localhost ~]# echo ${a[*]}
1 2 3 4 5
[root@localhost ~]# b=${#a[*]}
[root@localhost ~]# echo $b
5

3.5数组遍历

格式

for  变量     in    数组

do 

  echo $变量

done
[root@localhost ~]# for v in ${a[*]}

> do
> echo $v
> done
> 1
> 2
> 3
> 4
> 5
3.5.1示例1

将数组中小于60的数变为60

#!/bin/bash
score=(40 50 59 60 70 80)
for ((i=0;i<${#score[*]};i++));do
  if [ ${score[i]} -lt 60 ];then
  score[$i]=60     直接将下标对应的元素替换
  fi
done
echo ${score[*]}



[root@localhost ~]# sh test06.sh
60 60 60 60 70 80

方法二

#!/bin/bash
score=(40 50 59 60 70 80)
for ((i=0;i<${#score[*]};i++));do
  if [ ${score[$i]} -lt 60 ];then
  new[$i]=60
  else
  new[$i]=${score[$i]}
  fi
done
echo ${new[*]}
3.5.2示例2

找出数组中最大的数值

#!/bin/bash
score=(40 50 59 60 70 80)
a=0
for ((i=0;i<${#score[*]};i++));do
  if [ ${score[$i]} -gt $a ];then
  a=${score[$i]}
  fi
done
echo $a

[root@localhost ~]# sh test06.sh
80

3.5.3示例3

降序排列

#!/bin/bash
score=(40 50 59 60 70 80)
for ((i=0;i<${#score[*]};i++));do
  for((j=i+1;j<${#score[*]};j++));do
  if [ ${score[$i]} -lt ${score[$j]} ];then

let a=${score[$j]}
let score[j]=${score[$i]}
let score[i]=a

   fi
   done
done
echo ${score[*]}
[root@localhost ~]# sh test06.sh
80 70 60 59 50 40

3.6数组切片

示例删除小于60的元素

#!/bin/bash
score=(55 66 77 44 88)
for((i=0;i<${#score[*]};i++));do
   if [ ${score[i]} -lt 60 ];then
      unset score[i]
   fi
done
echo ${score[*]}

上面这种方法看似正确,实际上有问题。因为在删除数组元素后,数组长度就出现了变化,肯会读不到对应的元素

下列方法能更准去的定位要删除的元素

#!/bin/bash
score=(55 66 77 44 88)
i=0
for v in ${score[*]};do
   if [ $v  -lt 60 ];then
      unset score[$i]
   fi
    let i++
    echo ${#score[*]}
done
echo ${score[*]}

[root@localhost ~]# sh tes04.sh
4
4
4
3
3
66 77 88

];then

let a=KaTeX parse error: Expected '}', got 'EOF' at end of input: {score[j]}
let score[j]=KaTeX parse error: Expected '}', got 'EOF' at end of input: {score[i]}
let score[i]=a

fi
done
done
echo ${score[*]}


[root@localhost ~]# sh test06.sh
80 70 60 59 50 40


### 3.6数组切片

示例删除小于60的元素

#!/bin/bash
score=(55 66 77 44 88)
for((i=0;i<${#score[]};i++));do
if [ ${score[i]} -lt 60 ];then
unset score[i]
fi
done
echo ${score[
]}


上面这种方法看似正确,实际上有问题。因为在删除数组元素后,数组长度就出现了变化,肯会读不到对应的元素

下列方法能更准去的定位要删除的元素

#!/bin/bash
score=(55 66 77 44 88)
i=0
for v in ${score[]};do
if [ v − l t 60 ] ; t h e n u n s e t s c o r e [ v -lt 60 ];then unset score[ vlt60];thenunsetscore[i]
fi
let i++
echo ${#score[
]}
done
echo ${score[*]}

[root@localhost ~]# sh tes04.sh
4
4
4
3
3
66 77 88












  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值