24-Linux-shell脚本进阶篇(四)

shell脚本进阶篇(四)


信号捕捉trap

  • trap ‘触发指令’ 信号

    • 进程收到系统发出的指定信号后,将执行自定义指令,而不会执行原操作
  • trap ‘’ 信号

    • 忽略信号的操作
  • trap ‘-’ 信号

    • 恢复原信号的操作
  • trap -p

    • 列出自定义信号操作
  • trap finish EXIT

    • 当脚本退出时,执行finish函数

使用 kill -l 查看信号类型

[root@CentOS8 ~]# kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

举个栗子

???

数组

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

  • 数组:存储多个元素的连续的内存空间,相当于多个变量的集合

  • 数组名和索引

    • 索引:编号从0开始,属于数值索引
    • 注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引, bash4.0版本之后开始支持
    • bash的数组支持稀疏格式(索引不连续)
  • 声明数组:

    declare -a ARRAY_NAME
    declare -A ARRAY_NAME 关联数组
    注意:两者不可相互转换

数组赋值

  • 数组元素的赋值

    (1) 一次只赋值一个元素
    ARRAY_NAME[INDEX]=VALUE
    weekdays[0]=“Sunday”
    weekdays[4]=“Thursday”

    (2) 一次赋值全部元素
    ARRAY_NAME=(“VAL1” “VAL2” “VAL3” …)

    (3) 只赋值特定元素
    ARRAY_NAME=([0]=“VAL1” [3]=“VAL2” …)

    (4) 交互式数组值对赋值
    read -a ARRAY

  • 显示所有数组:declare -a

        [root@CentOS7 data]# title[0]=ceo
        
        [root@CentOS7 data]# title[1]=dog
        
        [root@CentOS7 data]# title[2]=yes
        
        [root@CentOS7 data]# echo ${title[0]} ${title[1]} ${title[2]}
        ceo dog yes
        
        [root@CentOS7 data]# declare -a
        declare -a BASH_ARGC='()'
        declare -a BASH_ARGV='()'
        .................
        declare -a PIPESTATUS='([0]="127")'
        declare -a title='([0]="ceo" [1]="dog" [2]="yes")'
**删除**

        [root@CentOS7 data]# unset title[0]=ceo
        [root@CentOS7 data]# unset title[1]=dog
        [root@CentOS7 data]# unset title[2]=yes
        [root@CentOS7 data]# echo ${title[0]} ${title[1]} ${title[2]}

        [root@CentOS7 data]#

换个方式来写

		[root@CentOS8 ~]# title=([0]=ceo [1]=dog [2]=yes) 
        [root@CentOS7 data]# echo ${title[0]} ${title[1]} ${title[2]}
        ceo dog yes

显示个数

可以替换成其他字符

        [root@CentOS7 data]# echo ${#title[*]}
        3

显示全部

可以替换成其他字符

        [root@CentOS7 data]# echo ${title[*]}
        ceo dog yes

从 0 开始显示的 n 个

        [root@CentOS7 data]# echo ${title[*]:0:n}

例如

        [root@CentOS7 data]# echo ${title[*]:0:1}
        ceo
        [root@CentOS7 data]# echo ${title[*]:0:2}
        ceo dog
        [root@CentOS7 data]# echo ${title[*]:0:3}
        ceo dog yes

添加新的数值

        [root@CentOS7 data]# title[${#title[*]}]=new
        [root@CentOS7 data]# echo ${title[*]}
        ceo dog yes new

删除整个数组

        root@CentOS7 data]# unset title
        [root@CentOS7 data]# echo ${title[*]}

        [root@CentOS7 data]# 
  • 数组从 0 开始排序

若假设一共有 n 个数值,则最后一位数值显示应为 :

    echo ${title[n-1]}

    root@CentOS7 data]# file=(*.sh)
  
    [root@CentOS7 data]# echo ${file[*]}
    1_100.sh batch_user2.sh batch_user.sh big_chess_while.sh ........ print.sh rename_file.sh star.sh sum_while.sh

    [root@CentOS7 data]# num=({a..k})
    
    [root@CentOS7 data]# echo ${#num[*]}
    11
    
    [root@CentOS7 data]# echo ${num[*]}
    a b c d e f g h i j k

