歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> SHELL編程 >> 感受一下完美的Shell腳本編寫規范

感受一下完美的Shell腳本編寫規范

日期:2017/3/1 11:10:31   编辑:SHELL編程

說到代碼規范,其實每個程序員都很關注這一點,只是換成系統管理員來說就沒那麼重視咯。看起來舒服、注釋到位的代碼是衡量一段代碼質量的標准之一,24個人是這麼認為哈。但是SA每天的工作不是一直在寫代碼,也許更多的是敲命令。所以寫腳本的時候,更為關注的應該是代碼執行質量、運行效果而不是規范性。當然,這不是說大批的linux SA寫腳本沒有規范性,不好看。24還是見過不少牛逼人物寫的代碼看起來很順眼的,注釋到位,提示合理,順序清晰。剛好今天打醬油看到一篇shell腳本,寫的非常好,是一個游戲腳本--“挖地雷”。像代碼注釋段,該有的信息都有,顯得非常專業化,再者腳本的內容也看起來很舒服,可以說是化難為易。當然了,這裡不是推薦大伙們去研究這段腳本,而是體會一下他的書寫規范。不過能夠把下面的內容理解了,自己在此基礎上改進發布改進版,那是再好不過的事情啦。這段代碼測試沒問題的,24已經驗證過了:

  1. #!/bin/bash
  2. #-------------CopyRight-------------
  3. # Name:Mine Sweeping
  4. # Version Number:1.00
  5. # Type:game
  6. # Language:bash shell
  7. # Date:2005-10-26
  8. # Author:BitBull
  9. # Email:BitBull.cn(at)gmail.com
  10. #------------Environment------------
  11. # Terminal: column 80 line 24
  12. # Linux 2.6.9 i686
  13. # GNU Bash 3.00.15
  14. #-----------------------------------
  15. #---------------Define--------------
  16. ECHO="echo -ne"
  17. ESC="\033["
  18. OK=0
  19. FALSE=1
  20. #--------------Variable--------------
  21. #ANSI ESC action
  22. FLASH=5
  23. REV=7
  24. #color
  25. NULL=0
  26. BLACK=30
  27. RED=31
  28. GREEN=32
  29. ORANGE=33
  30. BLUE=34
  31. PURPLE=35
  32. SBLUE=36
  33. GREY=37
  34. #back color
  35. BBLACK=40
  36. BRED=41
  37. BGREEN=42
  38. BORANGE=43
  39. BBLUE=44
  40. BPURPLE=45
  41. BSBLUE=46
  42. BGREY=47
  43. MINE='@'
  44. FLAG='F'
  45. NUL=' '
  46. SHADOW='X'
  47. X=0
  48. Y=0
  49. CurX=1 #cur's X
  50. CurY=1 #cur's Y
  51. OCurX=1 #old cur's X
  52. OCurY=1 #old cur's Y
  53. MCount=0 #count mine
  54. FCount=0 #count flag
  55. SCount=0 #count shadow
  56. MXYp=0 #MXY Array's ptr
  57. #---------------Array----------------
  58. #if ${XY[]} == M { mine }
  59. #if ${XY[]} == F { flag }
  60. #if ${XY[]} == N { null }
  61. #if ${XY[]} == S { shadow }
  62. #if ${XY[]} == [1-8] { tip_num }
  63. #${XY[]} init in XYInit(i)
  64. MXY[0]=""
  65. #--------------Function--------------
  66. function SttyInit ()
  67. {
  68. stty_save=$(stty -g) #backup stty
  69. clear
  70. trap "GameExit;" 2 15
  71. stty -echo
  72. $ECHO "${ESC}?25l" #hidden cursor
  73. return $OK
  74. }
  75. function GameExit ()
  76. {
  77. stty $stty_save
  78. stty echo
  79. clear
  80. trap 2 15
  81. $ECHO "${ESC}?25h${ESC}0;0H${ESC}0m"
  82. exit $OK
  83. }
  84. #print help
  85. function Help ()
  86. {
  87. msg="Move:w s a d Dig:j Flag:f NewGame:n Exit:x --CopyRight-- -2005-10-28 BitBull--"
  88. $ECHO "${ESC}${REV};${RED}m${ESC}24;1H${msg}${ESC}${NULL}m"
  89. return $OK
  90. }
  91. #print dialog window in screen
  92. function PMsg ()
  93. {
  94. local title="$1" content="$2" greeting="$3"
  95. $ECHO "${ESC}${RED}m"
  96. $ECHO "${ESC}11;20H ------------------------------------------- "
  97. $ECHO "${ESC}12;20H| ======>$title<====== |"
  98. $ECHO "${ESC}13;20H| $content |"
  99. $ECHO "${ESC}14;20H| ======>$greeting<====== |"
  100. $ECHO "${ESC}15;20H ------------------------------------------- "
  101. $ECHO "${ESC}${NULL}m"
  102. return $OK
  103. }
  104. #print menu and player choose level,then ${X,Y,MCount,FCount,SCount} init
  105. function Menu ()
  106. {
  107. local key
  108. $ECHO "${ESC}6;1H${ESC}${RED}m"
  109. cat<<MENUEND
  110. +++++++++++++++++++++++++++++
  111. + (1) Easy +
  112. + (2) Normal +
  113. + (3) Hardly +
  114. + (4) Exit +
  115. +++++++++++++++++++++++++++++
  116. MENUEND
  117. $ECHO "${ESC}${NULL}m"
  118. while read -s -n 1 key
  119. do
  120. case $key in
  121. 1) X=10;Y=10;MCount=10;FCount=10;SCount=100;break
  122. ;;
  123. 2) X=20;Y=14;MCount=28;FCount=28;SCount=280;break
  124. ;;
  125. 3) X=36;Y=18;MCount=65;FCount=65;SCount=648;break
  126. ;;
  127. 4) GameExit
  128. ;;
  129. esac
  130. done
  131. return $OK
  132. }
  133. #receive CurX CurY,put it into XY[CurX+X*(CurY-1))]
  134. #if $# == 3;write into XY[]
  135. #if $# == 2;read from XY[]
  136. function XYFormat ()
  137. {
  138. local XTmp=$1 YTmp=$2
  139. if [[ $# -eq 3 ]]
  140. then XY[$XTmp+$X*($YTmp-1)]=$3
  141. else echo ${XY[$XTmp+$X*($YTmp-1)]}
  142. fi
  143. return $OK
  144. }
  145. function DrawInit ()
  146. {
  147. local DIline DIline2
  148. DIline=$( for (( i=1; i<$((X*2)); i++ )) do $ECHO '-';done )
  149. DIline2=$( for (( i=0; i<X; i++ )) do $ECHO "|${ESC}${SBLUE}mX${ESC}${NULL}m";done )
  150. clear
  151. Help
  152. $ECHO "${ESC}1;1H+${DIline}+"
  153. for (( i=0; i<Y; i++ ))
  154. do
  155. $ECHO "${ESC}$((i+2));1H${DIline2}|"
  156. done
  157. $ECHO "${ESC}$((Y+2));1H+${DIline}+"
  158. return $OK
  159. }
  160. #${XY[*]}=S
  161. function XYInit ()
  162. {
  163. for (( i=1; i<=$X; i++ ))
  164. do
  165. for (( j=1; j<=$Y; j++ ))
  166. do
  167. XYFormat $i $j S
  168. done
  169. done
  170. return $OK
  171. }
  172. #check X Y
  173. function CheckXY ()
  174. {
  175. local XYTmp="$1 $2"
  176. for(( i=0; i<MXYp; i++ ))
  177. do
  178. if [[ "${MXY[i]}" == "$XYTmp" ]]
  179. then return $FALSE
  180. fi
  181. done
  182. return $OK
  183. }
  184. #RANDOM mine's X Y
  185. function XYRand ()
  186. {
  187. local XTmp YTmp
  188. for(( i=0; i<MCount; i++ ))
  189. do
  190. while :
  191. do
  192. XTmp=$(( RANDOM % ( X - 1 ) + 1 ))
  193. YTmp=$(( RANDOM % ( Y - 1 ) + 1 ))
  194. CheckXY $XTmp $YTmp
  195. if [[ "$?" == "$OK" ]]
  196. then
  197. XYFormat $XTmp $YTmp M
  198. MXY[i]="$XTmp $YTmp"
  199. (( ++MXYp ))
  200. break
  201. else continue
  202. fi
  203. done
  204. done
  205. return $OK
  206. }
  207. #DEBUG
  208. # print ${XY[*]} into ./mine.tmp
  209. #you can read mine.tmp to know where is mine,xixi~~:)
  210. #M is mine
  211. function DEBUGPXY ()
  212. {
  213. rm mine.tmp>/dev/null 2>&1
  214. for(( i=1; i<=$Y; i++ ))
  215. do
  216. for(( j=1; j<=$X; j++))
  217. do
  218. $ECHO "$(XYFormat $j $i)">>mine.tmp
  219. done
  220. $ECHO "\n">>mine.tmp
  221. done
  222. return $OK
  223. }
  224. #move cur
  225. #usage:CurMov [UP|DOWN|LEFT|RIGHT]
  226. function CurMov ()
  227. {
  228. local direction=$1 Xmin=1 Ymin=1 Xmax=$X Ymax=$Y
  229. OCurX=$CurX
  230. OCurY=$CurY
  231. case $direction in
  232. "UP") if [[ $CurY -gt $Ymin ]];then (( CurY-- ));fi
  233. ;;
  234. "DOWN") if [[ $CurY -lt $Ymax ]];then (( CurY++ ));fi
  235. ;;
  236. "LEFT") if [[ $CurX -gt $Xmin ]];then (( CurX-- ));fi
  237. ;;
  238. "RIGHT")if [[ $CurX -lt $Xmax ]];then (( CurX++ ));fi
  239. ;;
  240. esac
  241. if [[ $CurX != $OCurX || $CurY != $OCurY ]]
  242. then DrawPoint $CurX $CurY CUR
  243. fi
  244. return $OK
  245. }
  246. #display point
  247. #include cur,flag,mine,shadow,nul,tip [1-8]
  248. function DrawPoint ()
  249. {
  250. local TCurX=$(( $1 * 2 )) TCurY=$(( $2 + 1 )) Type=$3
  251. local TOCurX=$(( OCurX * 2 )) TOCurY=$(( OCurY + 1 ))
  252. local colr=0 osign=0 sign=0
  253. case $Type in
  254. "CUR")
  255. case $(XYFormat $OCurX $OCurY) in
  256. F) colr=$PURPLE;osign=$FLAG;;
  257. N) colr=$NULL;osign=$NUL;;
  258. [1-8]) colr=$ORANGE;osign=$(XYFormat $OCurX $OCurY);;
  259. [SM]) colr=$SBLUE;osign=$SHADOW;;
  260. esac
  261. case $(XYFormat $CurX $CurY) in
  262. F) sign=$FLAG;;
  263. N) sign=$NUL;;
  264. [1-8]) sign=$(XYFormat $CurX $CurY);;
  265. [SM]) sign=$SHADOW;;
  266. esac
  267. $ECHO "${ESC}${colr}m${ESC}${TOCurY};${TOCurX}H${osign}${ESC}${NULL}m"
  268. $ECHO "${ESC}${REV};${FLASH};${ORANGE}m${ESC}${TCurY};${TCurX}H${sign}${ESC}${NULL}m"
  269. ;;
  270. "SHADOW")
  271. $ECHO "${ESC}${SBLUE}m${ESC}${TCurY};${TCurX}H${SHADOW}${ESC}${NULL}m"
  272. ;;
  273. "MINE")
  274. $ECHO "${ESC}${REV};${RED}m${ESC}${TCurY};${TCurX}H${MINE}${ESC}${NULL}m"
  275. ;;
  276. "FLAG")
  277. $ECHO "${ESC}${TCurY};${TCurX}H${ESC}${PURPLE}m${FLAG}${ESC}${NULL}m"
  278. ;;
  279. [1-8])
  280. $ECHO "${ESC}${TCurY};${TCurX}H${ESC}${ORANGE}m${Type}${ESC}${NULL}m"
  281. ;;
  282. "NUL")
  283. $ECHO "${ESC}${TCurY};${TCurX}H${NUL}"
  284. esac
  285. return $OK
  286. }
  287. #check xy
  288. function Loop ()
  289. {
  290. local XYTmp="$1 $2"
  291. for (( i=0; i<MXYp; i++ ))
  292. do
  293. if [[ "$XYTmp" == "${MXY[i]}" ]]
  294. then $ECHO 1
  295. fi
  296. done
  297. return $OK
  298. }
  299. #count around mine
  300. #A B C
  301. #D X E
  302. #F G H
  303. #return mine's number
  304. function CountM ()
  305. {
  306. local Xmin=1 Ymin=1 Xmax=$X Ymax=$Y minecount=0 n=0
  307. #A
  308. if [[ ( $CurX -gt $Xmin ) && ( $CurY -gt $Ymin ) ]]
  309. then
  310. n=$( Loop $((CurX-1)) $((CurY-1)) )
  311. (( minecount += n ))
  312. n=0
  313. fi
  314. #B
  315. if [[ $CurY -gt $Ymin ]]
  316. then
  317. n=$( Loop $CurX $((CurY-1)) )
  318. (( minecount += n ))
  319. n=0
  320. fi
  321. #C
  322. if [[ ( $CurX -lt $Xmax ) && ( $CurY -gt $Ymin ) ]]
  323. then
  324. n=$( Loop $((CurX+1)) $((CurY-1)) )
  325. (( minecount += n ))
  326. n=0
  327. fi
  328. #D
  329. if [[ $CurX -gt $Xmin ]]
  330. then
  331. n=$( Loop $((CurX-1)) $CurY )
  332. (( minecount += n ))
  333. n=0
  334. fi
  335. #E
  336. if [[ $CurX -lt $Xmax ]]
  337. then
  338. n=$( Loop $((CurX+1)) $CurY )
  339. (( minecount += n ))
  340. n=0
  341. fi
  342. #F
  343. if [[ ( $CurX -gt $Xmin ) && ( $CurY -lt $Ymax ) ]]
  344. then
  345. n=$( Loop $((CurX-1)) $((CurY+1)) )
  346. (( minecount += n ))
  347. n=0
  348. fi
  349. #G
  350. if [[ $CurY -lt $Ymax ]]
  351. then
  352. n=$( Loop $CurX $((CurY+1)) )
  353. (( minecount += n ))
  354. n=0
  355. fi
  356. #H
  357. if [[ ( $CurX -lt $Xmax ) && ( $CurY -lt $Ymax ) ]]
  358. then
  359. n=$( Loop $((CurX+1)) $((CurY+1)) )
  360. (( minecount += n ))
  361. n=0
  362. fi
  363. return $minecount
  364. }
  365. #dig
  366. #if mine ,gameover
  367. #else tip around mine's number
  368. function Dig ()
  369. {
  370. local key minenum=0
  371. case $(XYFormat $CurX $CurY) in
  372. M)
  373. DrawPoint $CurX $CurY MINE
  374. read -s -n 1 key
  375. GameOver "Game Over"
  376. ;;
  377. S)
  378. CountM
  379. minenum=$?
  380. if [[ $minenum -eq $NULL ]]
  381. then
  382. XYFormat $CurX $CurY N
  383. DrawPoint $CurX $CurY NUL
  384. else
  385. XYFormat $CurX $CurY $minenum
  386. DrawPoint $CurX $CurY $minenum
  387. fi
  388. (( SCount-- ))
  389. if [[ $SCount -eq $MCount ]]
  390. then GameOver "Well Done"
  391. fi
  392. ;;
  393. esac
  394. DrawPoint $CurX $CurY CUR
  395. return $OK
  396. }
  397. #draw flag's number
  398. function DrawFCount ()
  399. {
  400. $ECHO "${ESC}22;34H${ESC};${PURPLE}mFLAG=${FCount} ${ESC}${NULL}m"
  401. }
  402. #sign mine
  403. function Flag ()
  404. {
  405. local XYTmp="$CurX $CurY";stat=$FALSE
  406. case $(XYFormat $CurX $CurY) in
  407. F)
  408. for (( i=1; i<MXYp; i++ ))
  409. do
  410. if [[ "${MXY[i]}" == "$XYTmp" ]]
  411. then XYFormat $CurX $CurY M;stat=$OK;break
  412. fi
  413. done
  414. if [[ $stat == $FALSE ]]
  415. then XYFormat $CurX $CurY S
  416. fi
  417. DrawPoint $CurX $CurY SHADOW
  418. (( FCount++ ))
  419. DrawFCount
  420. ;;
  421. [SM])
  422. if [[ $FCount -eq $NULL ]]
  423. then return $FALSE
  424. fi
  425. DrawPoint $CurX $CurY FLAG
  426. XYFormat $CurX $CurY F
  427. (( FCount-- ))
  428. DrawFCount
  429. ;;
  430. esac
  431. DrawPoint $CurX $CurY CUR
  432. return $OK
  433. }
  434. function GameOver ()
  435. {
  436. local key msgtitle=$1
  437. PMsg "$msgtitle" "Do you want replay?<y/n>" "Thank You"
  438. while read -s -n 1 key
  439. do
  440. case $key in
  441. [yY]) exec $(dirname $0)/$(basename $0);;
  442. [nN]) GameExit;;
  443. *) continue;;
  444. esac
  445. done
  446. return $OK
  447. }
  448. #main
  449. #drawscreen and control
  450. function Main ()
  451. {
  452. local key
  453. XYInit
  454. XYRand
  455. ############################
  456. # if you enable DEBUGPXY,
  457. #you can know where is mine
  458. # DEBUGPXY #delete this line's #
  459. #then cat ./mine.tmp
  460. ############################
  461. DrawPoint $CurX $CurY CUR
  462. DrawFCount
  463. while read -s -n 1 key
  464. do
  465. case $key in
  466. [wW]) CurMov UP;;
  467. [sS]) CurMov DOWN;;
  468. [aA]) CurMov LEFT;;
  469. [dD]) CurMov RIGHT;;
  470. [jJ]) Dig;;
  471. [fF]) Flag;;
  472. [nN]) exec $(dirname $0)/$(basename $0);;
  473. [xX]) GameExit;;
  474. esac
  475. done
  476. return $OK
  477. }
  478. #---------------Main-----------------
  479. SttyInit
  480. Menu #X Y MCount FCount SCount OK!
  481. DrawInit
  482. Main
Copyright © Linux教程網 All Rights Reserved