做 者: 畢小朋 用 途: 規範Shell代碼書寫,方便查看與修改 博 客: http://blog.csdn.net/wirelessqa 參 考: http://www.ohlinux.com/archives/191/ http://kodango.com/shell-script-style
程序頭應加註版本與功能說明的註釋。但程序第一行不能漢字。linux
程序體中應包含必要的註釋,註釋說明以下:ios
單行註釋,能夠放在代碼行的尾部或代碼行的上部;程序員
多行註釋,用於註解複雜的功能說明,能夠放在程序體中,也能夠放在代碼塊的開始部分redis
代碼修改時,對修改的內容要加必要版本註釋及功能說明。shell
1.本文檔的命名約定是系統配置文件、腳本文件; 2.文件名、變量名、函數名不超過20個字符; 3.命名只能使用英文字母,數字和下劃線,只有一個英文單詞時使用全拼,有多個單詞時,使用下劃線分隔,長度較長時,能夠取單詞前3~4個字母。 4.文件名所有以小寫命名,不能大小寫混用(經過U盤交換文件時,大小寫可能會丟失,即:大寫文件名可能會所有變成小寫文件名); 5.避免使用Linux的保留字如true、關鍵字如PWD等(見附表); 6.從配置文件導出配置時,要注意過濾空行和註釋
函數名稱應該採用小寫的形式,而且有一個很好的意義。函數名稱應該容易讓人理解,好比f1這個名稱雖然容易輸入可是對調試和其它人閱讀代碼形成了很大的困難,它說明不了任何東西。好的函數名稱能夠幫助說明代碼,而不須要額外的註釋。vim
一個或多或少有趣的是:若是你無心這樣作,不要把函數名稱命名爲常見的命令名,新手每每比較容易將腳本或者函數名命名成test,這樣就和UNIX的test命令衝突了。安全
除非絕對必要,僅使用字母、數字和下劃線做爲函數名稱。bash
每一個函數控制在50-100行,超出行數建議分紅兩個函數less
屢次反覆調用的程序最好分紅函數,能夠簡化程序,使程序條理更清楚編輯器
全部函數定義應該在腳本主要代碼執行以前,這樣能夠給人全局的印象,而且確保全部函數在使用以前它是已知的。
你應該使用可移植性高的函數定義形式,即不帶function關鍵字的形式。
一、第一行通常爲調用使用的語言 二、下面要有這個程序名,避免更改文件名爲沒法找到正確的文件 三、版本號 四、更改後的時間 五、做者相關信息 六、該程序的做用,及注意事項 七、版權與是否開放共享GNU說明 八、最後是各版本的更新簡要說明
以下面的例子:
#!/bin/bash # ------------------------------------------------------------------------------- # Filename: check_mem.sh # Revision: 1.1 # Date: 2009/02/10 # Author: Ajian # Email: ajian521#gmail.com # Website: www.ohlinux.com # Description: Plugin to monitor the memory of the system # Notes: This plugin uses the "" command # ------------------------------------------------------------------------------- # Copyright: 2009 (c) Ajian # License: GPL # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # you should have received a copy of the GNU General Public License # along with this program (or with Nagios); # # Credits go to Ethan Galstad for coding Nagios # If any changes are made to this script, please mail me a copy of the changes # ------------------------------------------------------------------------------- #Version 1.0 #The first one , can monitor the system memory #Version 1.1 #Modify the method of the script ,more fast
因爲Shell沒有很好的編輯環境,因此,建議用四個空格爲基數進行縮進,好處在不一樣的環境下TAB可能表明的空格數不一樣,形成代碼的錯亂。用TAB他的優勢是速度快方便,能夠在編輯的時候也用TAB,但須要轉換。
能夠在更改編輯器,Windows的就不說了,主要是VIM
:set softtabstop=4
注意不要使用 :set tabstop=4 上面那個是同時把這一個TAB轉換爲四個空格,而這一條是定義TAB爲四個空格,若是到其它編輯器上就會看到默認8個空格的狀況,那就會不美觀了。
另外將原有的TAB轉換爲空格,:retab
若是想讓剛纔的配置永久生效須要改動vim的配置文件 vim ~/.vimrc,更多詳細的有用的配置見「VIM配置總結」
每行不要超過80字,若是超出,建議用「\」折行,有管道的命令行除外。
若是須要分隔過長的代碼,你可使用下面的任意一種方法:
1) 使用與命令寬度相同的縮進
activate some_very_long_option \ some_other_option
2) 使用2個空格縮進
activate some_very_long_option \ some_other_option
從我的的角度來講,除非有特別的須要,我更傾向於第一種形式,由於它突出「上下兩行的內容是一塊兒的」這一聯繫。
譯者注:其實這裏的複合命令就是指塊語句,例如for/while循環, if分支結構等等。
HEAD_KEYWORD parameters; BODY_BEGIN BODY_COMMANDS BODY_END
我習慣於:
1)if/then/elif/else分支語句 if ...; then ... elif ...; then ... else ... fi 2)for循環 for f in /etc/*; do ... done 3) while/until循環 while [[ $answer != [YyNn] ]]; do ... done 4) case分支語句 case $input in hello) echo "You said hello" ;; bye) echo "You said bye" if foo; then bar fi ;; *) echo "You said something weird..." ;; esac
幾點注意的地方:
除非你知道本身作的事情,請在參數展開的地方使用雙引號
固然,也有一些地方並不須要使用雙引號,例如:
若是你要傳遞一個參數做爲一個單詞列表,你能夠不使用引號,例如:
list="one two three" # you MUST NOT quote $list here for word in $list; do ... done
正如文章the article about command substitution [Bash Hackers Wiki]中說起的,你應該使用$( .. )形式。
不過,若是可移植性是一個問題,你可能必須使用反引號的形式...
。
在任何狀況,若是其它展開或者單詞分隔並非你指望的,你應該將命令替換用雙引號引發來。
變量:所有是大寫字母
變量引用:所有以變量名加雙引號引用,如」$TERMTYPE」,或「${TERMTYPE}」,若是變量類型是數值型不引用,如:
若是須要從配置文件導出變量,則在變量前加一大寫字母,以識別導出變量與自定義環境變量的區別,如:
變量值的引用盡可能以$開頭,如$(ls inst_.sh),避免使用`ls inst_。sh`
循環控制變量能夠命名爲單個字母, 好比 i、j等。 也能夠是更有意義的名稱, 好比 UserIndex。
環境變量和全局變量 在腳本開頭定義。
函數中使用較多的文件,以環境變量的形式在文件開頭定義,僅函數中使用的變量在函數開頭定義
在這裏,我將這一類變量——能夠被用戶更改的——叫作配置變量。
讓這類變量容易找到,通常放在腳本的頭部,給它們有意義的名稱而且加上註釋說明。正如上面說的,僅當你知道你爲何這麼作的時候,才用大寫的變量名形式,不然小寫形式更加安全。
if 語句
if/then/else 語句中最可能被執行的部分應該放在 then 子句中, 不太可能被執行的部分應該放在 else 子句中。
若是可能, 儘可能不要使用一連串的 if 語句, 而應該以 case 語句替代。
不要使 if 語句嵌套超過5層以上, 儘可能以更清楚的代碼替代。
case 語句
概要
case 語句中的單個子句應該以 case 常數的數字順序或字母順序排列。 子句中的執行語句應該儘可能保持簡單, 通常不要超過4到5行代碼。 若是執行語句過於複雜, 應該將它放置在獨立的函數中。
case 語句的 *) 子句應該只在正常的默認狀況或檢測到錯誤的狀況下使用。
格式
case 語句遵循一樣的縮進和命名約定。
while 語句
使用 Exit 過程退出 while 循環是很差的; 若是可能, 應該只使用循環條件來結束循環。
while 循環的全部初始化代碼應該緊貼在進入 while 循環以前, 不要被其餘無關語句分隔開。
循環結束後的處理應該緊跟在循環以後。
for 語句
若是須要執行肯定次數的增量循環, 應該用 for 語句替代 while 語句。
一個腳本的基本結構是這樣的:
#!SHEBANG CONFIGURATION_VARIABLES FUNCTION_DEFINITIONS MAIN_CODE Shebang
若是可能,請不要忘記shebang。
請當心使用/bin/sh做爲shebang,在Linux系統中,/bin/sh就是Bash這是一個錯誤的觀點。
於我而言,shebang有兩個目的:
當腳本檢測到問題時儘早退出,以避免執行潛在的問題; 若是你須要用到的命令可能並無安裝在系統上,在腳本執行的時候最好檢查命令是否存在而且提醒用戶缺乏什麼; 採用有意義的腳本返回值,例如0代碼成功,1代碼錯誤或者失敗;
if the script is interactive, if it works for you and if you think this is a nice feature, you can try to save the terminal content and restore it after execution;(譯者注:不理解這一點是什麼意思) 在屏幕中輸出簡單易理解的消息; 使用顏色或者特別的前綴區分錯誤和警告信息; 輸出正常的內容到STDOUT,而輸出錯誤、警告或者診斷的信息到STDERR; 在日誌文件中輸出全部詳細的信息;
不要盲目地假設任何事情,若是你但願用戶輸入一個數字,請在腳本中主動檢查它是否真得是一個數字,檢查頭部是否包含0,等等。咱們都應該知道這一點,用戶僅僅是用戶而不是程序員,他們會作他們想要的,而不是程序想要的。