数组数据处理

  • 引用数组中的元素:
    数组切片:
    ${ARRAY[@]:offset:number}

    offset 要跳过的元素个数
    number 要取出的元素个数

    取偏移量之后的所有元素
    ${ARRAY[@]:offset}

  • 向数组中追加元素:
    ARRAY[${#ARRAY[*]}]=value

  • 关联数组:
    declare -A ARRAY_NAME
    ARRAY_NAME=([idx_name1]=‘val1’ [idx_name2]='val2‘…)
    注意:关联数组必须先声明再调用

关联数组未经声明无法调用

    [root@CentOS7 data]# laowang[a]='111'
    [root@CentOS7 data]# laowang[b]='222'
    [root@CentOS7 data]# laowang[c]='333'
    
    [root@CentOS7 data]# echo ${laowang[a]}
    333
    
    [root@CentOS7 data]# echo ${laowang[b]} ${laowang[c]}
    333 333

    [root@CentOS7 data]# unset laowang

如何声明

    [root@CentOS7 data]# declare -A laowang
    
    [root@CentOS7 data]# laowang[a]='111'
    [root@CentOS7 data]# laowang[b]='222'
    [root@CentOS7 data]# laowang[c]='333'

    [root@CentOS7 data]# echecho ${laowang[b]} ${laowang[c]}
    222 333

示例 :

生成10个随机数保存于数组中,找出其最大值和最小值
[root@CentOS7 data]# vim max_min_dac.sh
#!/bin/bash
declare -i min max
declare -a nums
for ((i=0;i<10;i++));do
        nums[$i]=$RANDOM
[ $i -eq 0 ] && min=${nums[$i]} && max=${nums[$i]} && continue
[ ${nums[$i]} -gt $max ] && max=${nums[$i]}
[ ${nums[$i]} -lt $min ] && min=${nums[$i]}
done
echo "All numbers are ( ${nums[*]} )"
echo Max is $max
echo Min is $min

[root@CentOS7 data]# sh max_min_dac.sh
All numbers are ( 23713 24106 17201 23830 22057 17093 17260 27638 4346 18327 )
Max is 27638
Min is 4346

字符串切片

  • ${#var}:返回字符串变量var的长度

  • ${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字 符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)

  • ${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个 字符)的字符开始,长度为number的部分

  • ${var: -length}:取字符串的最右侧几个字符 注意:冒号后必须有一空白字符

  • ${var:offset:-length}:从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字 符之前的内容

  • ${var: -length:-offset}:先从最右侧向左取到length个字符开始,再向右取到距离最 右侧offset个字符之间的内容
    注意:-length前空格

举个栗子

    [root@CentOS7 data]# str=`echo {0..9} |tr -d " "`

    [root@CentOS7 data]# echo ${str[*]}
    0123456789

    [root@CentOS7 data]# echo ${str:3:4}    #从第三个开始后面四个
    3456

    [root@CentOS7 data]# echo ${str: -3}    #从后往前数三个
    789

    [root@CentOS7 data]# echo ${str::5}     #显示前五个
    01234

    [root@CentOS7 data]# echo ${str::5 -3}  #从第五个开始往前数三个之后的数
    01

字符串处理

  • 基于模式取子串

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

    ${var##*word}:同上,贪婪模式,不同的是,删除的是字符串开头至最后 一次由word指定的字符之间的所有内容

  • 示例:
    file=“var/log/messages”
    ${file#*/}: log/messages
    ${file##*/}: messages

  • ${var%word*}:其中word可以是指定的任意字符

    功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删 除字符串最后一个字符向左至第一次出现word字符串(含)之间的所有字符

      file="/var/log/messages"  
      ${file%/*}: /var/log 
    
  • ${var%%word*}:同上,只不过删除字符串最右侧的字符向左至最后一次出现 word字符之间的所有字符

  • 示例:
    url=http://www.magedu.com:80

      ${url##*:} 80  
      
      ${url%%:*} http 
    
  • 查找替换

    ${var/pattern/substr}:
    查找var所表示的字符串中,第一次被pattern所匹 配到的字符串,以substr替换之

    ${var//pattern/substr}:
    查找var所表示的字符串中,所有能被pattern所匹 配到的字符串,以substr替换之

    ${var/#pattern/substr}:
    查找var所表示的字符串中,行首被pattern所匹 配到的字符串,以substr替换之

    ${var/%pattern/substr}:
    查找var所表示的字符串中,行尾被pattern所匹 配到的字符串,以substr替换之

  • 查找并删除

    ${var/pattern}:
    删除var表示的字符串中第一次被pattern匹配到的字符串

    ${var//pattern}:
    删除var表示的字符串中所有被pattern匹配到的字符串

    ${var/#pattern}:
    删除var表示的字符串中所有以pattern为行首匹配到的 字符串

    ${var/%pattern}:
    删除var所表示的字符串中所有以pattern为行尾所匹配 到的字符串

  • 字符大小写转换
    ${var^^}:把var中的所有小写字母转换为大写
    ${var,}:把var中的所有大写字母转换为小写

##贪婪模式

贪婪模式将搜索全局至最后一个结束

    [root@CentOS8 ~]# getent passwd td
    td:x:1000:1000:td:/home/td:/bin/bash
    
    [root@CentOS8 ~]# line=\`getent passwd td\`
    
    [root@CentOS8 ~]# echo ${line#*td}
    :x:1000:1000:td:/home/td:/bin/bash
    
    [root@CentOS8 ~]# echo ${line##*td}
    :/bin/bash
  • 变量赋值表
    在这里插入图片描述

高级变量用法-有类型变量

  • Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令 用于指定变量的类型,两个命令是等价的

  • declare [选项] 变量名

    -r 声明或显示只读变量 
    
    -i 将变量定义为整型数 
    
    -a 将变量定义为数组 
    
    -A 将变量定义为关联数组 
    
    -f 显示已定义的所有函数名及其内容 
    
    -F 仅显示已定义的所有函数名 
    
    -x 声明或显示环境变量和函数 
    
    -l  声明变量为小写字母  declare –l var=UPPER 
    
    -u  声明变量为大写字母 declare –u var=lower 
  • eval命令

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

  • 示例:

    [root@server ~]# CMD=whoami 
    
    [root@server ~]# echo  $CMD  
        whoami 
        
    [root@server ~]# eval $CMD  root      
    
    [root@server ~]# n=10             
    
    [root@server ~]# echo {0..$n}          
        {0..10}     
        
    [root@server ~]# eval echo {0..$n}      
        0 1 2 3 4 5 6 7 8 9 10 

使用 expect 实现非用户交互

当我们想远程传送文件或定时登录终端进行一些自动化的操作时,是无法保证人在电脑前的,若想使其不因输入密码而卡在该界面,expect命令便可实现该目的

[root@localhost data]# vim expect.sh 
#!/bin/expect 
spawn scp /etc/fstab root@192.168.23.128:/data 
expect { 
    "yes/no" { send "yes\n";exp_continue } 
    "password" { send "123456\n" } 
    } 
    expect eof 

[root@localhost data]# chmod +x expect1

间接变量引用

如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值 就称为间接变量引用

variable1的值是variable2,而variable2又是变量名,variable2的值为value, 间接变量引用是指通过variable1获得变量值value的行为
variable1=variable2
variable2=value

bash Shell提供了两种格式实现间接变量引用
eval tempvar=$ v a r i a b l e 1 t e m p v a r = variable1 tempvar= variable1tempvar={!variable1}

示例:

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

创建临时文件

  • mktemp命令:创建并显示临时文件,可避免冲突

  • mktemp [OPTION]… [TEMPLATE]

    TEMPLATE: filenameXXX
    X至少要出现三个

  • OPTION:
    -d: 创建临时目录
    -p DIR或–tmpdir=DIR:指明临时文件所存放目录位置

  • 示例:
    mktemp /tmp/testXXX
    tmpdir=`mktemp –d /tmp/testdirXXX`
    mktemp --tmpdir=/testdir testXXXXXX

安装复制文件

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

  • 示例:
    install -m 700 -o wang -g admins srcfile desfile
    install –m 770 –d /testdir/installdir

expect命令

expect 语法:
选项 :
-c:从命令行执行expect脚本,默认expect是交互地执行的
示例:expect -c 'expect “\n” {send “pressed enter\n”}

-d:可以输出输出调试信息    
示例:expect  -d ssh.exp 
  • expect中相关命令

    spawn 启动新的进程

    send 用于向进程发送字符串

    expect 从进程接收字符串

    interact 允许用户交互

    exp_continue 匹配多个字符串在执行动作后加此命令

  • expect最常用的语法(tcl语言:模式-动作)

    单一分支模式语法:

      expect “hi” {send “You said hi\n"} 
      匹配到hi后,会输出“you said hi”,并换行 
    

    多分支模式语法:

      expect "hi" { send "You said hi\n" } \    
      "hehe" { send "Hehe yourself\n" } \   
      "bye" { send "Good bye\n" } 
    
  • 匹配hi,hello,bye任意字符串时,执行相应输出。等同如下:
    expect {
    “hi” { send “You said hi\n”}
    “hehe” { send “Hehe yourself\n”}
    “bye” { send " Good bye\n"}
    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值