shell编码规范

Shell 编程规范:保证脚本可读性、可维护性、可移植性和安全性的核心准则
1.文件基础规范
  (1)脚本头部(Shebang)
     必须以#!/bin/bash(或 #!/bin/sh,适配 POSIX 标准)开头,明确指定解释器,避免依赖系统默认Shell
  (2)文件命名与编码
     命名:小写字母+下划线(蛇形命名法),后缀为 .sh(如 backup_mysql.sh),禁止使用空格、特殊字符或大写字母。命名需 “见名知意”,避免缩写
     编码:统一使用 UTF-8,避免中文乱码(可通过 set fileencoding 验证)。
     权限:脚本执行权限设为 755(chmod 755 script.sh),避免过度权限(如 777)。
  (3)脚本说明注释(必须包含)
     头部注释需说明脚本功能、作者、创建时间、参数说明、依赖等,示例:
2.语法与编码规范
  (1)严格模式(推荐启用)
     脚本开头启用严格模式,捕获未定义变量、命令执行失败等问题,提升健壮性:
  (2)缩进与换行/空格使用
     a.缩进:统一使用 4 个空格(禁止 Tab 键,避免跨编辑器显示不一致)。
     b.换行:每行代码不超过 80 个字符(超长时换行,换行符后加缩进);运算符 / 管道符 | 后换行,且后续行缩进一层:
     c.空行:脚本头部注释后空 1 行;函数之间空 1 行;逻辑块(如条件、循环)前后空 1 行(简短逻辑可省略)。
     d.空格: 运算符两侧加空格:=、==、&&、||、+、- 等;逗号、分号后加空格;括号内侧不加空格:
  (3)变量规范
     命名:小写字母 + 下划线(如 backup_dir),禁止使用大写(系统环境变量通常大写,避免冲突)。
     定义:变量赋值时等号两侧无空格(name="value",而非 name = "value")。
     引用:所有变量引用必须加双引号("$var"),避免空格、通配符解析错误:
     常量:全大写+下划线(readonly),用 readonly 或 declare -r:如 readonly MAX_BACKUP_DAYS=7
     临时变量: 前缀加 tmp_ ,如:tmp_file
     数组:定义或引用数组时使用规范格式,如:
          # 数组定义(元素带空格时必须加引号):backup_dbs=("test_db" "prod_db" "user_db")
          # 数组引用(遍历所有元素,保留空格):for db in "${backup_dbs[@]}"; do ...
  (4)函数规范
     命名:小写字母 + 下划线,动词开头(如 check_mysql_status)。
     结构:函数必须有注释说明功能、入参、返回值,示例:
     函数定义必须置顶(或在调用前),禁止先调用后定义;
     函数内优先使用局部变量(local),避免污染全局变量:如函数内加local file="$1" # 局部变量,仅函数内有效
     函数返回值:仅用0(成功)非0(失败),复杂结果通过 echo 输出并捕获:
     调用:函数调用时参数传递清晰,避免隐式依赖全局变量。
  (5)条件判断
     优先使用 [[ ]](Bash 扩展)替代 [ ] 或 test,支持正则、逻辑运算符(&&/||(而非 -a/-o)),更安全:
     文件判断常用运算符:
          -f:是否为普通文件 -d:是否为目录
          -x:是否可执行 -s:文件是否非空
     多条件分支:case 语句格式规范
  (6)循环规范
     避免无边界循环,循环变量命名清晰:
     遍历数组时使用 "${array[@]}" 避免空格分割问题
  (7)输出与日志
     标准输出(stdout)用于正常信息,标准错误(stderr)用于错误信息:
     生产脚本建议记录日志,而非直接输出到终端:
  (8)重定向与管道
     错误输出(stderr)统一重定向到指定位置,避免混杂到标准输出。如:# 静默执行(屏蔽所有输出) /usr/bin/rm -f "$tmp_file" >/dev/null 2>&1
     管道命令避免多层嵌套(超过 3 层建议拆分),提升可读性。该脚本需拆分:cat access.log | grep "POST" | awk '{print $7}' | sort | uniq -c | head -10
3.安全规范
  (1)路径与命令安全
     所有命令使用绝对路径(如 /usr/bin/mysql 而非 mysql),避免 PATH 劫持:
          # 错误 mysql -e "backup"
          # 正确 /usr/bin/mysql -e "backup"
     避免使用 eval(易注入)、set -i(交互模式)等危险命令。
  (2)参数校验
     脚本入参必须校验,如检查参数数量、合法性:
if [[ $# -ne 2 ]]; then
echo "使用说明: $0 [数据库名] [备份目录]" >&2
exit 1
fi
db_name="$1"
backup_dir="$2"
     # 校验备份目录是否存在
if [[ ! -d "$backup_dir" ]]; then
echo "ERROR: 备份目录 $backup_dir 不存在" >&2
exit 1
fi
  (3)权限控制
     避免以 root 运行脚本,仅在必要时使用 sudo,且限定最小权限。
     临时文件使用 /tmp/[脚本名].$$($$ 为进程 ID),避免覆盖或劫持:
     TMP_FILE="/tmp/backup_mysql.$$"
     trap 'rm -f "$TMP_FILE"' EXIT # 脚本退出时删除临时文件
  (4)避免硬编码敏感信息
     密码、密钥等敏感信息不直接写在脚本中,通过环境变量或配置文件读取

4.可维护性与性能
  (1)模块化:
     将通用功能抽离为函数或独立脚本,避免重复代码。
  (2)注释规范:
     复杂逻辑必须加注释,说明 “为什么这么做”(而非 “做了什么”)。
     临时注释(如调试)使用 # TODO 标记,上线前清理。
     脚本头部注释:见「Shell 编程规范」的头部模板,必须包含功能、作者、使用说明等核心信息
     函数注释:函数上方注释,说明功能、入参、返回值(示例见前文)
     行内注释:代码右侧,# 后加 1 个空格,注释简短(不超过 50 字符)
     块注释:复杂逻辑前的多行注释,每行以 # 开头,空行分隔
  (3)性能优化:
     避免频繁创建子进程(如循环中调用 echo/cat)。
     大文件处理优先使用 awk/sed 而非 Shell 循环。
  (4)兼容性:
     如需适配多系统,避免使用 Bash 特有语法(如 [[ ]]),改用 POSIX 标准语法([ ])。
     脚本开头可检查 Bash 版本:
if [[ ${BASH_VERSION%%.*} -lt 4 ]]; then
echo "ERROR: 需要Bash 4.0以上版本" >&2
exit 1
fi
5.调试与测试
  (1)调试技巧:
     开发时启用 set -x 打印执行命令,或使用 bash -x script.sh 运行脚本。
     使用 trap 'echo "Error at line $LINENO"' ERR 捕获错误行号。
  (2)测试场景:
     测试空参数、非法参数、文件不存在、权限不足等异常场景。
     生产环境上线前先在测试环境验证。

6.常见的几个错误
     错误类型 错误示例 正确写法
     变量未加双引号 rm -rf $dir/* rm -rf "$dir"/*
     等号两侧加空格 name = "test" name="test"
     使用 == 赋值 if [[ $var == "test" ]] 赋值用 =,判断用 ==(此处正确)
     循环遍历空值 for f in $(ls $dir) for f in "$dir"/*
     忽略命令返回值 mysql -e "backup" if ! mysql -e "backup"; then ...

 

posted on 2025-12-13 14:44  枫飘过的天1  阅读(1)  评论(0)    收藏  举报