目录
特殊字符16进制
| 字符 | 名称 | 十六进制 | 说明 |
|---|
| \0 | 空字符 (NUL) | 0x00 | 字符串结束符 |
| \t | 水平制表符 (TAB) | 0x09 | 制表符 |
| \n | 换行符 (LF) | 0x0A | 常用于 Unix/Linux 换行 |
| \r | 回车符 (CR) | 0x0D | 常用于 Windows 换行(CR+LF) |
| \b | 退格符 (BS) | 0x08 | 回退一格 |
| \f | 换页符 (FF) | 0x0C | 打印机换页 |
| \e | 转义符 (ESC) | 0x1B | 控制序列起始 |
| 字符 | 十六进制 | 说明 |
|---|
| 0x20 | 空格 |
| ! | 0x21 | 感叹号 |
| " | 0x22 | 双引号 |
| # | 0x23 | 井号 |
| $ | 0x24 | 美元符号 |
| % | 0x25 | 百分号 |
| & | 0x26 | 与符号 |
| ' | 0x27 | 单引号 |
| ( | 0x28 | 左括号 |
| ) | 0x29 | 右括号 |
| * | 0x2A | 星号 |
| + | 0x2B | 加号 |
| , | 0x2C | 逗号 |
| - | 0x2D | 减号/连字符 |
| . | 0x2E | 句点 |
| / | 0x2F | 斜杠 |
| : | 0x3A | 冒号 |
| ; | 0x3B | 分号 |
| < | 0x3C | 小于号 |
| = | 0x3D | 等号 |
| > | 0x3E | 大于号 |
| ? | 0x3F | 问号 |
| @ | 0x40 | At符号 |
| [ | 0x5B | 左方括号 |
| \ | 0x5C | 反斜杠 |
| ] | 0x5D | 右方括号 |
| ^ | 0x5E | 脱字符 |
| _ | 0x5F | 下划线 |
| ` | 0x60 | 反引号 |
| { | 0x7B | 左花括号 |
| | | 0x7C | 竖线 |
| } | 0x7D | 右花括号 |
| ~ | 0x7E | 波浪号 |
Shell脚本模板
#!/usr/bin/env bash
set -eEuo pipefail
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() {
if [[ ! -v ARGS_MAP["help"] ]]; then
log "执行清理操作\n"
fi
}
function die() {
log -e "$1"
exit "${2:-1}"
}
function parse_args(){
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 " ... 其他待补充帮助信息"
}
function log() {
if [[ "$#" -eq 0 ]]; then
return 0
fi
local level="${1#-}"
if [[ -v "LEVEL_MAP[$level]" ]]; then
shift
else
level='i'
fi
if [[ "$level" == 'd' && ! -v "ARGS_MAP["debug"]" ]] ; then
return 0
fi
local log_line="[$(date '+%F %T.%3N')] [${LEVEL_MAP[$level]}] $*"
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"
}
function init() {
declare -gA COLOR_MAP
if [[ -t 1 ]]; then
COLOR_MAP=(
[e]='\033[0;31m'
[w]='\033[1;33m'
[i]='\033[0m'
[d]='\033[34m'
[s]='\033[0;32m'
[n]='\033[0m'
)
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 "$@"