我们组的Shell编程规范统一采用Google Shell Style Guide。
下面介绍其中需要重点关注或稍作调整的一些规范。
背景
- 使用哪种Shell
- Shell 脚本第一行必须使用Shebang语法注明使用的Shell版本,比如:
#!/bin/bash - 默认情况下使用bash。如果脚本的运行环境不支持bash,再考虑使用sh。
- 什么时候使用Shell
- Shell 只应该用作小的工具脚本。
- 如果你写的脚本大于100行,或者涉及不直观的控制逻辑,你应该改用更加结构化的编程语言。
注释
- 文件头
- 每个文件开头描述该脚本的意图。
#!/bin/bash
#
# Perform hot backups of Oracle databases.
格式
- 缩进
- 以2个空格进行缩进。不要使用Tab。
- 循环
- 把
; do和; then放在跟while,for或if同一行。
for file in "$(ls .)"; do
if [[ -f ${file} ]]; then
# do something
fi
done
- 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
- 变量展开(按照以下的优先级来考虑)
- 跟已有代码保持一致(前提是已有代码的质量得到认可)
- 将变量用引号括起来
- 单字母的shell特殊变量/位置参数等不要用括号括起来。比如:
$1, $!, $# - 其他变量都用括号括起来
特性
- 命令替换
- 使用
$(command),不要使用反括号。
# This is preferred:
var="$(command "$(command1)")"
# This is not:
var="`command \`command1\``"
TEST,[ ... ]和[[ ... ]]
- 优先使用
[[ ... ]],除非你是在写sh脚本。
- 测试字符串
- 使用引号括起字符串变量,不要使用填充字符的方式。(下面代码的最后一种情况即填充字符的方式)
# 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
- 算数运算
- 总是使用
(( ... )),除非你是在写sh脚本。
命名
- 函数名
- 小写,单词之间使用下划线隔开。
- 变量名
- 跟函数名一样,小写+下划线。
- 常量和环境变量名
- 大写,单词之间使用下划线隔开。并且应该在文件开头声明。
# Constant
readonly PATH_TO_FILES='/some/path'
# Both constant and environment
declare -xr ORACLE_SID='PROD'
- 文件名
- 小写,单词之间使用下划线隔开。
- 只读变量
- 使用
readonly或declare -r来声明只读变量,以避免误修改。
- 局部变量
- 使用
local来声明函数局部变量,以避免命名冲突或误修改等问题。
布局
- 函数位置
- 将所有函数放在文件中常量定义后面的位置。
- 函数之间不要插入可执行的代码,这样会降低可读性和可维护性。
- main函数放在所有其他函数的下面。最后一行应该是对main函数的调用:
main "$@"
命令调用
- 检查返回值
- 永远检查返回值并给出便于理解的返回信息。