马哥29-脚本进阶

信号捕捉trap

创建1.txt 2.txt 内容分别为12345和abcde,将其合并且显示效果为1a2b3c4d5e

[root@localhost scripts-exercise]# cat 1.txt 
1
2
3
4
5
[root@localhost scripts-exercise]# cat 2.txt 
a
b
c
d
e
[root@localhost scripts-exercise]# paste 1.txt 2.txt  | tr '\t' '\n'
1
a
2
b
3
c
4
d
5
e
[root@localhost scripts-exercise]# LINE=`cat 1.txt|wc -l`
[root@localhost scripts-exercise]# for i in `seq 1 $LINE`;do INSERT=`sed -n "${i}p" 2.txt`;sed -i "$[2*i-1] a $INSERT" 1.txt ; done
[root@localhost scripts-exercise]# cat 1.txt 
1
a
2
b
3
c
4
d
5
e

trap 在shell中称之为陷阱,类似于mysql的触发器

trap '触发指令' 信号
    进程收到系统发出的指定信号后,将执行自定义指令,而不会执行原操作
trap '' 信号
    忽略信号的操作
trap '-' 信号
    恢复原信号的操作
trap -p
    列出自定义信号操作
trap finish EXIT
    当脚本退出时,执行finish函数
注:trap无法捕获kill -9 信号

设置循环1到10,捕获在此期间的组合键ctrl+c,显示press ctrl+c

#!/bin/bash
trap 'echo press ctrl+c' int
trap -p
for ((i=0;i<10;i++)) ; do
        echo $i
        sleep 1
done

在此过程中我们按ctrl+c成功出发陷阱

[root@localhost scripts-exercise]# bash trap.sh 
trap -- 'echo press ctrl+c' SIGINT
0
1
2
^Cpress ctrl+c
3
^Cpress ctrl+c
4
^Cpress ctrl+c
5
6
7
^Cpress ctrl+c
8
9

在此前基础上设置循环10到20,并且忽略ctrl+c的操作

#!/bin/bash
trap 'echo press ctrl+c' int
trap -p
for ((i=0;i<10;i++)) ; do
        echo $i
        sleep 1
done

trap '' 2
trap -p
for ((i=10;i<20;i++));do
        echo $i
        sleep 1
done

前10秒触发了组合键的信号,但是10到20期间系统忽略了我们的组合键ctrl+c的信号

[root@localhost scripts-exercise]# bash trap.sh 
trap -- 'echo press ctrl+c' SIGINT
0
1
^Cpress ctrl+c
2
^Cpress ctrl+c
3
^Cpress ctrl+c
4
^Cpress ctrl+c
5
6
7
8
9
trap -- '' SIGINT
10
^C11
^C12
^C13
^C14
^C15
16
17
18
19

设置20到30的循环,恢复我们之前忽略的ctrl+c信号的操作

#!/bin/bash
trap 'echo press ctrl+c' int
trap -p
for ((i=0;i<10;i++)) ; do
        echo $i
        sleep 1
done

trap '' 2
trap -p
for ((i=10;i<20;i++));do
        echo $i
        sleep 1
done

trap '-' sigint
trap -p
for ((i=20;i<30;i++));do
        echo $i
        sleep 1
done

显示在20到30循环期间,ctrl+c组合键起作用了,并且成功退出循环

[root@localhost scripts-exercise]# bash trap.sh 
trap -- 'echo press ctrl+c' SIGINT
0
1
^Cpress ctrl+c
2
^Cpress ctrl+c
3
^Cpress ctrl+c
4
^Cpress ctrl+c
5
^Cpress ctrl+c
6
7
8
9
trap -- '' SIGINT
10
^C11
^C12
^C13
^C14
^C15
^C16
17
18
19
20
21
22
23
^C

设置while死循环,并且定义函数为显示excute finish,在trap退出是显示函数

#!/bin/bash
finish(){
        echo excute finish
}

trap finish exit
i=0
while true ; do
        echo $i
        let i++
        sleep 1
done

我们使用组合键ctrl+c退出脚本,成功打印了excute finish

