系统基础之shell脚本编程详解4(数组及字符串处理,变量赋值和配置文件)

系统基础之shell脚本编程详解4(数组及字符串处理,变量赋值和配置文件)

    今天来讲shell脚本编程的最后一些内容,数组及字符串处理,变量赋值和配置文件.这些内容也是我们经常在工作中使用到的知识点.下面让我们来详细了解下:




数组:


  程序=指令+数据

         指令:编程语法的关键字,调用系统命令,编写的函数

        数据:变量,文件

  变量:存储单个元素的内存空间;

  数组:存储多个元素的连续的内存空间;(连续的内存空间存储连续的元素,元素有独立的空间,但只有一个统一的名字,索引表示各个元素)

         数组名:整个数组只有一个名字;数组的标识,数组名指向的存储多个元素的内存空间起始地址的标识

         数组索引:编号从0开始,1,2,3..N

         使用方式:数组名[索引]

                ${ARRAY_NAME[INDEX]}

         注意:bash-4及以后的版本,支持自定义索引格式,而不仅仅是0,1,2..数字格式;

         此类数组称之为"关联数组"

  声明数组:

         declare -a name: 声明索引数组

         declare -A name: 声明关联数组(自定义下标的数组,必须声明)

         也可不声明,直接使用

                animals[0]=pig

                animals[1]=dog

  引用数组:

         1.直接引用数组名,显示第一个数组的元素.  echo $animals

         2.指定引用元素:

  数组的赋值方式:

         1.一次只复制一个元素

                ARRAY_name[IDX]=value

         2.一次复制全部元素

                ARRAY_name=("mem" "TUS" "web")

         3.只赋值特定元素:

                ARRAY_name=([0]="mem" [3]="erv"..)

                注意:bahs支持稀疏格式的数组

         4.read  -a ARRAY_NAME

            [root@wen-7 shangkelianxi]# qwe=(1 2 4  5  67  8 9 )            
            [root@wen-7 shangkelianxi]# qwe[1]=1
            [root@wen-7 shangkelianxi]# qwe=([1]=1 [2=]2 )
            [root@wen-7 shangkelianxi]# read -a qwe
            1 2 3 4 5

  引用数组中的元素,${ARRAY_NAME[INDEX]}

        注意:引用时,只给数组名,表示引用下标为0的元素;

            [root@wen-7 shangkelianxi]# echo ${qwe[1]}            
            2
            [root@wen-7 shangkelianxi]# echo ${qwe[2]}
            3
            [root@wen-7 shangkelianxi]# echo ${qwe}
            1

  数组的长度(数组中元素的个数)

        ${#ARRAY_NAME[*]}

        ${#ARRAY_NAME[@]}

        [root@wen-7 shangkelianxi]# echo ${#qwe[@]}        
        5
        [root@wen-7 shangkelianxi]# echo ${#qwe[*]}
        5

  引用数组中所有元素:

        ${ARRAY_NAME[*]}

        ${ARRAY_NAME[@]}

        [root@wen-7 shangkelianxi]# echo ${qwe[*]}        
        1 2 3 4 5
        [root@wen-7 shangkelianxi]# echo ${qwe[@]}
        1 2 3 4 5

  数组元素切片:$ {ARRAY_NAME[@]:offset:number}

        offset:要路过的元素个数

        number:要去除的元素个数,省略number时,表示取偏移量之后的所有元素

            [root@wen-7 shangkelianxi]# echo ${qwe[@]:2:3}            
            3 4 5
            [root@wen-7 shangkelianxi]# echo ${qwe[@]:2:1}
            3

  向非稀疏数组中追加元素:

        ARRAY_name[${ARRAY_name[*]}]=

    

  删除数组中的元素

         unset ARRAY[index]

        [root@wen-7 shangkelianxi]# unset qwe[2]        
        [root@wen-7 shangkelianxi]# echo ${qwe[2]}

  关联数组

         declare -A ARRAY_name

         ARRAY_NAME=([index_name1]="value1" [index_name1]="value2")         

            [root@wen-7 shangkelianxi]# declare -A asd            
            [root@wen-7 shangkelianxi]# asd=([a]="qwe" [b]="zc" [c]="fd1")
            [root@wen-7 shangkelianxi]# echo ${asd[a]}
            qwe
            [root@wen-7 shangkelianxi]# echo ${asd[b]}
            zc

 实战:

      1.生成10个随机数,并找出其中的最大值和最小值

        declare -a rand        
        declare -i max=0
        declare -i min=99999
        
        for i in {1..9};do
        	rand[$i]=$RANDOM
        	echo ${rand[$i]}
        	[ ${rand[$i]} -gt $max ] && max=${rand[$i]}
        	[ ${rand[$i]} -lt $min ] && min=${rand[$i]}
        
        done
        echo "max: $max min:$min"

   

      2.定义一个数组,数组中的元素是/var/log目录下所有以.log结尾文件,统计其下标为偶数的文件中的行数之和             

    declare -a files
    files=(/var/log/*.log)
    declare -i lins=0

    for i in $(seq 0 $[${#files[*]}-1]);do
       if [ $[$i%2] -eq 0 ]; then
          let lins+=$(wc -l ${files[$i]} | cut -d' ' -f1)
       fi
    done
    echo "lines:$lins"

     

     3. 冒泡法,计算10个随机数,从大到小,从小到大排列

        declare -i num;    
    read -a   arg -p    "请输入10个数字:"
    for((i=0;i<=9;i++))do
        for((k=$[i+1];k<=9;k++))do
           if  [ ${arg[$i]} -gt ${arg[$k]} ];then
             num=${arg[$i]} 
             arg[$i]=${arg[$k]} 
             arg[$k]=$num
           fi 
          done
    done
       echo "正序排列${arg[*]}"
    echo "=============="
    for((i=0;i<=9;i++))do    
        for((k=$[i+1];k<=9;k++))do
        if  [ ${arg[$i]} -lt ${arg[$k]} ];then
             num=${arg[$i]} 
             arg[$i]=${arg[$k]} 
             arg[$k]=$num
         fi 
         done
    done
       echo "逆序排列${arg[*]}"


字符串处理:


bash的内置字符串处理工具

   字符串切片:

       ${var:offset:number}

       取字符串的子串

        [root@wen-7 shangkelianxi]# name=jerry
        [root@wen-7 shangkelianxi]# echo ${name:2}
         rry
        [root@wen-7 shangkelianxi]# echo ${name:2:2}
         rr

       取字符串的最右侧的几个字符:${var: -length}

            注意:冒号后必须有一个空白字符

        [root@wen-7 shangkelianxi]# echo ${name: -4}
        erry

       基于模式取子串:

            ${var#*word}:其中word是指定的分隔符,功能:自左而右,查找var变量所存储的字符串中,第一次出现的word分隔符,删除字符串开头至此分隔符之间的所有字符.

            ${var##*word}:其中word是指定的分隔符,功能:自左而右,查找var变量所存储的字符串中,最后一次出现的word分隔符,删除字符串开头至此分隔符之间的所有字符.

        [root@wen-7 shangkelianxi]# myfa="/etc/init.d/functions"
        [root@wen-7 shangkelianxi]# echo ${myfa#*/}
        etc/init.d/functions
        [root@wen-7 shangkelianxi]# echo ${myfa##*/}
        functions

                

            ${var%word*}:其中word是指定的分隔符,功能:自右而左,查找var变量所存储的字符串中,第一次出现的word分隔符,删除字符串开头至此分隔符之间的所有字符.

            ${var%%word*}:其中word是指定的分隔符,功能:自右而左,查找var变量所存储的字符串中,最后一次出现的word分隔符,删除字符串开头至此分隔符之间的所有字符.

         [root@wen-7 shangkelianxi]# myfa="/etc/init.d/functions"
         [root@wen-7 shangkelianxi]# echo ${myfa%/*}
          /etc/init.d
         [root@wen-7 shangkelianxi]# echo ${myfa%%/*}
        
         [root@wen-7 shangkelianxi]#mypath="/etc/init.d/funtion"
          ${mypath%*}   /etc/init.d
         url=http://www.magedu.com:80
         {url##*:}
         {url%%:*}

      查找替换:

            ${var/PATTERN/SUBST}:查找var所代表的字符串中,第一次被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串

            ${var//PATTERN/SUBST}:查找var所代表的字符串中,所有被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串

            ${var/#PATTERN/SUBSTI}:查找var所代表的字符串中,行首被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串

            ${var/%PATTERN/SUBSTI}:查找var所代表的字符串中,行尾被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串

           

         [root@wen-7 ~]# user="root:x:0:0:root admin:/root:bin/chroot"
         [root@wen-7 ~]# echo ${user/root/ROOT}
         ROOT:x:0:0:root admin:/root:bin/chroot
         [root@wen-7 ~]# echo ${user//root/ROOT}
         ROOT:x:0:0:ROOT admin:/ROOT:bin/chROOT
         [root@wen-7 ~]# echo ${user/#root/ROOT}
         ROOT:x:0:0:root admin:/root:bin/chroot
         [root@wen-7 ~]# echo ${user/%root/ROOT}
         root:x:0:0:root admin:/root:bin/chROOT
           注意:PATTERN中使用glob风格的通配符

      查找删除:

            ${var/PATTERN}:以PATTERN为模式,查找var字符串中第一次的匹配,并删除值

            ${var//PATTERN}:以PATTERN为模式,查找var字符串中所有的匹配,并删除值

            ${var/#PATTERN}:以PATTERN为模式,查找var字符串中行首的匹配,并删除值

            ${var/%PATTERN}:以PATTERN为模式,查找var字符串中行尾的匹配,并删除值

        [root@wen-7 shangkelianxi]# var=`getent passwd | grep ^root`                     
        [root@wen-7 shangkelianxi]# echo $var
        root:x:0:0:root:/root:/bin/bash
        [root@wen-7 shangkelianxi]# echo ${var/root}
        :x:0:0:root:/root:/bin/bash
        [root@wen-7 shangkelianxi]# echo ${var//root}
        :x:0:0::/:/bin/bash
        [root@wen-7 shangkelianxi]# echo ${var/#root}
        :x:0:0:root:/root:/bin/bash
        [root@wen-7 shangkelianxi]# echo ${var/%bash}
        root:x:0:0:root:/root:/bin/

      字符大小写转换:

            ${var^^}:把var中的所有小写字符转化为大写

            ${var,,}:把var中的所有大写字符转化为小写

        [root@wen-7 shangkelianxi]# var=dfadfkladsnfkldshfkdf                    
        [root@wen-7 shangkelianxi]# echo ${var^^}
        DFADFKLADSNFKLDSHFKDF
        [root@wen-7 shangkelianxi]# var=AJDKFDAFKLDF
        [root@wen-7 shangkelianxi]# echo ${var,,}
        ajdkfdafkldf


变量赋值及引用:


 变量赋值:

        ${var:-value}: 如果var变量为空,或未定义,那么返回value为值,否则,则返回var变量值

           [root@wen-7 ~]# echo ${user:-qwe}
           root:x:0:0:root admin:/root:bin/chroot
           [root@wen-7 ~]# unset user
           [root@wen-7 ~]# echo ${user:-qwe}
           qwe

     

       ${var:=value}如果var变量为空,或未定义,那么返回value,并将value赋值给var变量,否则,则返回var变量值

           [root@wen-7 ~]# user=adfdf
           [root@wen-7 ~]# echo ${user:=qwe}
           adfdf
           [root@wen-7 ~]# unset user
           [root@wen-7 ~]# echo ${user:=qwe}
           qwe

      

     ${var:+value}:如果var变量不空,则返回value为值.

         [root@wen-7 ~]# user=adfdf
         [root@wen-7 ~]# echo ${user:+qwe}
         qwe

  

      ${var:?ERROR_INFO}:如果var变量为空,或未定义,则返回ERROR_INFO,否则,返回var的值

         [root@wen-7 ~]# user=adfdf
         [root@wen-7 ~]# echo ${user:?error}
         adfdf
         [root@wen-7 ~]# unset user
         [root@wen-7 ~]# echo ${user:?error}
         -bash: user: error

               

    为脚本程序使用配置文件,实现变量赋值(编写变亮脚本,多次引用)
        (1) 定义文本文件,每行定义“ name=value”
        (2) 在脚本中source此文件即可

        [root@wen-7 shangkelianxi]# cat  variable.sh            
         #!/bin/bash
         declare -A qwe
         qwe=([a]="qas" [b]="zxc" )
         declare -a asd
         asd=(1 2 3 5 4 6)
         declare -i sum=0
         
         [root@wen-7 shangkelianxi]# cat variable1.sh
          #!/bin/bash

         source variable.sh
        
         echo ${qwe[a]}
         echo ${qwe[b]}
         echo $sum
        [root@wen-7 shangkelianxi]# bash variable1.sh
         qas
         zxc
         4

     变量高级用法-有类型变量
         Shell变量一般是无类型的,但是bash Shell提供了declare和
         typeset两个命令用于指定变量的类型,两个命令是完全等价的
        declare [选项] 变量名
            -r 将变量设置为只读属性
            -i 将变量定义为整型数
            -a 将变量定义为数组
            -f 显示此脚本前定义过的所有函数名及其内容
            -F 仅显示此脚本前定义过的所有函数名
            -x 将变量声明为环境变量
            -l 将变量值转为小写字母
            -u 将变量值转为大写字母

     间接变量引用:

       如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用
          variable1=variable2
          variable2=value
          variable1的值是variable2,而variable2又是变量名,
           variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为  

             bash Shell提供了两种格式实现间接变量引用
             eval tempvar=\$$variable1

           tempvar=${!variable1}

            [root@server ~]# N=NAME           
            [root@server ~]# NAME=wangxiaochun
            [root@server ~]# N1=${!N}
            [root@server ~]# echo $N1
            wangxiaochun
            [root@server ~]# eval N2=\$$A
            [root@server ~]# echo $2
            wangxiaochun

     eval命令:

        eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量。该命令对变量进行两次扫描

        [root@server ~]# V1=pwd
        [root@server ~]# echo $V1
         pwd
        [root@server ~]# eval $V1
        /root

    创建临时文件
       mktemp命令:创建的临时文件可避免冲突
        mktemp [OPTION]… [TEMPLATE]
            TEMPLATE: filename.XXX
            X至少要出现三个
         OPTION:
            -d: 创建临时目录
            –tmpdir=/DIR:指明临时文件所存放的目录位置

        #mktemp --tmpdir=/testdir test.XXXXXX

    安装复制文件
       install命令:
            install [OPTION]… [-T] SOURCE DEST 单文件
            install [OPTION]… SOURCE… DIRECTORY
            install [OPTION]… -t DIRECTORY SOURCE…
            install [OPTION]… -d DIRECTORY…创建空目录
        选项:
        -m MODE,默认755
        -o OWNER
           -g GROUP

    bash如何展开命令行
       把命令行分成单个命令词
        展开别名
        展开大括号种的声明( {})
        展开波浪符声明( ~)
        命令替换$() 和 “)
         再次把命令行分成命令词
         展开文件通配( *、 ?、 [abc]等等)
         准备I/0重导向( <、 >)
         运行命令

    防止扩展
        反斜线( \)会使随后的字符按原意解释
        $ echo Your cost: \$5.00
        Your cost: $5.00
        加引号来防止扩展
        单引号( ’)防止所有扩展
        双引号( ”)也防止所有扩展,但是以下情况例外:
        $(美元符号) - 变量扩展
        (反引号) - 命令替换
         \(反斜线) - 禁止单个字符扩展
         !(叹号) - 历史命令替换


配置文件:


两类:

profile类:为交互式登录的shell进程提供配置

bashrc类:为交互式登录的shell进程提供配置

登录类型:

交互式登录shell进程:

直接通过某终端输入账号密码后登录打开的shell进程

使用su命令,:su – uaername ;su -l Username 执行的登录切换

非交互式登录shell进程:

su username 执行的登录切换

图形界面下打开的终端

运行脚本

profile类:为交互式登录的shell进程提供配置

全局:对所有用户都生效

/etc/profile

/etc/profile.d/*.sh

局部:仅对当前用户生效

~/.bash_profile

功用:

用于定义环境变量

运行命令或脚本

bashrc类:

全局:

/etc/bashrc

局部:仅对当前用户生效

~/.bashrc

功用:

定义本地变量

冬衣命令别名

注意:仅管理员可修改全局配置文件

交互式登录shell进程:

/etc/profile–>/etc/profile.d/* –>~/.bash_profile–>~/.bashrc–>/etc/bashrc

非交互式登录shell进程:

~/.bashrc–>/etc/bashrc–>/etc/profile.d/*

命令行中定义的特性,例如变量和别名作用域为当前shell进程的生命周期;

配置文件定义的特性,只对随后新启动的shell进程有效。

让通过配置文件定义的特性立即生效:

(1)用过命令重新定义一次;

(2)让shell进程重读配置文件

~]#source /path/TO/CONF_FILE

~]#./path/TO/CONF_FILE

问题:

1.如何定义对所有用户都生效的命令别名

            在/etc/profile.d/中编写文件

2.让centos用户登录时,提供其已登录 并显示当前系统时间

[root@wen-7 ~]# vim /home/centos/.bash_login
echo "hello $HOSTNAME"
date

原创文章,作者:wencx,如若转载,请注明出处:http://www.178linux.com/39452

(0)
上一篇 2016-08-23 23:11
下一篇 2016-08-24 10:12

相关推荐

  • Linux中/etc/passwd、/etc/shadow文件字段的含义以及用处

        今天本人学习到了两个个Linux中非常重要的文件,它们承载着Linux用户的相关信息,如果在账号方面出现一些密码相关的问题,就可以来找这两个文件查看和分析一番。     他们分别是/etc/passwd和/etc/shadow两个文件,他们都存放于/etc目录中,都可以使用cat命令来查看其内容。  …

    Linux干货 2016-01-14
  • 第六周-Vim、计划任务及Shell脚本练习

    一、复制/etc/rc.d/rc.sysinit文件至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的行的行首加#; cp /etc/rc.d/rc.sysinit /tmp vim /tmp/rc.sysinit 末行模式输入 :%s@^[[:space:]]\+@#&@g 二、复制/boot/grub/grub.co…

    Linux干货 2017-08-13
  • 网络配置详解(一)

    Linux网络属性配置      ifcfg命令家族:ifconfig, route, netstat      ifconfig命令:      ifconfig [INTERFACE]      # ifconfig -a 显示所有接口…

    Linux干货 2017-01-02
  • 创建CA 和申请证书

    创建CA 和申请证书1生成私有CA的私钥:(umask 066;openssl genrsa -out /etc/pki/CA/private/cakey.pem 2048)注:CA的私钥文件必须放在/etc/pki/CA/private/cakey.pem 这个路径里2创建序列号 ,数据库文件touch  /etc/pki/CA/index.tx…

    Linux干货 2017-07-17
  • Linux的哲学思想

    Linux的哲学思想 一切皆文件 在linux中所有的一切,都是可以通过ls进行查询的到的,甚至可以说ll查看详细信息时表现形式为文件,所有的设备,所有的文件不论后缀,只是一个单纯文件通过vim可以编辑一切 单一目的的小程序,组合小程序完成复杂任务 在linux中,每一个命令都是对应一个功能,通过不同的参数来完成不同的要求,通过繁多的小的命令来完成大型的要求…

    Linux干货 2016-10-30
  • 第八周作业

    1、写一个脚本,使用ping命令探测172.16.250.1-172.16.250.254之间的所有主机的在线状态;     在线的主机使用绿色显示;     不在线的主使用红色显示; #!/bin/bash for i in {1..254};do if ping -c 1 -w 1 192.16…

    2017-07-03