第三十二章 脚本编程分格
写脚本时养成结构化和系统方法的习惯。要养成在写代码前花几分钟来规划和组织你的想法。注意这节文档不是一个官方 Shell 编程风格。
32.1 非官方的Shell脚本风格
注释你的代码。这会使你的代码更容易让别人理解和赏识,同时也便于你维护。
PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
# 当你去年写下这句代码时非常的了解它在干什么事,但现在它完全是一个谜.
给脚本和函数加上描述性的头部信息
#!/bin/bash
#************************************************#
# xyz.sh #
# written by Bozo Bozeman #
# July 05, 2001 #
# #
# 清除项目文件. #
#************************************************#
E_BADDIR=65 #没有那样的目录
projectdir=/home/imeiftp #要清楚的目录
#-----------------------------------------#
# cleanup_pfiles()
# 删除指定目录里的是所有文件
# 参数:$target_directory
# 返回:成功返回0,失败返回$E_BADDIR值
#-----------------------------------------#
cleanup_pfiles()
{
if [ ! -d "$1" ];then #测试目录是否存在
echo "$1 is not a directory."
return $E_BADDIR
fi
rm -f "$1"/*
return 0 #成功
}
cleanup_pfiles $projectdir
exit 0
避免使用"魔数",它是硬编码的字符常量。用有意义的变量名来代替。这使脚本更容易理解并允许在不破坏应用的情况下做改变和更新。
if [ -f /var/log/messages ];then
...
fi
# 一年以后,你决定让脚本改为检查 /var/log/syslog.
# 那么现在就需要你手动修改脚本里每一处的要改动的代码,希望不要有你疏漏的地方.
#更好的办法是:
LOGFILE=/var/log/messages # 只需要改动一行.
if [ -f $LOGFILE ];then
...
fi
为变量和函数选择描述性的名字
fl=`ls -al $dirname` #含义含糊
file_listing=`ls -al $dirname` #更好的名字
MAXVAL=10 # 同一个脚本所有程序代码使用脚本常量.
while [ "$index" -le "$MAXVAL" ]
...
E_NOTFOUND=75 # 把错误代码的代表的变量名大写,并以"E_"开头.
if [ ! -e "$filename" ];then
echo "File $filename not found."
exit $E_NOTFOUND
fi
MAIL_DIRECTORY=/var/spool/mail/bozo # 环境变量名用大写.
export MAIL_DIRECTORY
GetAnswer() # 函数名用适当的大小写混合组成.
{
prompt=$1
echo -n $prompt
read answer
return $answer
}
GetAnswer "What is your favorite number? "
favorite_number=$?
echo $favorite_number
_uservariable=23 # 语法允许, 但不推荐.
# 用户定义的变量最好不要用下划线开头.
# 把这个留给系统变量使用更好.
用有含义和系统的方法来使用退出代码
E_WRONG_ARGS=65
...
...
exit $E_WRONG_ARGS
使用标准的参数选项
建议使用下面一组参数标志
-a | 全部:返回所有信息(包括隐藏的文件信息) |
-b | 简短:简短的版本,通常用于其他脚本 |
-c | 复制、连接等 |
-d | Daily:使用全天的信息,而不仅仅是特定实例/用户的信息 |
-e | 扩展/详细说明:(通常不包括隐藏的文件信息) |
-h | |
-l | 记录脚本的输出 |
-m | 手册:启动基本命令的手册页 |
-n | 字:仅数字数据 |
-r | 递归:目录(和/或所有子目录)中的所有文件 |
-s | 安装和文件维护:此脚本的配置文件 |
-u | 用法:脚本的调用标志列表 |
-v | 详细:人类可读的输出,或多或少是格式化的 |
-V | 版本 |
把复杂的脚本分割成简单一些的模块。
用合适的函数来实现各个功能。参考例子 34-4。
如果有简单的结构可以使用,不要使用复杂的结构。
COMMAND
if [ $? -eq 0 ];then
...
if COMMAND #更简练
...