[root@localhost scripts-exercise]# bash trap_finish.sh
0
1
2
3
4
5
^Cexcute finish

数组

变量:存储单个元素的内存空间(如:mage、wang、zhang、tom)

索引:又称下标,一般使用数字表示,从0开始标识(如:0、1、2、3、)

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

注意:索引可支持使用自定义的格式,比如说字母字符,而不仅是数值格式,即为关联索引

在这里插入图片描述

bash的数组支持稀疏格式(索引不连续稀):文件的实际大小和磁盘上存储的真实大小不同
又称空洞文件(如下图)

申明数组 declare -a ARRAY_NAME 可以不申明,但建议申明

关联数组必须先申明再使用 declare -A ARRAY_NAME 关联数组

显示所有数组 declare -a

在这里插入图片描述

数组演示

创建数组title

[root@localhost scripts-exercise]# title[0]=ceo
[root@localhost scripts-exercise]# title[1]=coo
[root@localhost scripts-exercise]# title[2]=cto
[root@localhost scripts-exercise]# echo ${title[0]}
ceo
[root@localhost scripts-exercise]# echo ${title[1]}
coo
[root@localhost scripts-exercise]# echo ${title[2]}
cto

删除title数组中的索引2

[root@localhost scripts-exercise]# unset title[2]
[root@localhost scripts-exercise]# echo ${title[0]}
ceo
[root@localhost scripts-exercise]# echo ${title[2]}

[root@localhost scripts-exercise]# echo ${title[1]}
coo

给数组批量添加元素

[root@localhost scripts-exercise]# name=(mage zhang wang sun)
[root@localhost scripts-exercise]# echo ${name[0]}
mage
[root@localhost scripts-exercise]# echo ${name[1]}
zhang
[root@localhost scripts-exercise]# echo ${name[2]}
wang
[root@localhost scripts-exercise]# echo ${name[3]}
sun

交互式创建数组,添加元素

[root@localhost scripts-exercise]# read -a student
liu guan zhang
[root@localhost scripts-exercise]# echo ${student[0]}
liu
[root@localhost scripts-exercise]# echo ${student[1]}
guan
[root@localhost scripts-exercise]# echo ${student[2]}
zhang

关联数组的下标是没有规律的

[root@localhost scripts-exercise]# declare -A teacher
[root@localhost scripts-exercise]# teacher[0]=mage
[root@localhost scripts-exercise]# teacher[1]=xu
[root@localhost scripts-exercise]# teacher[2]=wang
[root@localhost scripts-exercise]# echo ${teacher[0]} 
mage
[root@localhost scripts-exercise]# echo ${teacher[1]} 
xu
[root@localhost scripts-exercise]# echo ${teacher[2]} 
wang

字符串切片

1.前提:元素字符串起始偏移量编号为0,number代表结束位置时,截取内容不包括结束位对应的字符。
2.offset 元素字符串偏移量编号 Python中的起始位置
	offset:为正数时代表从左向右截取,为负数时代表从右向左截取。
3.number 要截取元素字符串的长度 Python中的结束位置 
	number:为正数时代表截取长度,为负数则代表结束位置,当number为代表结束位置时截取内容不包括第m位
4.offset为正数时,从左向右截取:${ARRAY[@]:n:m},n为起终位置,m为截取长度
[root@localhost scripts-exercise]# num=({1..10})
[root@localhost scripts-exercise]# echo ${num[@]}
1 2 3 4 5 6 7 8 9 10
[root@localhost scripts-exercise]# echo ${num[@]:2:3}
3 4 5
[root@localhost scripts-exercise]# echo ${num[@]:2}
3 4 5 6 7 8 9 10
[root@localhost scripts-exercise]# echo ${num[@]:-2}
1 2 3 4 5 6 7 8 9 10
[root@localhost scripts-exercise]# echo ${num[@]: -2}
9 10

生成10个随机数保存于数组中,并找出其最大值最小值

#!/bin/bash
#生成10个随机数保存于数组中,并找出其最大值最小值
for((i=0;i<10;i++));do
        NUM[$i]=$RANDOM
        if [ $i -eq 0 ] ; then
                MAX=${NUM[$i]}
                MIN=$MAX
        else
                [ ${NUM[$i]} -gt $MAX ] && MAX=${NUM[$i]}
                [ ${NUM[$i]} -lt $MIN ] && MIN=${MUN[$i]}
        fi
