通用shell脚本模板
前言
自己在工作中,比较喜欢使用
shell脚本来完成一些自动化的工作,毕竟作为程序员,能自动完成的就绝不手动完成。
每次自己临时写一个
shell脚本,只为了完成业务逻辑。但有些通用的功能,每次都现写又觉得麻烦且费时,比如记录日志,解析脚本参数等。因此就想写一个通用的shell模板,提供基础且常用的功能,这样让自己只专注于编写业务逻辑,而不需要花费太多时间在基础通用功能上。
一个完整的 shell 脚本通常应该具备以下功能:
- 具备完整的日志记录
- 控制日志输出级别
- 解析脚本参数
- 在脚本结束时自动清理临时文件或目录
- 输出彩色日志
- 响应系统发出的各类信号
- ...
脚本内容
- 下面在自己写的一个shell模板,提供大家使用,有好的建议和写法欢迎在评论区分享。
#!/usr/bin/env bash
set -eEuo pipefail
# =========== 脚本说明 ===========
# 请修改工作目录 WORK_DIR 和日志文件 LOG_FILE
# 使用方式: ./template.sh
# 参数:
# -v: 开启 debug 日志
#
# =========== 配置区域 ===========
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
readonly WORK_DIR="$SCRIPT_DIR" # 工作目录
readonly LOG_FILE="$WORK_DIR/script.log" # 日志文件
# =========== 主函数 ===========
function main() {
# 切换到工作目录
cd "$WORK_DIR" || die "无法进入目录: $WORK_DIR"
# 业务逻辑
log "业务逻辑开始"
ls
log -s "业务逻辑结束"
}
# =========== 清理函数 ===========
function cleanup() {
# 清理临时文件、释放资源等
# rm -f "$TEMP_FILE" 2>/dev/null || true
if [[ ! -v ARGS_MAP["help"] ]]; then
log "执行清理操作\n"
fi
}
# =========== 工具函数 ===========
function die() {
log -e "$1"
exit "${2:-1}"
}
# =========== 解析参数 ===========
function parse_args(){
# 参数列表MAP, 形如 [d] = "/path/dir"
declare -gA ARGS_MAP
while getopts ":vh" opt; do
case "$opt" in
h) ARGS_MAP["help"]="true" ;;
v) ARGS_MAP["debug"]="true" ;;
\?) die "无效选项:$OPTARG" ;;
:) die "选项 $OPTARG 缺少参数" ;;
esac
done
}
# =========== 打印帮助 ===========
function print_help_info(){
echo "Usage: $0 [OPTIONS] [ARGS]"
echo "Options:"
echo " -h 显示帮助信息"
echo " -v 显示脚本执行过程详细信息"
echo " ... 其他待补充帮助信息"
}
# =========== 日志函数 ===========
# 使用方式:log -d "xxx"
function log() {
if [[ "$#" -eq 0 ]]; then
return 0
fi
local level="${1#-}"
# 检测 LEVEL_MAP 是否存在键 level
if [[ -v "LEVEL_MAP[$level]" ]]; then
shift
else
level='i' # 默认 INFO 级别
fi
# DEBUG 级别未开启
if [[ "$level" == 'd' && ! -v "ARGS_MAP["debug"]" ]] ; then
return 0
fi
# 构建日志行
local log_line="[$(date '+%F %T.%3N')] [${LEVEL_MAP[$level]}] $*"
# 只有 SUCCESS 作为输出,其他写入 stderr
if [[ "$level" == 's' ]]; then
echo -e "${COLOR_MAP[$level]}$log_line${COLOR_MAP['n']}"
elif [[ -t 2 ]]; then
echo -e "${COLOR_MAP[$level]}$log_line${COLOR_MAP['n']}" >&2
else
echo -e "$log_line" >&2
fi
# 写入日志文件
echo -e "$log_line" >> "$LOG_FILE"
}
# ========= 初始化设置 =========s
function init() {
# 颜色数组
declare -gA COLOR_MAP
if [[ -t 1 ]]; then
COLOR_MAP=(
[e]='\033[0;31m' # Red
[w]='\033[1;33m' # Yellow
[i]='\033[0m' # No color
[d]='\033[34m' # Blue
[s]='\033[0;32m' # Green
[n]='\033[0m' # No color
)
fi
# 日志级别
declare -gA LEVEL_MAP=(
[e]='ERROR'
[w]='WARN'
[i]='INFO'
[d]='DEBUG'
[s]='SUCCESS'
)
# 解析参数
parse_args "$@"
# 打印帮助信息
if [[ -v ARGS_MAP["help"] ]]; then
print_help_info
exit 0
fi
log -d "检查工作目录"
if [[ ! -d "$WORK_DIR" ]]; then
die "工作目录不存在: $WORK_DIR"
fi
log -d "检查日志文件"
if [[ ! -e "$LOG_FILE" ]]; then
log -w "新建日志文件$LOG_FILE"
touch "$LOG_FILE"
fi
}
# =========== 信号处理 ===========
function handle_signal() {
errorcode="$?"
if [[ $errorcode -ne 0 ]]; then
log -e "脚本非正常退出: 错误码: $errorcode, 行号: $LINENO, 命令: $BASH_COMMAND"
elif [[ ! -v ARGS_MAP["help"] ]]; then
log "脚本执行结束"
fi
# 执行清理
cleanup
}
# =========== 信号捕获 ===========
trap 'handle_signal $? $LINENO $BASH_COMMAND' EXIT
# =========== 初始化 ===========
init "$@"
log -d "脚本初始化完成"
# ========= 执行主函数 ==========
main "$@"
内容解释
配置
-
脚本中提供的配置区域,需要修改的是工作目录
WORK_DIR,默认是脚本所在的目录 -
也可自定义脚本日志的输出路径
LOG_FILE。BASH_SOURCE是shell脚本中的一个内置数组变量,表示shell脚本的调用层级。例如:outer.sh内部执行inner.sh,则${BASH_SOURCE[0]}表示的是当前脚本名inner.sh,而${BASH_SOURCE[1]}表示调用的脚本名称outer.sh。与$0区别是:$0表示的是当前使用的shell名称(如bash, sh)。后面会专门出一期shell常见的内置变量。
主要函数
-
main()中是写业务逻辑的地方。 -
cleanup()中可以进行一些清理操作,比如删除临时文件。 -
parse_args()中是一个解析脚本参数的函数,解析结果存入ARGS_MAP关联数组。getopts是内置的一个专门用类解析参数的函数,只能处理短选项参数,但也足够用了。 -
print_help_info()提供了脚本的帮助说明,如有需要可在此处扩展。 -
log()提供了记录日志的功能。- 使用方式
log [-d] "xxx",提供了不同的日志级别(默认info级别),不同级别使用不同的颜色输出: -e:error,红色-w:warn,黄色-i:info,无颜色-d:debug,蓝色-s:success,绿色(主要用于输出成功执行的日志信息)
- 使用方式
-
init()执行一些初始化操作:定义颜色数组,日志级别数组,前置检查等。 -
handle_signal()处理操作系统的信号,脚本出现的运行错误会被trap捕获,自动定位错误的位置 -
脚本先执行
init函数,完成初始化准备工作,然后把脚本的参数全部传给main函数main "$@"执行业务逻辑。
结束语
- 这只是自己使用的脚本模板,分享出来希望能帮助到需要的同学。如有好的建议,欢迎评论区补充。
- 欢迎大家关注我的微信公众号【扶锐随笔】
![3f30b7eef45e37ccfa179b30e3123322]()

浙公网安备 33010602011771号