Linux扩展篇-shell编程(九)-shell 异常处理
1、异常退出
- ${0}:获取当前脚本的名称
- $?:获取函数返回值或者上一个命令的退出状态
- set -x:开启debug调试功能
按照目前个人理解,异常分为以下几种情况:
- 程序处理的异常退出
程序员判断,当前分支不满足条件,已经不需要继续向下执行 - 中断异常,不可预知的异常
这种异常一般是程序员不可预料的,包含命令本省执行错误等一下低级错误。 - 执行成功
这种一般是脚本按照程序员的逻辑顺利执行完成。
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 ###############