马哥29-脚本进阶

mac2024-03-30  27

文章目录

信号捕捉trap数组数组演示字符串切片字符串处理变量赋值eval命令间接变量引用mktemp创建临时文件install安装复制文件expect命令示例示例 变量示例 位置参数示例 执行多个命令shell脚本调用expect

信号捕捉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)