Linux3月7日-shell脚本进阶函数


函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程,它与shell程序形式上相似,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分。

脚本函数三种写法

[root@rocky8 ~]# help function
function: function name { COMMANDS ; } or name () { COMMANDS ; }
    Define shell function.
    
    Create a shell function named NAME.  When invoked as a simple command,
    NAME runs COMMANDs in the calling shell's context.  When NAME is invoked,
    the arguments are passed to the function as $1...$n, and the function's
    name is in $FUNCNAME.
    
    Exit Status:
    Returns success unless NAME is readonly.
#语法一:
function (){
   ...函数体...
}

#语法二:
function func_name{
   ...函数体...
}

#语法三:
function func_name(){
   ...函数体...
}

在这里插入图片描述

信号捕捉trap

在 Linux 系统中,信号是一种进程间通信的机制,允许进程通过信号来通知或中断其他进程的执行。信号捕捉(Signal Handling)是指进程对信号进行响应的机制,可以选择忽略、处理或终止信号。

trap命令可以捕捉信号,修改信号原来的功能,实现自定义功能。

[root@rocky ~]# help trap
trap: trap [-lp] [[arg] signal_spec ...]
    Trap signals and other events.
    
    Defines and activates handlers to be run when the shell receives signals or other conditions.
    
    ARG is a command to be read and executed when the shell receives the signal(s) SIGNAL_SPEC.
    If ARG is absent (and a single SIGNAL_SPEC is supplied) or `-', 
    each specified signal is reset to its original value.  
    If ARG is the null string each SIGNAL_SPEC is ignored by the shell and by the commands it invokes.
    
    If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell.  
    If a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.  
    If a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a
    script run by the . or source builtins finishes executing.  A SIGNAL_SPEC
    of ERR means to execute ARG each time a command's failure would cause the
    shell to exit when the -e option is enabled.
    
    If no arguments are supplied, trap prints the list of commands associated
    with each signal.
    
    Options:
      -l	print a list of signal names and their corresponding numbers
      -p	display the trap commands associated with each SIGNAL_SPEC
    
    Each SIGNAL_SPEC is either a signal name in <signal.h> or a signal number.
    Signal names are case insensitive and the SIG prefix is optional.  A
    signal may be sent to the shell with "kill -signal $$".
    
    Exit Status:
    Returns success unless a SIGSPEC is invalid or an invalid option is given.

为什么我们按下ctrl+c键就能结束linux当前正在运行的进程,比如ping命令默认是一直进行ping,当你按下ctrl+c时就结束了ping,为什么会这样?其实是ctrl+c向ping发送了一个停止的信号,可以使用“trap -l”查看所有的信号
在这里插入图片描述
在这里插入图片描述

#列出所有信号
trap -l

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

#列出自定义信号操作
trap -p

#当脚本退出时,执行finish函数
trap finish EXIT

信号捕捉的应用:将来在程序执行时,不希望被ctrl+c这样的异常突然终止掉程序。信号捕捉工具就是trap,trap是内部命令,内部命令通过help查看帮助。外部命令则可以通过man查看。
在这里插入图片描述

#! /bin/bash
# 捕获2信号 2信号是: 2) SIGINT 
trap 'echo 删除根系统,不能中断' 2
while true; do
        echo "正在删除系统中,请稍后!"
        sleep 1
done

在这里插入图片描述
安全退出

#! /bin/bash
  
finish(){
    echo "Finish at `date +%F_%T`" | tee -a /root/finish.log
}

trap finish exit

while true ;do
     echo running
     sleep 1
done

在这里插入图片描述
在这里插入图片描述

创建临时文件mktemp

mktemp命令用于创建显示临时文件,可避免冲突。


mktemp [option]...[TEMPLATE]
#说明:template: filenameXXXX x至少要出现三个

在这里插入图片描述
在这里插入图片描述
编写"rm.sh"脚本实现手工制作垃圾箱

#! /bin/bash
DIR=`mktemp -d /tmp/trash-$(date +%F_%H-%M-%S)xxxxxx`
mv $* $DIR
echo $* is move to $DIR

定义一个rm的别名,将’'rm.sh"脚本赋值给rm这个别名。
在这里插入图片描述在这里插入图片描述

安装复制文件install

install 功能相当于cp,chmod,chown,chgrp,mkdir等相关命令的集合
在这里插入图片描述
在这里插入图片描述

交互式转化批处理工具expect

expect是由Don Libes基于Tcl(Tool Command Language)语言开发的,主要应用于自动化交互式操作的场景,借助expect处理交互的命令,可以将交互过程如:ssh登录,ftp登录写在一个脚本上,使之自动化完成,尤其适用于需要多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率。expect需要安装 yum -y install except

交互式命令:需要你输入yes/no才能执行下一步的操作。

expect中相关命令
·spawn         启动新的进程
·expect        从进程接收字符串
·send          用于向进程发送字符串
·interact      运行用户交互
·exp_continue  匹配多个字符串在执行动作后加次命令

在这里插入图片描述
可以认为expect就是一种独立的脚本编程语言,则它的首行机制就是“/usr/bin/expect”

#!/usr/bin/expect
spawn scp /etc/redhat-release 10.0.0.201:/data
expect {
     "yes/no" { send "yes\n";exp_continue }
     "password" { send "123456\n"}
}
expect eof

#此脚本是将当前机器上的linux版本信息远程拷贝到10.0.0.201机器上,并在需要交互yes时,自动输入yes,并在需要输入201机器上的密码时,自动输入密码

因为不是/bin/bash了,所以expect1的执行就只能是赋予执行权限之后执行了。
在这里插入图片描述
回到交互式(interact)

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

在这里插入图片描述
expect 通过set赋值变量

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

expect 位置参数,(执行脚本实,后面的参数的位置得和脚本里定义的参数的位置保持一直)

#!/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_contiune }
		"password" { send "$password\n"}
}
interact

在这里插入图片描述
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 123456 | passwd --stdin hehe\n" }
expect "]#" { send "exit\n" }
expect eof
EOF

#一定记得expect和{之间有空格啊,不然就报invalid
#invalid command name "expect{"
#    while executing
#"expect{"

在这里插入图片描述
在这里插入图片描述
在多个机器201,216,217上,批量创建test账号

#!/bin/bash
NET=10.0.0
user=root
password=123456
IPLIST="
201
216
217
"
for ID in $IPLIST;do
ip=$NET.$ID

expect <<EOF
set timeout 20
spawn ssh $user@$ip
expect {
      "yes/no" { send "yes\n";exp_continue }
      "password" { send "$password\n" }
}
expect "]#" { send "useradd test\n" }
expect "]#" { send "exit\n" }
#关闭selinux
#expect "]#" { send "sed -i ‘s/^SELINUX=enforcing/SELINUX=disabled/’ /etc/selinux/config\n" }
#expect "]#" { send "setenforce 0\n" }
expect eof
EOF
done
#批量创建test账号成功
[root@rocky8 scripts]# bash expect6.sh 
spawn ssh root@10.0.0.201
root@10.0.0.201's password: 
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Tue Mar 14 14:39:27 2023 from 10.0.0.210
[root@centos8 ~]# useradd test
[root@centos8 ~]# exit
logout
Connection to 10.0.0.201 closed.
spawn ssh root@10.0.0.216
The authenticity of host '10.0.0.216 (10.0.0.216)' can't be established.
ECDSA key fingerprint is SHA256:mZPxf2BlCHWGFGOySe3SIqZz4cKNlqJZyBsl63kbGEg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.216' (ECDSA) to the list of known hosts.
root@10.0.0.216's password: 
Last login: Tue Mar 14 15:01:17 2023 from 10.0.0.1
[root@centos7 ~]# useradd test
[root@centos7 ~]# exit
logout
Connection to 10.0.0.216 closed.
spawn ssh root@10.0.0.217
The authenticity of host '10.0.0.217 (10.0.0.217)' can't be established.
ECDSA key fingerprint is SHA256:o4LXS6D+DywH8JOjcem8/f4wcRXkOMQ7TCUipw+9aeM.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.217' (ECDSA) to the list of known hosts.
root@10.0.0.217's password: 
Last login: Tue Mar 14 15:01:28 2023 from 10.0.0.1
[root@rocky8 ~]# useradd test
[root@rocky8 ~]# exit
logout
Connection to 10.0.0.217 closed.
[root@rocky8 scripts]# 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

shell脚本数组array

变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组名和索引
   索引的编号从0开始,属于述职引用
   索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引。bash4.0版本之后开始支持。
  
#普通数组可以不事先声明,直接使用
declare -a array_name
#关联数组必须先声明,再使用
declare -A array_name
#注意两者不可相互转换

declare 声明和查看数组变量, unset:删除数组
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
范例:生产10个随机数保存于数组中,并找出其最大只和最小值

#!/bin/bash
declare -i min max
declare -a nums
for ((i=0;i<10;i++));do
        nums[$i]=$RANDOM
        [ $i -eq 0 ] && min=${nums[0]} && max=${nums[0]} && continue
        [ ${nums[$i]} -gt $max ] && max=${nums[$i]} && continue
        [ ${nums[$i]} -lt $min ] && min=${nums[$i]}
done
echo "All number are ${nums[*]}"
echo "Max is $max"
echo "Min is $min"

在这里插入图片描述

基于模式取子串

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

#从var变量的值中删除以word开头的部分
${var#word}

#同上,贪婪模式,不同的是,删除的是字符串开头至最后一次有word指定的字符之间的所有内容,即贪婪模式,以最后一个word为界删左留右
${var##*word}
${var##word}

#与上相反,从右侧的字符开始向左删,,即贪婪模式,以从右向左的最后一个word为界删右留左
${var%%*word}
${var%%word}

在这里插入图片描述
贪婪模式
贪婪模式的应用,将来编译安装nginx等软件时,可以直接获取软件下载链接(http://nginx.org/download/nginx-1.23.3.tar.gz)后面的包名(nginx-1.23.3.tar.gz),获取包名后就可以直接做解压等后续的操作了

在这里插入图片描述
在这里插入图片描述
从右往左删
在这里插入图片描述
查找替换

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

在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值