shell脚本——函数、数组

shell脚本——函数、数组

一、util

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

格式

util  [ 条件格式操作 ]
do
   命令序列
done

案例一:1-50求和

#!/bin/bash
i=1
sum=0
until [ $i -eq 51 ]
  do
  sum=$[$sum+$i]
let i++
done
echo "$sum"
            

验证

[root@localhost data]# sh util.sh 
1275
[root@localhost data]# 

案例二:指定用户发送信息

在这里插入图片描述

方法一

[root@localhost shell]# vim zhidingusr.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 "no user"
        exit 2   //返回值用于验证,无太大意义
fi
#测试用户是否在线,如果不在线,每5s联系一次
until who | grep "$username" > /dev/null;do
        echo "user not login"
        sleep 5
done
#发送消息
echo "$2" | write "$username"
echo "${username}发送成功"

验证

[root@localhost ~]# sh zhidingusr.sh  zhangsan iiop
zhangsan发送成功

方法二


[root@localhost shell]# vim zdjyonghu.sh
#!/bin/bash
read -p "请输入你要联系的用户名:" a
 if grep $a /etc/passwd >/dev/null
 then
   echo "当前用户在系统中,正在测试是否在线"
   if who | grep $a > /dev/null
    then
      read -p "该用户在线,输入消息:" b
      echo $b | write $a
      echo "消息:$b 发送成功"
   else
    echo "该用户不在线"
    until who | grep $a > /dev/null
     do
      sleep 2
      echo "正在尝试联系该用户"
     done
      read -p "该用户已上线,输入消息:" b
      echo $b | write $a
      echo "消息发送成功"
   fi
 else
   echo "没有该用户"
 fi

验证

[root@localhost shell]# sh zdjyonghu.sh 
请输入你要联系的用户名:zhangsan
当前用户在系统中,正在测试是否在线
该用户不在线
正在尝试联系该用户
正在尝试联系该用户
正在尝试联系该用户
正在尝试联系该用户
^C
[root@localhost shell]# sh zdjyonghu.sh 
请输入你要联系的用户名:zhangsan
当前用户在系统中,正在测试是否在线
该用户在线,输入消息:ueiox
消息:ueiox 发送成功

在这里插入图片描述

案例三:数值求和

[root@localhost shell]# vim hansu.sh

#!/bin/bash
#求和函数体
function sum (){
        #命令序列
        read -p "请输入第一个整数:" num1
        read -p "请输入第一个整数:" num2
        SUM=$[$num1+$num2]
        #echo 返回的是处理结果值
        echo $SUM
        #return 返回的是状态码
        return 100
}
number=`sum`
echo $?
echo $number

[root@localhost shell]# sh hansu.sh 
请输入第一个整数:10
请输入第一个整数:20
100
30



二、函数

  • 将命令序号按格式写在一起
  • 可方便重复使用命令序列
  • shell函数定义

格式
shell函数的定义


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


调用函数参数的方法


函数名 [ 参数1 ] [ 参数2 ]

num=(11 22 33 44 55 66 77)