done
echo ${MUN[*]}
echo MAX=$MIN
[root@localhost scripts-exercise]# bash title_NUM.sh 
318 7226 21905 21268 32217 15934 30686 5319 16922 15688
MAX=32217 MIN=318

字符串处理

[root@localhost scripts-exercise]# string=`getent passwd root`
[root@localhost scripts-exercise]# echo $string
root:x:0:0:root:/root:/bin/bash
#显示字符个数
[root@localhost scripts-exercise]# echo ${#string} 
31

[root@localhost scripts-exercise]# str2="mage-linux"
#显示字符个数
[root@localhost scripts-exercise]# echo ${#str2} 
10

#左--->右,从前往后跳过五个字符取至结尾
[root@localhost scripts-exercise]# echo ${str2:5} 
linux

#左--->右,从前往后跳过四个字符取一个字符
[root@localhost scripts-exercise]# echo ${str2:4:1} 
-

#右--->左,取后五个字符
[root@localhost scripts-exercise]# echo ${str2: -5} 
linux

#前---><---后,从左往右取零个字符,从右往左跳过六个字符
[root@localhost scripts-exercise]# echo ${str2: : -6} 
mage

#左<---右,从右往左取五个字符,再从右往左跳过两个字符
[root@localhost scripts-exercise]# echo ${str2: -5: -2} 
lin

#左---><---右,从左往右跳过四个字符,从右往左跳过五个字符
[root@localhost scripts-exercise]# echo ${str2:4: -5} 
-

给数组赋值命令

[root@localhost scripts-exercise]# string=`getent passwd root`
[root@localhost scripts-exercise]# echo $string
root:x:0:0:root:/root:/bin/bash

#在数组前加#号,显示字符个数
[root@localhost scripts-exercise]# echo ${#string} 
31
#左--->右,找到字符串里的第一个:,删除包含:在内之前所有字符
[root@localhost scripts-exercise]# echo ${string#*:} 
x:0:0:root:/root:/bin/bash

#左--->右,贪婪模式,找到字符串里最后一个:,删除包含:在内之前所有的字符
[root@localhost scripts-exercise]# echo ${string##*:} 
/bin/bash
[root@localhost scripts-exercise]# url="http://www.magedu.com:80"
[root@localhost scripts-exercise]# echo ${url} 
http://www.magedu.com:80
#左<---右,找到字符串里第一个:,删除包含:在内的所有字符
[root@localhost scripts-exercise]# echo ${url%:*} 
http://www.magedu.com

#左<---右,贪婪模式,找到字符串里最后一个:,删除包含:在内的所有字符
[root@localhost scripts-exercise]# echo ${url%%:*} 
http

替换数组中的字符

[root@localhost scripts-exercise]# echo ${string}
root:x:0:0:root:/root:/bin/bash
#查找所有字符串,把第一次匹配到的root替换成admin
[root@localhost scripts-exercise]# echo ${string/root/admin} 
admin:x:0:0:root:/root:/bin/bash

#贪婪模式,查找所有字符串,把所有匹配到的root替换成admin
[root@localhost scripts-exercise]# echo ${string//root/admin} 
admin:x:0:0:admin:/admin:/bin/bash

#查找所有字符串,行首匹配到的root替换成admin
[root@localhost scripts-exercise]# echo ${string/#root/admin} 
admin:x:0:0:root:/root:/bin/bash

#查找所有字符串,行尾匹配到的root替换成admin,行尾并没有符合的字符,所以没变化
[root@localhost scripts-exercise]# echo ${string/%root/admin} 
root:x:0:0:root:/root:/bin/bash

#把string中的所有小写字母转换为大写
[root@localhost scripts-exercise]# echo ${string^^} 
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH

#把string中的所有大写字母转换为小写
[root@localhost scripts-exercise]# echo ${string,,} 
root:x:0:0:root:/root:/bin/bash

变量赋值

