当前位置: 首页 > 文档资料 > Shell 中文文档 >

第32章. 脚本编程风格

优质
小牛编辑
120浏览
2023-12-01

写脚本时养成结构化和系统方法的习惯. 即使你在信封背后随便做一下草稿也是有益的,要养成在写代码前花几分钟来规划和组织你的想法.

这儿是一些风格的指南. 注意这节文档不是想成为一个官方Shell编程风格.

32.1. 非官方的 Shell 脚本风格

注释你的代码.这会使你的代码更容易让别人理解和赏识,同时也便于你维护.

   1 PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
   2 # 当你去年写下这句代码时非常的了解它在干什么事,但现在它完全是一个谜.
   3 # (摘自 Antek Sawicki的"pw.sh" 脚本.)

给脚本和函数加上描述性的头部信息.

   1 #!/bin/bash
   2
   3 #************************************************#
   4 #                   xyz.sh                       #
   5 #           written by Bozo Bozeman              #
   6 #                July 05, 2001                   #
   7 #                                                #
   8 #                   清除项目文件.                #
   9 #************************************************#
  10
  11 E_BADDIR=65                       # 没有那样的目录.
  12 projectdir=/home/bozo/projects    # 要清除的目录.
  13
  14 # --------------------------------------------------------- #
  15 # cleanup_pfiles ()                                         #
  16 # 删除指定目录里的所有文件.                                 #
  17 # 参数: $target_directory                                   #
  18 # 返回: 成功返回0 , 失败返回$E_BADDIR值.                    #
  19 # --------------------------------------------------------- #
  20 cleanup_pfiles ()
  21 {
  22   if [ ! -d "$1" ]  # 测试目标目录是否存在.
  23   then
  24     echo "$1 is not a directory."
  25     return $E_BADDIR
  26   fi
  27
  28   rm -f "$1"/*
  29   return 0   # 成功.
  30 }
  31
  32 cleanup_pfiles $projectdir
  33
  34 exit 0

确认 #!/bin/bash在脚本的第一行,在任何头部注释行之前.

避免使用 "魔数,"

[1]

它是硬编码的字符常量. 用有意义的变量名来代替. 这使脚本更容易理解并允许在不破坏应用的情况下做改变和更新.

   1 if [ -f /var/log/messages ]
   2 then
   3   ...
   4 fi
   5 # 一年以后,你决定让脚本改为检查 /var/log/syslog.
   6 # 那么现在就需要你手动修改脚本里每一处的要改动的代码,
   7 # 希望不要有你疏漏的地方.
   8
   9 # 更好的办法是:
  10 LOGFILE=/var/log/messages  # 只需要改动一行.
  11 if [ -f "$LOGFILE" ]
  12 then
  13   ...
  14 fi

为变量和函数选择描述性的名字.

   1 fl=`ls -al $dirname`                 # 含义含糊.
   2 file_listing=`ls -al $dirname`       # 更好的名字.
   3
   4
   5 MAXVAL=10   # 同一个脚本所有程序代码使用脚本常量.
   6 while [ "$index" -le "$MAXVAL" ]
   7 ...
   8
   9
  10 E_NOTFOUND=75                        #  把错误代码的代表的变量名大写U,
  11                                      # +并以"E_"开头.
  12 if [ ! -e "$filename" ]
  13 then
  14   echo "File $filename not found."
  15   exit $E_NOTFOUND
  16 fi
  17
  18
  19 MAIL_DIRECTORY=/var/spool/mail/bozo  # 环境变量名用大写.
  20 export MAIL_DIRECTORY
  21
  22
  23 GetAnswer ()                         # 函数名用适当的大小写混合组成.
  24 {
  25   prompt=$1
  26   echo -n $prompt
  27   read answer
  28   return $answer
  29 }
  30
  31 GetAnswer "What is your favorite number? "
  32 favorite_number=$?
  33 echo $favorite_number
  34
  35
  36 _uservariable=23                     # 语法允许, 但不推荐.
  37 # 用户定义的变量最好不要用下划线开头.
  38 # 把这个留给系统变量使用更好.

用有含义和系统的方法来使用退出代码(exit codes).

   1 E_WRONG_ARGS=65
   2 ...
   3 ...
   4 exit $E_WRONG_ARGS

也参考附录 D.

最后建议在脚本中使用/usr/include/sysexits.h的退出码, 虽然它们主要由 C 和 C++语言编程时使用.

使用标准的参数选项.最后建议使用下面一组参数标志.

   1 -a      All: Return all information (including hidden file info).
   2 -b      Brief: Short version, usually for other scripts.
   3 -c      Copy, concatenate, etc.
   4 -d      Daily: Use information from the whole day, and not merely
   5         information for a specific instance/user.
   6 -e      Extended/Elaborate: (often does not include hidden file info).
   7 -h      Help: Verbose usage w/descs, aux info, discussion, help.
   8         See also -V.
   9 -l      Log output of script.
  10 -m      Manual: Launch man-page for base command.
  11 -n      Numbers: Numerical data only.
  12 -r      Recursive: All files in a directory (and/or all sub-dirs).
  13 -s      Setup & File Maintenance: Config files for this script.
  14 -u      Usage: List of invocation flags for the script.
  15 -v      Verbose: Human readable output, more or less formatted.
  16 -V      Version / License / Copy(right|left) / Contribs (email too).

也参考附录 F.

把复杂的脚本分割成简单一些的模块. 用合适的函数来实现各个功能. 参考例子 34-4.

如果有简单的结构可以使用,不要使用复杂的结构.

   1 COMMAND
   2 if [ $? -eq 0 ]
   3 ...
   4 # 多余的并且也不直接明了.
   5
   6 if COMMAND
   7 ...
   8 # 更简练 (或者可能会损失一些可读性).

 

 

... reading the UNIX source code to the Bourne shell (/bin/sh). Iwas shocked at how much simple algorithms could be made cryptic, andtherefore useless, by a poor choice of code style. I asked myself,"Could someone be proud of this code?"


Landon Noll

[1]

在上下文, "魔数"和用来指明文件类型的 魔数(magic numbers)有完全不同的意思.