zoukankan      html  css  js  c++  java
  • shell编程 13 --- shell 数组的应用实践

    shell编程 13 --- shell 数组的应用实践

    13.1 shell数组介绍


    数组的概念:

    简单地说, Shell的数组就是一个元素集合,它把有限个元素(变量或字符内容)用一个名字来命名,然后用编号对它们进行区分。这个名字就称为数组名,用于区分不同内容的编号就称为数组下标。组成数组的各个元素(变量)称为数组的元素,有时也称为下标变量。

    有了Shell数组之后,就可以用相同名字来引用一系列变量及变量值了,并通过数字(索引)来识别使用它们。在很多场合中,使用数组可以缩短和简化程序开发。


    13.2 shell数组的定义与增删改查

    13.2.1 shell数组的定义

    Shell数组的定义有多种方法,列举如下。

    方法1:用小括号将变量值括起来赋值给数组变量,每个变量值之间要用空格进行分隔。语法如下:

    推荐使用

    array=(value1 value2 value3 value4 ...)
    ## 实例:
    [root@zabbix 0514]# array=(1 2 3)
    [root@zabbix 0514]# echo ${array[*]} 
    1 2 3
    

    **方法2:用小括号将变量值括起来,同时采用键值对的形式赋值。**语法如下:

    此方法比较复杂,不推荐使用

    [root@zabbix 0514]# array=([1]=one [2]=two [3]=three)
    [root@zabbix 0514]# echo ${array[*]}
    one two three
    [root@zabbix 0514]# echo ${array[1]}
    one
    [root@zabbix 0514]# echo ${array[2]}
    two
    [root@zabbix 0514]# echo ${array[3]}
    three
    
    

    方法3:通过分别定义数组变量的方法来定义。语法如下:

    此方法比较复杂,不推荐使用

    [root@zabbix 0514]# array[0]=a;array[1]=b;array[2]=c;
    [root@zabbix 0514]# echo ${array[*]}
    a b c
    

    方法4:动态地定义数组变量,并使用命令的输出结果作为数组的内容。语法为:

    array=($(命令)) 或 array=(`命令`)
    

    实例:

    [root@zabbix 0514]# mkdir array
    [root@zabbix 0514]# touch array/{1..3}.txt
    [root@zabbix 0514]# ll array/
    total 0
    -rw-r--r-- 1 root root 0 May 14 10:06 1.txt
    -rw-r--r-- 1 root root 0 May 14 10:06 2.txt
    -rw-r--r-- 1 root root 0 May 14 10:06 3.txt
    [root@zabbix 0514]# array=($(ls array/))
    [root@zabbix 0514]# echo ${array[*]}
    1.txt 2.txt 3.txt
    

    13.2.2 Shell数组的打印和输出

    13.2.2.1.打印数组元素
    [root@zabbix 0514]# array=(one two three four) 		== 定义数组
    [root@zabbix 0514]# echo ${array[1]}				== 打印单个元素
    two
    [root@zabbix 0514]# echo ${array[0]}				== 数组下标从0开始
    one
    [root@zabbix 0514]# echo ${array[*]}	
    one two three four
    [root@zabbix 0514]# echo ${array[@]}				== 使用*和@可以得到整个数组元素
    one two three four
    [root@zabbix 0514]#
    
    13.2.2.2.打印数组元素的个数
    # 用${#数组名[*]} 或 ${#数组名[@]} 可以得到数组长度
    [root@zabbix 0514]# echo ${array[*]}
    one two three four
    [root@zabbix 0514]# echo ${#array[*]}
    4
    [root@zabbix 0514]# echo ${array[@]}
    one two three four
    [root@zabbix 0514]# echo ${#array[@]}
    4
    
    13.2.2.3.数组赋值

    可直接通过“数组名[下标]”对数组进行引用赋值,如果下标不存在,则自动添加一个新的数组元素, 如果下标存在,则覆盖原来的值。

    [root@zabbix 0514]# array=(one two three four)
    [root@zabbix 0514]# echo ${array[@]}
    one two three four
    [root@zabbix 0514]# echo ${array[0]}
    one
    [root@zabbix 0514]# array[0]=moox		==> 修改数组元素,覆盖先前元素
    [root@zabbix 0514]# echo ${array[0]}	
    moox
    [root@zabbix 0514]# echo ${array[@]}
    moox two three four
    [root@zabbix 0514]# echo ${array[4]}
    
    [root@zabbix 0514]# array[4]=new		==> 赋值新元素
    [root@zabbix 0514]# echo ${array[4]}
    new
    
    13.2.2.4.数组的删除

    因为数组本质上还是变量,因此可通过“unset数组[下标]”清除相应的数组元素, 如果不带下标,则表示清除整个数组的所有数据。

    [root@zabbix 0514]# echo ${array[*]}
    moox two three four new
    [root@zabbix 0514]# unset array[1]
    [root@zabbix 0514]# echo ${array[*]}
    moox three four new
    [root@zabbix 0514]# unset array
    [root@zabbix 0514]# echo ${array[*]}
    
    [root@zabbix 0514]# 
    
    13.2.2.5.数组内容的截取、替换和删除

    这里和前文变量子串的替换是一样的,因为数组是特殊的变量。 数组元素部分的内容截取的示例如下:

    [root@zabbix 0514]# array=(1 2 3 4 5)
    [root@zabbix 0514]# echo ${array[@]:1:3}
    2 3 4
    [root@zabbix 0514]# array=($(echo {a..z}))
    [root@zabbix 0514]# echo ${array[@]}
    a b c d e f g h i j k l m n o p q r s t u v w x y z
    [root@zabbix 0514]# echo ${array[@]:4:5}
    e f g h i
    =========================================================
    说明:echo ${array[@]:4:5}截取时,4表示数组下标开始的位置,5表示截取的长度,如:
    [root@zabbix 0514]# echo ${array[@]:4:1}
    e
    

    替换数组元素部分内容的代码如下:

    [root@zabbix 0514]# array=(1 2 3 1 1)
    [root@zabbix 0514]# echo ${array[*]}
    1 2 3 1 1
    [root@zabbix 0514]# echo ${array[*]/1/b}
    b 2 3 b b
    ========================================================
    提示:调用方法为${数组名[@或*]/查找字符/替换字符},该操作不会改变原先数组的内容,
    如果需要修改,可以参考上面的例子,重新定义数组。
    

    删除数组元素部分内容的代码如下:

    [root@zabbix 0514]# array=(one one1 two two1 three three1  four four1 left)
    [root@zabbix 0514]# echo ${array[*]#f*}			==> 删除数组中以f开头的元素中的f
    one one1 two two1 three three1 our our1 left
    [root@zabbix 0514]# echo ${array[*]##f*}		==> 删除数组中以f开头的元素
    one one1 two two1 three three1 left
    =======================================================================
    [root@zabbix 0514]# echo ${array[*]}
    one one1 two two1 three three1 four four1 left
    [root@zabbix 0514]# echo ${array[*]%1*}			==> 删除数组中以1结尾的元素中的1
    one one two two three three four four left
    

    13.3 shell 数组脚本开发实践

    13.3.1 使用循环批量输出数组的元素

    范例13-1:使用循环批量输出数组的元素。

    方法1:通过C语言型的for循环语句打印数组元素。

    [root@zabbix 0514]# cat for_c.sh 
    #!/bin/bash
    array=(1 2 3 4 5)
    for((i=0;i<${#array[*]};i++))
    do
        echo ${array[i]}
    done
    [root@zabbix 0514]# sh for_c.sh 
    1
    2
    3
    4
    5
    

    方法2:通过普通for循环语句打印数组元素。

    [root@zabbix 0514]# cat array_1.sh 
    #!/bin/bash
    array=(1 2 3 4 5)
    for n in ${array[*]}
    do
        echo $n
    done
    
    

    方法3:使用while循环语句打印数组元素。

    [root@zabbix 0514]# cat array_while.sh 
    #!/bin/bash
    array=(1 2 3 4 5)
    i=0
    while ((i<${#array[*]}))
    do
        echo ${array[i]}
        ((i++))
    done
    

    13.3.2 竖向列举法定义数组元素并批量打印

    范例13-2:通过竖向列举法定义数组元素并批量打印。

    [root@zabbix 0514]# cat array_menu.sh 
    #!/bin/bash
    array=(
    oldboy
    oldgirl
    moox
    tingting
    )
    for ((i=0;i<${#array[*]};i++))
    do
        echo "this is num $i ,content: ${array[$i]}"
    done
    echo -----------------------------
    echo "array length: ${#array[*]}"
    
    
    ===================================
    [root@zabbix 0514]# sh array_menu.sh 
    this is num 0 ,content: oldboy
    this is num 1 ,content: oldgirl
    this is num 2 ,content: moox
    this is num 3 ,content: tingting
    -----------------------------
    array length: 4
    

    范例13-3:将命令结果作为数组元素定义并打印。

    [root@zabbix 0514]# ll array
    total 0
    -rw-r--r-- 1 root root 0 May 14 11:19 1.txt
    -rw-r--r-- 1 root root 0 May 14 11:19 2.txt
    -rw-r--r-- 1 root root 0 May 14 11:19 3.txt
    [root@zabbix 0514]# cat array_ls.sh 
    #!/bin/bash
    dir=($(ls array))				==> 将ls的结果放到数组中,数组定义:array=(1 2 3 ..)
    								==> $(ls array) =  `ls array`
    for ((i=0;i<${#dir[*]};i++))
    do
        echo "NO.$i : ${dir[$i]}"
    done
    [root@zabbix 0514]# sh array_ls.sh 
    NO.0 : 1.txt
    NO.1 : 2.txt
    NO.2 : 3.txt
    
    

    13.4 shell 数组的重要命令

    (1)定义命令

    1.静态数组   array=(1 2 3)
    2.动态数组	 array=($(ls))或array=(`ls`)
    3.数组赋值	 array[2]=3
    

    (2)打印命令

    1.打印所有元素   ${array[@]} 或 ${array[*]}
    2.打印数组长度   ${#array[@]} 或 ${#array[*]}
    3.打印单个元素   ${array[i]}
    

    (3)循环打印的常用基本语法

    #!/bin/bash
    array={
        10.0.0.11
        10.0.0.22
        10.0.0.33
    }
    ==> C语言for循环语法
    for ((i=0;i<${#array[*]};i++))
    do
    	echo ${array[$i]}
    done
    ==>普通for循环语法
    for  n  in ${array[*]}
    do
    	echo $n
    done
    

    13.5 shell数组相关面试题及实战案例

    13.5.1 数组实现循环打印单词

    范例13-4:利用bash for循环打印下面这句话中字母数不大于6的单词(某企业面试真题)。

    I am oldboy training  welcome to my linux class
    

    方法1:通过数组方法来实现。

    [root@zabbix 0515]# cat array_length.sh 
    #!/bin/bash
    arr=(I am oldboy training  welcome to my linux class )
    for ((i=0;i<${#arr[*]};i++))
    do
        if [ ${#arr[$i]} -lt 6 ];then
           echo ${arr[$i]}
        fi
    done
    echo ------------------------
    for word in ${arr[*]}
    do
        if [ `expr length $word` -lt 6 ]
          then
    	echo $word
        fi
    done
    
    

    方法2:使用for循环列举取值列表法。

    [root@zabbix 0515]# cat array_length.sh 
    #!/bin/bash
    #for word in I am oldboy training  welcome to my linux class 
    chars="I am oldboy training  welcome to my linux class" 
    for word in $chars
    do
        if [ `echo $word|wc -L` -lt 6 ]
          then
    	echo $word
        fi
    done
    
    

    方法3:通过awk循环实现。

    [root@zabbix 0515]# chars="I am oldboy training  welcome to my linux class"
    [root@zabbix 0515]# echo $chars |awk '{for(i=1;i<=NF;i++)if(length($i)<=6) print $i}'
    I
    am
    oldboy
    to
    my
    linux
    class
    

    13.5.2 数组实现批量检查多个网址异常

    范例13-5:批量检查多个网站地址是否正常。

    要求: 1)使用Shell数组的方法实现,检测策略尽量模拟用户访问。 2)每10秒进行一次全部检测,无法访问的输出报警。 3)待检测的地址如下。 http://blog.moox.com http://blog.moox.org http://www.moox.com http://10.0.0.71

    解题思路: 1)把URL定义成数组,形成函数。 2)编写URL检查脚本函数,传入数组的元素,即URL。 3)组合实现整个案例,编写main主函数(即执行函数),每隔10秒检查一次。 下面的参考答案采用了Shell数组的方法,同时检测多个URL是否正常,并给出专业的展示效果

    [root@zabbix 0515]# cat array_url.sh 
    #!/bin/bash
    . /etc/init.d/functions
    
    check_count=0
    url_list=(
    http://blog.moox.com
    http://blog.moox.org
    http://www.moox.com
    http://10.0.0.71
    )
    function wait(){
        echo -n "3 second  later , check url would be run."
        for ((i=3;i>=1;i--))
        do
    	echo -n " $i " 
    	sleep 1
        done
    }
    function check_url(){
        wait
        for ((i=0;i<`echo ${#url_list[*]}`;i++))
        do
    	wget -o /dev/null -T 3 --tries=1 --spider ${url_list[$i]} > /dev/null 2>&1
    	if [ $? -eq 0 ];then
    	    action $"${url_list[$i]}" /bin/true
    	else
    	    action $"${url_list[$i]}" /bin/false
    	fi
        done
        ((check_count++))
    }
    function main(){
        while true
        do
    	check_url
    	echo "--------check count: ${check_count}"
    	sleep 10
        done
    }
    main 
    

    13.6 合格运维人员必会的脚本列表

    作为一个合格的运维人员,需要掌握的脚本知识列表如下: 1)系统及各类服务的监控脚本,例如:文件、内存、磁盘、端口,URL监控报警等。 2)监控网站目录下的文件是否被篡改,以及当站点目录被批量篡改后如何批量恢复它们的脚本。 3)各类服务Rsync、Nginx、MySQL等的启动及停止专业脚本(使用chkconfig管理)。 4)MySQL主从复制监控报警,以及自动处理不复制故障的脚本。 5)一键配置MySQL多实例、一键配置MySQL主从部署的脚本。 6)监控HTTP、MySQL、Rsync、NFS、Memcached等服务是否异常的生产脚本。 7)一键软件安装及优化的脚本,比如LANMP、Linux一键优化,一键数据库安装、优化等。 8)MySQL多实例启动脚本,分库、分表自动备份脚本。 9)根据网络连接数及Web日志PV数封IP的脚本。 10)监控网站的PV及流量,并且对流量信息进行统计的脚本。 11)检查Web服务器多个URL地址是否异常的脚本,要是可以批量处理且通用的脚本。 12)对系统的基础配置一键优化的脚本。 13)TCP连接状态及IP统计报警的脚本。 14)批量创建用户并设置随机8位密码的脚本。

  • 相关阅读:
    前端自动化gulp使用方法
    npm 如何提升最新版本
    AJAX——理解XMLHttpRequest对象
    免插件,简单实现上拉加载loading
    mobiscroll实现二级联动菜单
    js点击页面其他地方如何隐藏div元素菜单
    gulp自动化构建工具使用总结
    如何优雅的选择字体(fontfamily)
    js如何判断用户使用的设备类型及平台
    ant 软件包 javax.servlet.http 不存在 解决办法
  • 原文地址:https://www.cnblogs.com/moox/p/12896432.html
Copyright © 2011-2022 走看看