没有配置表示没这个变量
空字符串表示变量存在但是没有赋值

在这里插入图片描述

高级变量用法

declare [选项] 变量名
-r  声明或显示只读变量
-i   将变量定义为整型数
-a  将变量定义为数组
-A  将变量定义为关联数组
-f   显示已定义的所有函数名及其内容
-F  仅显示已定义的所有函数名
-x  声明或显示环境变量和函数
-l   声明变量为小写字母 declare –l var=UPPER
-u  声明变量为大写字母 declare –u var=lower
#申明变量为小写字母
[root@localhost scripts-exercise]# declare -l name="MAGEDU" 
[root@localhost scripts-exercise]# echo $name
magedu

#申明变量为大写字母
[root@localhost scripts-exercise]# declare -u name="mege" 
[root@localhost scripts-exercise]# echo $name
MEGE

eval命令

eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。  
该命令适用于那些一次扫描无法实现其功能的变量.该命令对变量进行两次扫描
#我们想要实现的效果
[root@localhost scripts-exercise]# n=10 ; echo {1..10} 
1 2 3 4 5 6 7 8 9 10

#无法直接引用变量
[root@localhost scripts-exercise]# n=10 ; echo {1..$n} 
{1..10}

#使用eval可达到我们的预期,等于先替换了变量,再执行echo {1..10}
[root@localhost scripts-exercise]# n=10 ; eval echo {1..$n} 
1 2 3 4 5 6 7 8 9 10
[root@localhost scripts-exercise]# n=10 ; for i in `eval echo {1..$n}` ; do echo $i ; done
1
2
3
4
5
6
7
8
9
10

间接变量引用

[root@localhost scripts-exercise]# title=name
[root@localhost scripts-exercise]# name=ceo
[root@localhost scripts-exercise]# echo \$$title 
$name
#通过eval间接引用变量$name
[root@localhost scripts-exercise]# eval echo \$$title 
ceo
[root@localhost scripts-exercise]# echo ${title}
name
#除了ecal,用这种方法也可以实现
[root@localhost scripts-exercise]# echo ${!title} 
ceo

mktemp创建临时文件

mktemp命令:创建并显示临时文件,可避免冲突
mktemp [OPTION]... [TEMPLATE]
        TEMPLATE: filenameXXX
                X至少要出现三个
OPTION:
        -d: 创建临时目录
        -p DIR或--tmpdir=DIR:指明临时文件所存放目录位置
[root@localhost scripts-exercise]# mktemp sunXXX #生成sun开头后面三个随机数的文件
sunanF
[root@localhost scripts-exercise]# ls
1.txt  2.txt  sunanF  title_NUM.sh  trap_finish.sh  trap.sh
#生成wang开头后面三个随机数的文件,并将文件名赋值给file
[root@localhost scripts-exercise]# file=`mktemp wangXXX` 
[root@localhost scripts-exercise]# echo $file
wang0hz
[root@localhost scripts-exercise]# ls
1.txt  2.txt  sunanF  title_NUM.sh  trap_finish.sh  trap.sh  wang0hz
#加-d生成mage开头后面三个随机数的文件夹
[root@localhost scripts-exercise]# mktemp -d mageXXX 
magelvT
[root@localhost scripts-exercise]# ls
1.txt  2.txt  magelvT  sunanF  title_NUM.sh  trap_finish.sh  trap.sh  wang0hz
[root@localhost scripts-exercise]# mktemp -p /data/scripts-exercise/ 111XXX
/data/scripts-exercise/111h2M
[root@localhost scripts-exercise]# ls /data/scripts-exercise/
111h2M  1.txt  2.txt  magelvT  sunanF  title_NUM.sh  trap_finish.sh  trap.sh  wang0hz

[root@localhost scripts-exercise]# mktemp /data/scripts-exercise/222XXX
/data/scripts-exercise/222czV
[root@localhost scripts-exercise]# ls /data/scripts-exercise/
111h2M  222czV  magelvT  title_NUM.sh    trap.sh
1.txt   2.txt   sunanF   trap_finish.sh  wang0hz

