为你的代码添加注释。这使得其他人更容易理解(和欣赏),也让你更容易维护。
PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}" # It made perfect sense when you wrote it last year, #+ but now it's a complete mystery. # (From Antek Sawicki's "pw.sh" script.) |
为你的脚本和函数添加描述性头部。
#!/bin/bash #************************************************# # xyz.sh # # written by Bozo Bozeman # # July 05, 2001 # # # # Clean up project files. # #************************************************# E_BADDIR=85 # No such directory. projectdir=/home/bozo/projects # Directory to clean up. # --------------------------------------------------------- # # cleanup_pfiles () # # Removes all files in designated directory. # # Parameter: $target_directory # # Returns: 0 on success, $E_BADDIR if something went wrong. # # --------------------------------------------------------- # cleanup_pfiles () { if [ ! -d "$1" ] # Test if target directory exists. then echo "$1 is not a directory." return $E_BADDIR fi rm -f "$1"/* return 0 # Success. } cleanup_pfiles $projectdir exit $? |
避免使用 “魔法数字” [1],也就是 “硬编码” 的字面常量。使用有意义的变量名来代替。这使得脚本更容易理解,并且允许进行更改和更新而不会破坏应用程序。
if [ -f /var/log/messages ] then ... fi # A year later, you decide to change the script to check /var/log/syslog. # It is now necessary to manually change the script, instance by instance, #+ and hope nothing breaks. # A better way: LOGFILE=/var/log/messages # Only line that needs to be changed. if [ -f "$LOGFILE" ] then ... fi |
为变量和函数选择描述性的名称。
fl=`ls -al $dirname` # Cryptic. file_listing=`ls -al $dirname` # Better. MAXVAL=10 # All caps used for a script constant. while [ "$index" -le "$MAXVAL" ] ... E_NOTFOUND=95 # Uppercase for an errorcode, #+ and name prefixed with E_. if [ ! -e "$filename" ] then echo "File $filename not found." exit $E_NOTFOUND fi MAIL_DIRECTORY=/var/spool/mail/bozo # Uppercase for an environmental export MAIL_DIRECTORY #+ variable. GetAnswer () # Mixed case works well for a { #+ function name, especially prompt=$1 #+ when it improves legibility. echo -n $prompt read answer return $answer } GetAnswer "What is your favorite number? " favorite_number=$? echo $favorite_number _uservariable=23 # Permissible, but not recommended. # It's better for user-defined variables not to start with an underscore. # Leave that for system variables. |
以系统化和有意义的方式使用 退出码。
E_WRONG_ARGS=95 ... ... exit $E_WRONG_ARGS |
Ender 建议在 shell 脚本中使用 /usr/include/sysexits.h 中的退出码,尽管这些退出码主要用于 C 和 C++ 编程。
对于脚本调用使用标准化的参数标志。Ender 提出了以下标志集。
-a All: Return all information (including hidden file info). -b Brief: Short version, usually for other scripts. -c Copy, concatenate, etc. -d Daily: Use information from the whole day, and not merely information for a specific instance/user. -e Extended/Elaborate: (often does not include hidden file info). -h Help: Verbose usage w/descs, aux info, discussion, help. See also -V. -l Log output of script. -m Manual: Launch man-page for base command. -n Numbers: Numerical data only. -r Recursive: All files in a directory (and/or all sub-dirs). -s Setup & File Maintenance: Config files for this script. -u Usage: List of invocation flags for the script. -v Verbose: Human readable output, more or less formatted. -V Version / License / Copy(right|left) / Contribs (email too). |
另请参阅 第 G.1 节。
将复杂的脚本分解为更简单的模块。在适当的地方使用函数。参见 示例 37-4。
不要使用复杂的结构,如果简单的结构就可以完成任务。
COMMAND if [ $? -eq 0 ] ... # Redundant and non-intuitive. if COMMAND ... # More concise (if perhaps not quite as legible). |
... 阅读 UNIX Bourne shell (/bin/sh) 的源代码。我震惊于简单的算法可以通过糟糕的代码风格变得多么晦涩难懂,以至于毫无用处。我问自己,“有人会为这样的代码感到自豪吗?” --Landon Noll |
[1] | 在此上下文中,“魔法数字” 的含义与用于指定文件类型的 魔法数字 完全不同。 |