魏蓝

以梦为马

导航

shell脚本进阶函数递归和信号捕捉

1.1)函数内部变量会和外部变量起冲突:

例:

[root@centos7 ~]# name=weilan
[root@centos7 ~]# func1(){ name=bbb; echo $name ; }
[root@centos7 ~]# func1
bbb
[root@centos7 ~]# echo $name
bbb

2)为了避免出现这种情况,我们函数内部的变量设置为本地变量

例:

[root@centos7 ~]# name=weilan
[root@centos7 ~]# func(){ local name=bbb; echo $name; }
[root@centos7 ~]# func
bbb
[root@centos7 ~]# echo $name
weilan 

local只影响函数内部的变量,不影响函数外部的变量,local变量只能在函数体内用

范例:初始化系统

[root@centos7 data]# vim functions

disable_selinux(){
        sed -i.bak 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
        action "SELINUX已禁用,重新启动后才可生效"
}
disable_firewall(){
        systemctl disable --now firewalld &> /dev/null
        action "防火墙已禁用"
}
set_ps1(){
        echo "PS1='\[\e[1;35m\][\u@\h \w \!]\$\[\e[0m\]'" > /etc/profile.d/reset.sh
        action "提示符已修改成功,请重新登录生效"
}
set_eth(){
        sed -i.bak '/GRUB_CMDLINE_LINUX=/s#"$# net.ifnames=0"#' /etc/default/grub
        grub2-mkconfig -o /boot/grub2/grub.cfg &> /dev/null
        action "网络名称已修改成功,请重新启动才能生效"
}
[root@centos7 data]# vim chushihua.sh

#!/bin/bash
. /data/functions
PS3="请选择相应的编号(1-6):"
MENU='
禁用SELINUX
关防火墙
修改提示符
修改网卡名
以上全实现
退出
'
select M in $MENU; do
case $REPLY in
1)
        disable_selinux
        ;;
2)
        distable_firewall
        ;;
3)
        set_ps1
        ;;
4)
        set_eth
        ;;
5)
        disable_selinux
        disable_firewall
        set_ps1
        set_eth
        ;;
6)
        break
        ;;
*)
        echo "请输入正确数字!"
esac
done
[root@centos7 data]# ./chushihua.sh 
1) 禁用SELINUX	3) 修改提示符	5) 以上全实现
2) 关防火墙	4) 修改网卡名	6) 退出
请选择相应的编号(1-6):5
SELINUX已禁用,重新启动后才可生效
防火墙已禁用
提示符已修改成功,请重新登录生效
网络名称已修改成功,请重新启动才能生效
请选择相应的编号(1-6):6

  

2.函数递归

函数自己调用自己,同时必须有结束函数的出口语句结束死循环

例:一个死循环递归

[root@centos7 data]# func(){ echo $i; echo "RUN func"; let i++; }

 

3.阶乘

例:用函数表达阶乘(bash)

#!/bin/bash
fact(){
        if [ $i -eq 0 -o $1 -eq 1 ]; then
                echo 1
        else
                echo $[$1*$(fact $[$1-1])]
        fi
}
fact 3

例:fork炸弹

[root@centos7 data]# bomb(){ bomb|bomb& ; }; bomb

  

4.信号捕捉trap

1)所谓信号就是比如你使用ctrl+c时,命令被取消时,就会发出一种取消信号SIGINT,随着该信号的发出,命令结果就取消了

2)查看信号类型

trap -l

 

 3)捕捉信号就是:避免外部干扰,捕获某一信号,将其自定义。

捕获信号用trap这个命令

语法:

trap '触发指令' 信号

这里的信号有三种写法:简写、全写、序号都可以

4)忽略信号的操作:

trap '' 信号

5)恢复原信号的操作

trap '-' 信号

6)列出自定义信号操作

trap -p

范例:

#!/bin/bash
trap "echo 'Press ctrl + c or ctrl + \'" int quit
trap -p
for ((i=0;i<=10;i++))
do
        sleep 1
        echo $i
done
trap ' ' int
trap -p
for((i=11;i<=20;i++))
do
        sleep 1
        echo $i
done
trap '-' int
trap -p
for((i=21;i<=30;i++))
do
        sleep 1
        echo $i
done

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

trap finish EXIT

例:

#!/bin/bash
finish () {
        echo finish is at `date +%F-%T` | tee -a /root/finish.sh
}
trap finish exit
while true; do
        echo running
        sleep 1
done

 

 

5.创建临时文件mktemp

1)我们在编脚本的时候,可能会临时创建一些文件或文件夹,脚本运行完后,这些文件夹也就不存在了,但是会引出一个问题,会和原系统文件冲突,从而导致数据丢失。为了解决此类问题,我们使用mktemp创建临时文件,可以避免冲突。

2)格式:

mktemp [OPTION]...[TEMPLATE](模板)

说明:TEMPLATE:filenameXXX,X至少要出现三个,两个会报错

例:用mktemp生成一个文件

[root@centos8 data]# mktemp fileXXX
fileLJM

3)选项:

-d:生成文件夹

例:生成一个临时文件夹在/data/

[root@centos8 data]# mktemp -d /data/tmpXXX
/data/tmpqGY

 

-p:指明临时文件或文件夹存放目录位置

例:

[root@centos8 data]# mktemp -d -p /data/ abcXXX
/data/abcWi2

 

 范例:实现文件垃圾箱功能

[root@centos7 data]# vim lajixiang.sh

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

 

 

6.安装复制文件install

1)install功能强大,相当于cp、chmod、chown、chgrp、mkdir的结合

2)格式

install [OPTION]...[-T] SOURCE DEST #单文件
install [OPTION]..SOURCE...DIRECTORY
install [OPTION]... -t DIRECTORY SOURCE
install [OPTION]... -d DIRECTORY ... #创建空目录

3)选项:

-m MODE,默认755

-o OWNER 所属者

-g GROUP 所属组

-d DIRNAME 目录

例:复制/etc/issue 为权限700,所属者wang,所属组bin,绝对路径/data/名字为a.txt

[root@centos8 ~]# install -m 700 -o wang -g bin /etc/issue /data/a.txt
[root@centos8 ~]# ll /data/a.txt
-rwx------ 1 wang bin 23 Mar  7 21:32 /data/a.txt 

例:创建一个770权限的文件夹

[root@centos8 ~]# install -m 770 -d /data/installdir/weilan
[root@centos8 installdir]# ll /data/installdir/
total 0
drwxrwx--- 2 root root 6 Mar  7 21:35 weilan 

这里需要注意的是:这里相当于mkdir -p也会将上级不存在的文件夹创建  

 

记录于2022-3-7-21:39

posted on 2022-03-07 21:38  魏蓝  阅读(89)  评论(0编辑  收藏  举报