install安装复制文件

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
[root@localhost scripts-exercise]# ll
total 20
-rw------- 1 root root   0 Oct 31 10:39 111h2M
-rw-r--r-- 1 root root  20 Oct 30 19:46 1.txt
-rw------- 1 root root   0 Oct 31 10:40 222czV
-rw-r--r-- 1 root root  10 Oct 30 19:17 2.txt
drwx------ 2 root root   6 Oct 31 10:31 magelvT
-rw------- 1 root root   0 Oct 31 10:29 sunanF
-rw-r--r-- 1 root root 320 Oct 30 21:43 title_NUM.sh
-rw-r--r-- 1 root root 143 Oct 30 20:26 trap_finish.sh
-rw-r--r-- 1 root root 239 Oct 30 20:25 trap.sh
-rw------- 1 root root   0 Oct 31 10:30 wang0hz

#复制1.txt到/data/scripts-exercise/下改名为333.txt
#更改属主、属组为sun
#设置文件权限为777
[root@localhost scripts-exercise]# install -o sun -g sun -m 777 1.txt /data/scripts-exercise/333.txt 
[root@localhost scripts-exercise]# ll
total 24
-rw------- 1 root root   0 Oct 31 10:39 111h2M
-rw-r--r-- 1 root root  20 Oct 30 19:46 1.txt
-rw------- 1 root root   0 Oct 31 10:40 222czV
-rw-r--r-- 1 root root  10 Oct 30 19:17 2.txt
-rwxrwxrwx 1 sun  sun   20 Oct 31 10:50 333.txt
drwx------ 2 root root   6 Oct 31 10:31 magelvT
-rw------- 1 root root   0 Oct 31 10:29 sunanF
-rw-r--r-- 1 root root 320 Oct 30 21:43 title_NUM.sh
-rw-r--r-- 1 root root 143 Oct 30 20:26 trap_finish.sh
-rw-r--r-- 1 root root 239 Oct 30 20:25 trap.sh
-rw------- 1 root root   0 Oct 31 10:30 wang0hz

expect命令

expect 语法:
expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
选项
        -c:从命令行执行expect脚本,默认expect是交互地执行的
        示例:expect -c 'expect "\n" {send "pressed enter\n"}
        -d:可以输出输出调试信息
        示例:expect -d ssh.exp
expect中相关命令
        - spawn 启动新的进程   #激活某个程序
	- send 用于向进程发送字符串  #捕获关键字
	- expect 从进程接收字符串   #发送你想发送的字符串
	- interact 允许用户交互
        - xp_continue 匹配多个字符串在执行动作后加此命令
     

示例

#!/usr/bin/expect
spawn ssh 192.168.8.100
expect {
        "yes/no" { send "yes\n";exp_continue }
        "password" { send "magedu\n" }
}
interact
#expect eof

示例 变量

#!/usr/bin/expect
set ip 192.168.8.100
set user root
set password magedu
set timeout 10
spawn ssh $user@$ip
expect {
        "yes/no" { send "yes\n";exp_continue }
        "password" { send "$password\n" }
}
interact

示例 位置参数

#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $user@$ip
expect {
        "yes/no" { send "yes\n";exp_continue }
        "password" { send "$password\n" }
}
interact
#./ssh3.exp 192.168.8.100 root magedu

示例 执行多个命令

#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
set timeout 10
spawn ssh $user@$ip
expect {
        "yes/no" { send "yes\n";exp_continue }
        "password" { send "$password\n" }
}
expect "]#" { send "useradd haha\n" }
expect "]#" { send "echo magedu |passwd --stdin haha\n" }
send "exit\n"
expect eof
#./ssh4.exp 192.168.8.100 root magedu

shell脚本调用expect

#!/bin/bash
ip=$1
user=$2
password=$3
expect <<EOF
set timeout 20
spawn ssh $user@$ip
expect {
        "yes/no" { send "yes\n";exp_continue }
        "password" { send "$password\n" }
}
expect "]#" { send "useradd hehe\n" }
expect "]#" { send "echo magedu |passwd --stdin hehe\n" }
expect "]#" { send "exit\n" }
expect eof
EOF
#./ssh5.sh 192.168.8.100 root magedu
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值