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


ECHO="echo -ne"
ESC="\033["
OK=0
FALSE=1
FLASH=5
REV=7
NULL=0
BLACK=30
RED=31
GREEN=32
ORANGE=33
BLUE=34
PURPLE=35
SBLUE=36
GREY=37
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
CurY=1
OCurX=1
OCurY=1
MCount=0
FCount=0
SCount=0
MXYp=0
MXY[0]=""
function SttyInit ()
{
stty_save=$(stty -g)
clear
trap "GameExit;" 2 15
stty -echo
$ECHO "${ESC}?25l"
return $OK
}
function GameExit ()
{
stty $stty_save
stty echo
clear
trap 2 15
$ECHO "${ESC}?25h${ESC}0;0H${ESC}0m"
exit $OK
}
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
}
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
}
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
}
function XYFormat ()
{
local XTmp=$1 YTmp=$2
if [[ $
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
}
function XYInit ()
{
for (( i=1; i<=$X; i++ ))
do
for (( j=1; j<=$Y; j++ ))
do
XYFormat $i $j S
done
done
return $OK
}
function CheckXY ()
{
local XYTmp="$1 $2"
for(( i=0; i<MXYp; i++ ))
do
if [[ "${MXY[i]}" == "$XYTmp" ]]
then return $FALSE
fi
done
return $OK
}
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
}
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
}
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
}
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
}
function Loop ()
{
local XYTmp="$1 $2"
for (( i=0; i<MXYp; i++ ))
do
if [[ "$XYTmp" == "${MXY[i]}" ]]
then $ECHO 1
fi
done
return $OK
}
function CountM ()
{
local Xmin=1 Ymin=1 Xmax=$X Ymax=$Y minecount=0 n=0
if [[ ( $CurX -gt $Xmin ) && ( $CurY -gt $Ymin ) ]]
then
n=$( Loop $((CurX-1)) $((CurY-1)) )
(( minecount += n ))
n=0
fi
if [[ $CurY -gt $Ymin ]]
then
n=$( Loop $CurX $((CurY-1)) )
(( minecount += n ))
n=0
fi
if [[ ( $CurX -lt $Xmax ) && ( $CurY -gt $Ymin ) ]]
then
n=$( Loop $((CurX+1)) $((CurY-1)) )
(( minecount += n ))
n=0
fi
if [[ $CurX -gt $Xmin ]]
then
n=$( Loop $((CurX-1)) $CurY )
(( minecount += n ))
n=0
fi
if [[ $CurX -lt $Xmax ]]
then
n=$( Loop $((CurX+1)) $CurY )
(( minecount += n ))
n=0
fi
if [[ ( $CurX -gt $Xmin ) && ( $CurY -lt $Ymax ) ]]
then
n=$( Loop $((CurX-1)) $((CurY+1)) )
(( minecount += n ))
n=0
fi
if [[ $CurY -lt $Ymax ]]
then
n=$( Loop $CurX $((CurY+1)) )
(( minecount += n ))
n=0
fi
if [[ ( $CurX -lt $Xmax ) && ( $CurY -lt $Ymax ) ]]
then
n=$( Loop $((CurX+1)) $((CurY+1)) )
(( minecount += n ))
n=0
fi
return $minecount
}
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
}
function DrawFCount ()
{
$ECHO "${ESC}22;34H${ESC};${PURPLE}mFLAG=${FCount} ${ESC}${NULL}m"
}
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
}
function Main ()
{
local key
XYInit
XYRand
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
}
SttyInit
Menu
DrawInit
Main