Linux扩展篇-shell编程(九)-shell 异常处理

1、异常退出

  • ${0}:获取当前脚本的名称
  • $?:获取函数返回值或者上一个命令的退出状态
  • set -x:开启debug调试功能

按照目前个人理解,异常分为以下几种情况:

  1. 程序处理的异常退出
    程序员判断,当前分支不满足条件,已经不需要继续向下执行
  2. 中断异常,不可预知的异常
    这种异常一般是程序员不可预料的,包含命令本省执行错误等一下低级错误。
  3. 执行成功
    这种一般是脚本按照程序员的逻辑顺利执行完成。

exception.sh脚本逻辑如下,使用时通过source方式加载到要执行的脚本中,可以选择性开启或关闭异常退出机制,详细讲解看下面的test.sh中的样例。
定义变量execption=-1、默认是-1表示中断退出或者执行成功的状态,0表示程序员主动退出的状态。

#!/bin/bash
#############################################
# 程序名:exception.sh
# 功能简介:shell异常处理
# 作者:cavan
# 日期:2023/3/20
# 修改说明:
#############################################

# 开启异常退出。当任何一行的命令执行错误,直接退出,不继续往下执行
function open_err_exit() {
    set -e
}

# 关闭异常退出。当任何一行的命令执行错误,继续往下执行
function close_err_exit() {
    set +e
}

# 处理退出的方法
function _exit() {
    exit_code=$?
    if [ "A${exception}" != 0 ]; then
        if [ "A${exit_code}" != "A0" ]; then
            _fail
        else
            _success
        fi
    fi
}

# 处理失败的方法
function _fail() {
    exception=0
    echo "脚本${0}执行异常中断,程序运行终止!"
    exit 1
}

# 处理成功的方法
function _success() {
    echo "脚本${0}执行成功,程序运行成功!"
}

# 程序开始的方法
function _start() {
    echo "脚本${0}开始执行。。。"
}

###########              Main           ##############
# exception=0 表示程序处理的异常退出
# exception=-1 表示中断异常或执行成功
exception=-1

# 捕获异常退出动作
trap _exit EXIT

# 开始执行脚本
_start
##################### END OF PROCEDURE ###############

测试开启异常退出,测试脚本:

#!/bin/bash
set -x
source ./exception.sh

# 开启异常退出
open_err_exit

# 查看一个不存在的文件
cat /home/cavan/hello.txt
echo "忽略报错,继续执行"

程序执行结果如下,开启异常退出后,脚本执行结果失败,echo "忽略报错,继续执行"不会被执行

+ source ./exception.sh
++ exception=-1
++ trap _exit EXIT
++ _start
++ echo 脚本./test.sh开始执行。。。
脚本./test.sh开始执行。。。
+ open_err_exit
+ set -e
+ cat /home/cavan/hello.txt
cat: /home/cavan/hello.txt: No such file or directory
+ _exit
+ is_exec_succ=1
+ '[' A-1 '!=' 0 ']'
+ '[' A1 '!=' A0 ']'
+ _fail
+ exception=0
+ echo 脚本./test.sh执行异常中断,程序运行终止!
脚本./test.sh执行异常中断,程序运行终止!
+ exit 1

测试关闭异常退出,测试脚本:

#!/bin/bash
set -x
source ./exception.sh

# 开启异常退出
close_err_exit

# 查看一个不存在的文件
cat /home/cavan/hello.txt
echo "忽略报错,继续执行"

程序执行结果如下,开启异常退出后,脚本执行结果失败,echo "忽略报错,继续执行"会执行

+ source ./exception.sh
++ exception=-1
++ trap _exit EXIT
++ _start
++ echo 脚本./test.sh开始执行。。。
脚本./test.sh开始执行。。。
+ close_err_exit
+ set +e
+ cat /home/cavan/hello.txt
cat: /home/cavan/hello.txt: No such file or directory
+ echo 忽略报错,继续执行
忽略报错,继续执行
+ _exit
+ is_exec_succ=0
+ '[' A-1 '!=' 0 ']'
+ '[' A0 '!=' A0 ']'
+ _success
+ echo 脚本./test.sh执行成功,程序运行成功!
脚本./test.sh执行成功,程序运行成功!

2、异常退出,清除敏感变量

定义一个数组变量,用于保存要清理的敏感变量名称,当脚本中产生敏感变量时,例如token,password等信息时,通过need_delete_params+=("password"),将变量password添加到清理数组中,当执行_exit时,如果数组的大小大于0,则执行清理动作。

#!/bin/bash
#############################################
# 程序名:exception.sh
# 功能简介:shell异常处理
# 作者:cavan
# 日期:2023/3/20
# 修改说明:
#############################################

# 定义数组,保存需要清理的变量名称
need_delete_params=()

# 开启异常退出。当任何一行的命令执行错误,直接退出,不继续往下执行
function open_err_exit() {
    set -e
}

# 关闭异常退出。当任何一行的命令执行错误,继续往下执行
function close_err_exit() {
    set +e
}

# 处理退出的方法
function _exit() {
    exit_code=$?
    if [ "A${exception}" != 0 ]; then
        if [ "A${exit_code}" != "A0" ]; then
            _fail
        else
            _success
        fi
    fi

    # 清空敏感变量,need_delete_params为数组,如果数组长度大于0,就进行清理
    if [ ${#need_delete_params[@]} -gt 0 ]; then
        echo "start to delete sensitive information"
        # 对数组去重,避免重复清理
        need_delete_params=($(awk -v RS=' ' '!a[$1]++' <<<${need_delete_params[@]}))
        del_param ${need_delete_params[@]}
    else
        echo "no need to delete sensitive information"
    fi
}

# 清理敏感变量
function del_param() {
    # 循环清除变量
    params=$*
    for param_name in ${params[@]}; do
        echo "delete param ${param_name}. "
        eval $param_name=$(eval echo '$'{"${param_name}"'//?/0}')
        unset ${param_name}
    done
}

# 处理失败的方法
function _fail() {
    exception=0
    echo "脚本${0}执行异常中断,程序运行终止!"
    exit 1
}

# 处理成功的方法
function _success() {
    echo "脚本${0}执行成功,程序运行成功!"
}

# 程序开始的方法
function _start() {
    echo "脚本${0}开始执行。。。"
}

###########              Main           ##############
# exception=0 表示程序处理的异常退出
# exception=-1 表示中断异常或执行成功
exception=-1

# 捕获异常退出动作
trap _exit EXIT

# 开始执行脚本
_start
##################### END OF PROCEDURE ###############

posted @ 2023-03-20 16:52  cavan丶keke  阅读(1711)  评论(0编辑  收藏  举报