函数的长度表示 : num_length=${#num[*]}

案例一:两个数值求和

调用参数

#!/bin/bash
#求和函数体
function sum (){
        #命令序列
       #read -p "请输入第一个整数:" num1
       #read -p "请输入第一个整数:" num2
        SUM=$[$1+$2]
        #echo 返回的是处理结果值
        echo $SUM
        #return 返回的是状态码
        return 100
}
number=`sum 10 20`
echo $?
echo $number

验证

[root@localhost shell]# sh hansu.sh 
请输入第一个整数:10
请输入第一个整数:20
100
30

案例二:全局变量和局部变量验证

  • 函数内定义的local变量,只能在函数内使用。全局变量可以在全局使用。
  • shell脚本默认变量是全局有效的。
  • 用户环境变量 ~.bashrc _profile
  • 系统环境变量 /etc/profile
#!/bin/bash
function sum(){
        read -p "请输入第一个整数:" num1
        read -p "请输入第二个整数:" num2
        SUM=$[$num1 + $num2]
        local score=70
        echo "$SUM"
        echo "局部数值:$score"
}
sum

echo "全局数值:$score"
                       

验证

[root@localhost shell]# vim local.sh
[root@localhost shell]# sh local.sh 
请输入第一个整数:10
请输入第二个整数:30
40
局部数值:70
全局数值:

案例二:在用户环境变量文件中添加自定义函数并调用

[root@localhost ttyy]# vim .bash_profile 

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

#!/bin/bash
function sum(){
        read -p "请输入第一个整数:" num1
        read -p "请输入第二个整数:" num2
        SUM=$[$num1 + $num2]
        local score=70
        echo "$SUM"
        echo "局部数值:$score"
}


# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH  


---------验证----------
[root@localhost ttyy]# source .bash_profile 
[root@localhost ttyy]# sum
请输入第一个整数:10
请输入第二个整数:20
30
局部数值:70


三、递归函数

调用自己本身的函数

案例一:递归调用显示/var/log目录的所有文件

[root@localhost shell]# vim digui.sh

#!/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 shell]# sh digui.sh 
anaconda
 anaconda.log
 ifcfg.log
 journal.log
 ks-script-RVBEet.log
 packaging.log
 program.log
 storage.log
 syslog
 X.log
audit
 audit.log
boot.log
boot.log-20200716
boot.log-20200717
boot.log-20200719
boot.log-20200720
boot.log-20200721
btmp
chrony
cron
cron-20200719
cups
 access_log
 access_log-20200719
 error_log
 page_log
dmesg
dmesg.old
firewalld
gdm
 :0-greeter.log
 :0-greeter.log.1
 :0-greeter.log.2
 :0-greeter.log.3
 :0-greeter.log.4
 :0.log
 :0.log.1
 :0.log.2
 :0.log.3
 :0.log.4
 :1-greeter.log
 :1.log
glusterfs
grubby_prune_debug
lastlog
libvirt
 qemu
maillog
maillog-20200719
messages
messages-20200719
ntpstats
pluto
 peer
ppp
qemu-ga
rhsm
sa
 sa15
 sa16
 sa17
 sa18
 sa19
 sa20
 sa21
 sar15
 sar16
 sar17
 sar20
samba
 old
secure
secure-20200719
speech-dispatcher
spooler
spooler-20200719
sssd
swtpm
 libvirt
  qemu
tallylog
tuned
 tuned.log
vmware-network.1.log
vmware-network.2.log
vmware-network.3.log
vmware-network.4.log
vmware-network.5.log
vmware-network.6.log
vmware-network.7.log
vmware-network.8.log
vmware-network.9.log
vmware-network.log
vmware-vgauthsvc.log.0
vmware-vmsvc.log
vmware-vmusr.log
wpa_supplicant.log
wtmp
xferlog
Xorg.0.log
Xorg.0.log.old
Xorg.1.log
Xorg.9.log
yum.log

shell脚本数值取绝对值

在这里插入图片描述

四、数组

数组:相同类型数据的集合

[11,22,33,44] 在内存中开辟了连续的空间
配合循环使用

数组名称:arr arr=(11,22,33,44) 索引
0 1 2 3
数组元素: 11 22 33 44

数组的长度: 4

数组下标: 33元素的下标值是2

for 临时变量 in 数组
do

done

1. 数组的切片

格式

${数组名[@/*]:起始位置:长度}

案例

[root@localhost shell]# arr=(1 2 4 5)
[root@localhost shell]# echo ${arr[@]:1:3}  //数组切片
2 4 5
[root@localhost shell]# echo ${arr[*]/4/99}
1 2 99 5
[root@localhost shell]# arr=(${arr[*]/4/99})  //从数组中替换
[root@localhost shell]# echo ${arr[*]}
1 2 99 5
[root@localhost shell]# 
[root@localhost shell]# unset arr[3]   //删除单个元素
[root@localhost shell]# echo ${arr[*]}
1 2 99
[root@localhost shell]# 
[root@localhost shell]# unset arr   //删除整个数组
[root@localhost shell]# echo ${arr[*]}

2. 数组的替换

格式

${数组名[@/*]/查找字符/替换字符}

3.数组的删除

unset

案例

五、shell 脚本调试

1. echo 命令

2. bash 命令

命令语法

sh [-nvx] 脚本名

常用选项

-n -v -x

[root@localhost shell]# sh -nvx bujigeshanchu.sh
#!/bin/bash
 num=(56 76 67 55 32 10)
 for (( i=0;i<=5;i++))
  do
        if [ ${num[$i]} -lt 60 ]
        then
          unset num[$i]
        fi
   done
echo ${num[*]}


[root@localhost shell]# sh -x bujigeshanchu.sh 
+ num=(56 76 67 55 32 10)
+ (( i=0 ))
+ (( i<=5 ))
+ '[' 56 -lt 60 ']'
+ unset 'num[0]'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 76 -lt 60 ']'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 67 -lt 60 ']'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 55 -lt 60 ']'
+ unset 'num[3]'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 32 -lt 60 ']'
+ unset 'num[4]'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 10 -lt 60 ']'
+ unset 'num[5]'
+ (( i++ ))
+ (( i<=5 ))
+ echo 76 67
76 67
[root@localhost shell]# sh -n bujigeshanchu.sh 
[root@localhost shell]# sh -v bujigeshanchu.sh 
#!/bin/bash
 num=(56 76 67 55 32 10)
 for (( i=0;i<=5;i++))
  do
        if [ ${num[$i]} -lt 60 ]
        then
          unset num[$i]
        fi
   done
echo ${num[*]}
76 67


3. set 命令

  • set -x : 开启调节模式
  • set +x : 关闭调节模式

***********方法一*****************

[root@localhost shell]# num=(11 22 33)
[root@localhost shell]# echo ${num[*]}
11 22 33
[root@localhost shell]# echo ${num[2]}
33
[root@localhost shell]# echo ${num[0]}
11
[root@localhost shell]# 


***********方法二******************

[root@localhost shell]# num1=([0]=12 [1]=77 [2]=88 [3]=99)
[root@localhost shell]# echo ${num1[@]}
12 77 88 99
[root@localhost shell]# echo ${num[@]}
11 22 33
[root@localhost shell]# echo ${num1[*]}
12 77 88 99
[root@localhost shell]# 


************方法三******************

[root@localhost shell]# num2="11 22 33 44"
[root@localhost shell]# num=($num2)
[root@localhost shell]# echo ${num[*]}
11 22 33 44
[root@localhost shell]# 

案例一:输出数组100元素

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


验证
[root@localhost shell]# sh shuzu.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
[root@localhost shell]# 


案例二:输出奇数数组

在这里插入图片描述

[root@localhost shell]# vim jisu.sh 
#!/bin/bash

k=0
j=1
for (( i=0;i<=99;i++ ))
do
        k=$[$i+$j]
        let j++
        if [ $k -le 100 ];then
        num[$i]=$k
        fi
done
        echo ${num[*]}


验证

[root@localhost shell]# sh jisu.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
i=0
while [ 1 ];do
  if [ $i != 0 ];then
    read -p "是否继续输入y/n?" is
    if [ $is = "n" ];then
        break
    fi
  fi
  read -p "请输入新数据元素?" num
  sum[$i]=$num
  let i++
done
echo ${sum[*]}

验证

请输入新数据元素?32
是否继续输入y/n?y
请输入新数据元素?5
是否继续输入y/n?y
请输入新数据元素?3
是否继续输入y/n?n
32 5 3

案例四:将小于60的分数,变为60

方法一

[root@localhost shell]# vim bujige.sh

#!/bin/bash
 num=(56 76 67 55 32 87)
 for (( i=0;i<=5;i++))
  do
        if [ $[num[$i]] -lt 60 ]
        then
          num[$i]=60
        fi
   done
echo ${num[*]}



验证
[root@localhost shell]# sh bujige.sh 
60 76 67 60 60 87

方法二

#!/bin/bash
 num=(56 76 67 55 32 87)
 for (( i=0;i<${#num[*]};i++))
  do
        if [ ${num[$i]} -lt 60 ]
        then
          num[$i]=60
        fi
   done
echo ${num[*]}

验证
[root@localhost shell]# sh bujige.sh 
60 76 67 60 60 87



案例五:输出最大值


#!/bin/bash
num=(89 30 40 76 100)
max=0
for (( i=0;i<${#num[*]};i++))
        do
      if [ ${num[$i]} -gt $max ]; then
         max=${num[$i]}
      fi
done
echo $max
        
验证
[root@localhost shell]# sh max-1.sh 
100


案例六:插入法排序-升序

[root@localhost shell]# vim sort.sh 

#!/bin/bash

a=(98 23 45 67 7 8 99)
k=${#a[*]}
for (( i=1;i<$k;i++ ))
 do
   if [ ${a[$i]} -lt ${a[$i-1]} ]
     then
      let temp=${a[$i]}         ////保存要比较的值
        for (( j=$i-1; j>=0;j--))   
          do
           if [ ${a[j]} -gt $temp ]  ////从后向前查找待插入位置
           then
           let a[$j+1]=a[$j]  //挪位
           else
            break
           fi
           done
        let a[$j+1]=$temp     ////复制到插入位置
fi
done
echo ${a[*]}

**验证**
[root@localhost shell]# sh sort.sh 
7 8 23 45 67 98 99

               

案例七:插入法排序-降序

#!/bin/bash

a=(98 23 45 67 7 8 99)
k=${#a[*]}
for (( i=1;i<$k;i++ ))
 do
   if [ ${a[$i]} -gt ${a[$i-1]} ]
     then
      let temp=${a[$i]}
        for (( j=$i-1; j>=0;j--))
          do
           if [ ${a[j]} -lt $temp ]
           then
           let a[$j+1]=a[$j]
           else
            break
           fi
           done
        let a[$j+1]=$temp
fi
done
echo ${a[*]}

验证
[root@localhost shell]# sh sort.jiaxu.sh
99 98 67 45 23 8 7




案例八:冒泡法排序

[root@localhost shell]# vim sort-maopao.sh

#!/bin/bash

a=(55 66 11 33 99)
k=${#a[*]}
for ((i=0;i<$k;i++))
 do
    temp=1
   for (( j=1;j<=$[$k-$i];j++ ))
        do
             if [ ${a[$j]} -lt  ${a[$j-1]} ]
           then
            tem=${a[$j]}
            a[$j]=${a[$j-1]}
            a[$j-1]=$tem
            temp=0
           fi
     done
      if [ $temp -eq 1 ]
       then
         break
       fi

done
echo ${a[*]}


**********验证**********

[root@localhost shell]# sh sort-maopao.sh 
11 33 55 66 99


在这里插入图片描述

案例九:删除数组中小于60的数值

[root@localhost shell]# vim bujigeshanchu.sh
#!/bin/bash
 num=(56 76 67 55 32 87)
 for (( i=0;i<${#num[*]};i++))
  do
        if [ ${num[$i]} -lt 60 ]
        then
          unset num[$i]
        fi
   done
echo ${num[*]}

*********验证*****************

[root@localhost shell]# sh bujigeshanchu.sh 
76 67 32 87


方法二
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42099301/article/details/107464096