我们组的Shell编程规范统一采用Google Shell Style Guide

下面介绍其中需要重点关注或稍作调整的一些规范。

背景

  1. 使用哪种Shell
  • Shell 脚本第一行必须使用Shebang语法注明使用的Shell版本,比如:#!/bin/bash
  • 默认情况下使用bash。如果脚本的运行环境不支持bash,再考虑使用sh。
  1. 什么时候使用Shell
  • Shell 只应该用作小的工具脚本。
  • 如果你写的脚本大于100行,或者涉及不直观的控制逻辑,你应该改用更加结构化的编程语言。

注释

  1. 文件头
  • 每个文件开头描述该脚本的意图。
#!/bin/bash
#
# Perform hot backups of Oracle databases.

格式

  1. 缩进
  • 2个空格进行缩进。不要使用Tab。
  1. 循环
  • ; do; then 放在跟while, forif 同一行。
for file in "$(ls .)"; do
  if [[ -f ${file} ]]; then
    # do something
  fi
done
  1. case语句
  • 每个case 选项(alternatives)以2个空格进行缩进。
  • 单行的选项在模式的闭括号后面、;;前面都需要有一个空格
  • 长的选项应该分行分别书写模式(pattern)、行为(actions)和;;
case "${flag}" in
  a) aflag='true' ;;
  b) bflag='true' ;;
  f) files="${OPTARG}" ;;
  v) verbose='true' ;;
  *) error "Unexpected option ${flag}" ;;
esac
case "${expression}" in
  a)
    variable="…"
    some_command "${variable}" "${other_expr}"    ;;
  absolute)
    actions="relative"
    another_command "${actions}" "${other_expr}"    ;;
  *)
    error "Unexpected expression '${expression}'"
    ;;
esac
  1. 变量展开(按照以下的优先级来考虑)
  • 跟已有代码保持一致(前提是已有代码的质量得到认可)
  • 将变量用引号括起来
  • 单字母的shell特殊变量/位置参数等不要用括号括起来。比如:$1, $!, $#
  • 其他变量都用括号括起来

特性

  1. 命令替换
  • 使用$(command),不要使用反括号。
# This is preferred:
var="$(command "$(command1)")"

# This is not:
var="`command \`command1\``"
  1. TEST, [ ... ][[ ... ]]
  • 优先使用[[ ... ]],除非你是在写sh脚本。
  1. 测试字符串
  • 使用引号括起字符串变量,不要使用填充字符的方式。(下面代码的最后一种情况即填充字符的方式)
# Do this:
if [[ "${my_var}" == "some_string" ]]; then
  do_something
fi

# -z (string length is zero) and -n (string length is not zero) are
# preferred over testing for an empty string
if [[ -z "${my_var}" ]]; then
  do_something
fi

# This is OK (ensure quotes on the empty side), but not preferred:
if [[ "${my_var}" == "" ]]; then
  do_something
fi

# Not this:
if [[ "${my_var}X" == "some_stringX" ]]; then
  do_something
fi
  1. 算数运算
  • 总是使用(( ... )),除非你是在写sh脚本。

命名

  1. 函数名
  • 小写,单词之间使用下划线隔开。
  1. 变量名
  • 跟函数名一样,小写+下划线。
  1. 常量和环境变量名
  • 大写,单词之间使用下划线隔开。并且应该在文件开头声明。
# Constant
readonly PATH_TO_FILES='/some/path'

# Both constant and environment
declare -xr ORACLE_SID='PROD'
  1. 文件名
  • 小写,单词之间使用下划线隔开。
  1. 只读变量
  • 使用readonlydeclare -r来声明只读变量,以避免误修改。
  1. 局部变量
  • 使用local来声明函数局部变量,以避免命名冲突或误修改等问题。

布局

  1. 函数位置
  • 将所有函数放在文件中常量定义后面的位置。
  • 函数之间不要插入可执行的代码,这样会降低可读性和可维护性。
  • main函数放在所有其他函数的下面。最后一行应该是对main函数的调用:main "$@"

命令调用

  1. 检查返回值
  • 永远检查返回值并给出便于理解的返回信息。