感受一下完美的Shell脚本编写规范

说到代码规范,其实每个程序员都很关注这一点,只是换成系统管理员来说就没那么重视咯。看起来舒服、注释到位的代码是衡量一段代码质量的标准之一,24个人是这么认为哈。但是SA每天的工作不是一直在写代码,也许更多的是敲命令。所以写脚本的时候,更为关注的应该是代码执行质量、运行效果而不是规范性。当然,这不是说大批的linux SA写脚本没有规范性,不好看。24还是见过不少牛逼人物写的代码看起来很顺眼的,注释到位,提示合理,顺序清晰。刚好今天打酱油看到一篇shell脚本,写的非常好,是一个游戏脚本--“挖地雷”。像代码注释段,该有的信息都有,显得非常专业化,再者脚本的内容也看起来很舒服,可以说是化难为易。当然了,这里不是推荐大伙们去研究这段脚本,而是体会一下他的书写规范。不过能够把下面的内容理解了,自己在此基础上改进发布改进版,那是再好不过的事情啦。这段代码测试没问题的,24已经验证过了:

感受一下完美的Shell脚本编写规范

感受一下完美的Shell脚本编写规范

#!/bin/bash   #-------------CopyRight-------------   #   Name:Mine Sweeping   #   Version Number:1.00   #   Type:game   #   Language:bash shell   #   Date:2005-10-26   #   Author:BitBull   #   Email:BitBull.cn(at)gmail.com   #------------Environment------------   #   Terminal: column 80 line 24   #   Linux 2.6.9 i686   #   GNU Bash 3.00.15   #-----------------------------------     #---------------Define--------------   ECHO="echo -ne"  ESC="\033["    OK=0  FALSE=1  #--------------Variable--------------   #ANSI ESC action   FLASH=5  REV=7    #color   NULL=0  BLACK=30  RED=31  GREEN=32  ORANGE=33  BLUE=34  PURPLE=35  SBLUE=36  GREY=37    #back color   BBLACK=40  BRED=41  BGREEN=42  BORANGE=43  BBLUE=44  BPURPLE=45  BSBLUE=46  BGREY=47    MINE='@'  FLAG='F'  NUL=' '  SHADOW='X'    X=0  Y=0  CurX=1 #cur's X   CurY=1 #cur's Y   OCurX=1 #old cur's X   OCurY=1 #old cur's Y   MCount=0 #count mine   FCount=0 #count flag   SCount=0 #count shadow   MXYp=0 #MXY Array's ptr   #---------------Array----------------     #if ${XY[]} == M { mine }   #if ${XY[]} == F { flag }   #if ${XY[]} == N { null }   #if ${XY[]} == S { shadow }   #if ${XY[]} == [1-8] { tip_num }   #${XY[]} init in XYInit(i)     MXY[0]=""     #--------------Function--------------     function SttyInit ()   {           stty_save=$(stty -g) #backup stty             clear           trap "GameExit;" 2 15          stty -echo             $ECHO "${ESC}?25l" #hidden cursor                      return $OK   }     function GameExit ()   {           stty $stty_save           stty echo           clear           trap 2 15          $ECHO "${ESC}?25h${ESC}0;0H${ESC}0m"            exit $OK   }     #print help   function Help ()   {           msg="Move:w s a d Dig:j Flag:f NewGame:n Exit:x   --CopyRight-- -2005-10-28 BitBull--"          $ECHO "${ESC}${REV};${RED}m${ESC}24;1H${msg}${ESC}${NULL}m"            return $OK   }     #print dialog window in screen   function PMsg ()   {           local title="$1" content="$2" greeting="$3"            $ECHO "${ESC}${RED}m"          $ECHO "${ESC}11;20H ------------------------------------------- "          $ECHO "${ESC}12;20H|         ======>$title<======           |"          $ECHO "${ESC}13;20H|         $content          |"          $ECHO "${ESC}14;20H|         ======>$greeting<======           |"          $ECHO "${ESC}15;20H ------------------------------------------- "          $ECHO "${ESC}${NULL}m"            return $OK   }     #print menu and player choose level,then ${X,Y,MCount,FCount,SCount} init   function Menu ()   {           local key             $ECHO "${ESC}6;1H${ESC}${RED}m"  cat<<MENUEND                          +++++++++++++++++++++++++++++                          +        (1) Easy           +                          +        (2) Normal         +                          +        (3) Hardly         +                          +        (4) Exit           +                          +++++++++++++++++++++++++++++   MENUEND           $ECHO "${ESC}${NULL}m"            while read -s -n 1 key           do                   case $key in                  1) X=10;Y=10;MCount=10;FCount=10;SCount=100;break                  ;;                   2) X=20;Y=14;MCount=28;FCount=28;SCount=280;break                  ;;                   3) X=36;Y=18;MCount=65;FCount=65;SCount=648;break                  ;;                   4) GameExit                   ;;                   esac           done             return $OK   }             #receive CurX CurY,put it into XY[CurX+X*(CurY-1))]   #if $# == 3;write into XY[]   #if $# == 2;read from XY[]   function XYFormat ()   {           local XTmp=$1 YTmp=$2            if [[ $# -eq 3 ]]           then XY[$XTmp+$X*($YTmp-1)]=$3          else echo ${XY[$XTmp+$X*($YTmp-1)]}           fi                              return $OK   }     function DrawInit ()   {           local DIline DIline2             DIline=$( for (( i=1; i<$((X*2)); i++ )) do $ECHO '-';done )           DIline2=$( for (( i=0; i<X; i++ )) do $ECHO "|${ESC}${SBLUE}mX${ESC}${NULL}m";done )             clear           Help                      $ECHO "${ESC}1;1H+${DIline}+"          for (( i=0; i<Y; i++ ))           do                   $ECHO "${ESC}$((i+2));1H${DIline2}|"          done           $ECHO "${ESC}$((Y+2));1H+${DIline}+"            return $OK   }     #${XY[*]}=S   function XYInit ()   {           for (( i=1; i<=$X; i++ ))           do                   for (( j=1; j<=$Y; j++ ))                   do                           XYFormat $i $j S                   done           done           return $OK   }     #check X Y   function CheckXY ()   {           local XYTmp="$1 $2"            for(( i=0; i<MXYp; i++ ))           do                   if [[ "${MXY[i]}" == "$XYTmp" ]]                   then return $FALSE                   fi           done             return $OK   }     #RANDOM mine's X Y   function XYRand ()   {           local XTmp YTmp             for(( i=0; i<MCount; i++ ))           do                   while :                    do                           XTmp=$(( RANDOM % ( X - 1 ) + 1 ))                           YTmp=$(( RANDOM % ( Y - 1 ) + 1 ))                           CheckXY $XTmp $YTmp                             if [[ "$?" == "$OK" ]]                           then                                   XYFormat $XTmp $YTmp M                                   MXY[i]="$XTmp $YTmp"                                  (( ++MXYp ))                                   break                          else continue                          fi                   done           done                      return $OK   }     #DEBUG   # print ${XY[*]} into ./mine.tmp   #you can read mine.tmp to know where is mine,xixi~~:)   #M is mine   function DEBUGPXY ()   {           rm mine.tmp>/dev/null 2>&1          for(( i=1; i<=$Y; i++ ))           do                   for(( j=1; j<=$X; j++))                   do                           $ECHO "$(XYFormat $j $i)">>mine.tmp                   done                   $ECHO "\n">>mine.tmp           done             return $OK   }     #move cur   #usage:CurMov [UP|DOWN|LEFT|RIGHT]   function CurMov ()   {           local direction=$1 Xmin=1 Ymin=1 Xmax=$X Ymax=$Y             OCurX=$CurX           OCurY=$CurY             case $direction        in          "UP")        if [[ $CurY -gt $Ymin ]];then (( CurY-- ));fi           ;;           "DOWN")        if [[ $CurY -lt $Ymax ]];then (( CurY++ ));fi           ;;           "LEFT"if [[ $CurX -gt $Xmin ]];then (( CurX-- ));fi           ;;           "RIGHT")if [[ $CurX -lt $Xmax ]];then (( CurX++ ));fi           ;;           esac             if [[ $CurX != $OCurX || $CurY != $OCurY ]]           then DrawPoint $CurX $CurY CUR           fi             return $OK   }     #display point   #include cur,flag,mine,shadow,nul,tip [1-8]   function DrawPoint ()   {           local TCurX=$(( $1 * 2 )) TCurY=$(( $2 + 1 )) Type=$3          local TOCurX=$(( OCurX * 2 )) TOCurY=$(( OCurY + 1 ))           local colr=0 osign=0 sign=0                     case $Type in          "CUR")                   case $(XYFormat $OCurX $OCurY) in                  F)        colr=$PURPLE;osign=$FLAG;;                   N)        colr=$NULL;osign=$NUL;;                   [1-8])        colr=$ORANGE;osign=$(XYFormat $OCurX $OCurY);;                   [SM])        colr=$SBLUE;osign=$SHADOW;;                   esac                     case $(XYFormat $CurX $CurY) in                  F)      sign=$FLAG;;                   N)      sign=$NUL;;                   [1-8])        sign=$(XYFormat $CurX $CurY);;                   [SM])     sign=$SHADOW;;                   esac                     $ECHO "${ESC}${colr}m${ESC}${TOCurY};${TOCurX}H${osign}${ESC}${NULL}m"                  $ECHO "${ESC}${REV};${FLASH};${ORANGE}m${ESC}${TCurY};${TCurX}H${sign}${ESC}${NULL}m"          ;;           "SHADOW")                   $ECHO "${ESC}${SBLUE}m${ESC}${TCurY};${TCurX}H${SHADOW}${ESC}${NULL}m"          ;;           "MINE")                    $ECHO "${ESC}${REV};${RED}m${ESC}${TCurY};${TCurX}H${MINE}${ESC}${NULL}m"          ;;           "FLAG")                   $ECHO "${ESC}${TCurY};${TCurX}H${ESC}${PURPLE}m${FLAG}${ESC}${NULL}m"          ;;           [1-8])                   $ECHO "${ESC}${TCurY};${TCurX}H${ESC}${ORANGE}m${Type}${ESC}${NULL}m"          ;;           "NUL")                   $ECHO "${ESC}${TCurY};${TCurX}H${NUL}"          esac                     return $OK   }     #check xy   function Loop ()   {           local XYTmp="$1 $2"            for (( i=0; i<MXYp; i++ ))           do                   if [[ "$XYTmp" == "${MXY[i]}" ]]                   then $ECHO 1                  fi           done             return $OK   }     #count around mine   #A B C   #D X E   #F G H   #return mine's number   function CountM ()   {           local Xmin=1 Ymin=1 Xmax=$X Ymax=$Y minecount=0 n=0  #A           if [[ ( $CurX -gt $Xmin ) && ( $CurY -gt $Ymin ) ]]           then                   n=$( Loop $((CurX-1)) $((CurY-1)) )                   (( minecount += n ))                   n=0          fi   #B           if [[ $CurY -gt $Ymin ]]           then                   n=$( Loop $CurX $((CurY-1)) )                   (( minecount += n ))                   n=0          fi   #C           if [[ ( $CurX -lt $Xmax ) && ( $CurY -gt $Ymin ) ]]           then                   n=$( Loop $((CurX+1)) $((CurY-1)) )                   (( minecount += n ))                   n=0          fi   #D           if [[ $CurX -gt $Xmin ]]           then                   n=$( Loop $((CurX-1)) $CurY )                   (( minecount += n ))                   n=0          fi   #E           if [[ $CurX -lt $Xmax ]]           then                   n=$( Loop $((CurX+1)) $CurY )                   (( minecount += n ))                   n=0          fi   #F           if [[ ( $CurX -gt $Xmin ) && ( $CurY -lt $Ymax ) ]]           then                   n=$( Loop $((CurX-1)) $((CurY+1)) )                   (( minecount += n ))                   n=0          fi   #G           if [[ $CurY -lt $Ymax ]]           then                    n=$( Loop $CurX $((CurY+1)) )                   (( minecount += n ))                   n=0          fi   #H           if [[ ( $CurX -lt $Xmax ) && ( $CurY -lt $Ymax ) ]]           then                   n=$( Loop $((CurX+1)) $((CurY+1)) )                   (( minecount += n ))                   n=0          fi             return $minecount   }     #dig   #if mine ,gameover   #else tip around mine's number   function Dig ()   {           local key minenum=0            case $(XYFormat $CurX $CurY) in          M)                   DrawPoint $CurX $CurY MINE                   read -s -n 1 key                   GameOver "Game Over"          ;;           S)                   CountM                   minenum=$?                   if [[ $minenum -eq $NULL ]]                   then                           XYFormat $CurX $CurY N                           DrawPoint $CurX $CurY NUL                   else                          XYFormat $CurX $CurY $minenum                           DrawPoint $CurX $CurY $minenum                   fi                              (( SCount-- ))                   if [[ $SCount -eq $MCount ]]                   then GameOver "Well Done"                  fi                   ;;           esac           DrawPoint $CurX $CurY CUR             return $OK   }     #draw flag's number   function DrawFCount ()   {           $ECHO "${ESC}22;34H${ESC};${PURPLE}mFLAG=${FCount}  ${ESC}${NULL}m"  }     #sign mine   function Flag ()   {           local XYTmp="$CurX $CurY";stat=$FALSE             case $(XYFormat $CurX $CurY) in          F)                   for (( i=1; i<MXYp; i++ ))                   do                           if [[ "${MXY[i]}" == "$XYTmp" ]]                           then XYFormat $CurX $CurY M;stat=$OK;break                          fi                   done                   if [[ $stat == $FALSE ]]                   then XYFormat $CurX $CurY S                   fi                     DrawPoint $CurX $CurY SHADOW                   (( FCount++ ))                   DrawFCount           ;;           [SM])                           if [[ $FCount -eq $NULL ]]                   then return $FALSE                   fi                     DrawPoint $CurX $CurY FLAG                   XYFormat $CurX $CurY F                   (( FCount-- ))                   DrawFCount           ;;           esac           DrawPoint $CurX $CurY CUR             return $OK   }     function GameOver ()   {           local key msgtitle=$1            PMsg "$msgtitle" "Do you want replay?<y/n>" "Thank You"          while read -s -n 1 key           do                   case $key in                  [yY])        exec $(dirname $0)/$(basename $0);;                   [nN])        GameExit;;                   *)        continue;;                   esac           done             return $OK           }              #main   #drawscreen and control   function Main ()   {           local key             XYInit           XYRand   ############################   # if you enable DEBUGPXY,   #you can know where is mine   #        DEBUGPXY  #delete this line's #   #then cat ./mine.tmp   ############################                     DrawPoint $CurX $CurY CUR           DrawFCount                     while read -s -n 1 key           do                   case $key in                  [wW])        CurMov UP;;                   [sS])        CurMov DOWN;;                   [aA])        CurMov LEFT;;                   [dD])        CurMov RIGHT;;                   [jJ])        Dig;;                   [fF])        Flag;;                   [nN])        exec $(dirname $0)/$(basename $0);;                   [xX])        GameExit;;                   esac           done             return $OK   }   #---------------Main-----------------     SttyInit   Menu #X Y MCount FCount SCount OK!   DrawInit   Main  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyppjw.html