版本1.0版,參考網上的一些文章規整而來。後期打算繼續修改。完成一篇適合本身的shell開發規範。html
最新編輯時間:2017.6.25shell
1) 腳本開始以前以註釋形式說明版本號;(推薦)
2) 若是調用其餘工具,還需說明工具的版本號;(推薦)
3) 爲腳本添加必須的運行參數,相似於C程序的運行參數,可以使用getopt的方式取得運行參數值,如基本的參數有:-v - 版本號;-h – 幫助信息;(推薦)框架
1) 變量命名要先後統一,建議使用所有大寫字母,如APACHE_ERR_NUM;語義要清晰,可以正確表達變量的含義,過長的英文單詞可採用前幾個字符代替。多個單詞鏈接使用「_」號鏈接, 引用時,必須以${APACHE_ERR_NUM}方式引用;
2) 避免無含義字符或數字: 例以下面的數字22, 並不知道其確切含義.ssh
COUNT=`grep keywords file` if [ ${COUNT} –ne 22 ] then Do Something fi
3) 全局變量和局部變量:
i. 如須要使用全局變量,則在變量加前綴g,如g_WORK_DIR,在變量使用時,使用{}將其括起,即${VARIABLE}
ii. 局部變量的使用:腳本在定義在一個函數(function)中的變量咱們稱之爲局部變量,必需要以local方式進行聲明,使之只在本函數中做用有效,以避免形成在函數中的命名與程序中變量重名,形成對程序中正常變量的不正常操做。如函數
function TestFunc() { local i for((i=0;i<n;i++)) do do something done }
4) 變量合併:當某些變量或配置項要組合起來纔有意義時,如文件的路徑和文件名稱,建議將要組合的變量合併到一塊兒賦值給一個新的變量,這樣既方便以後的調用,也爲之後進行修改提供了方便。工具
1) 函數命名使用單詞首字母大寫,如CreateFile,而且要語義清晰,如使DumpDataToFile()代替DataFile()。同時要注意先後綴,如後綴爲Max則爲最大值,Min爲最小值,前綴Is爲判斷型函數,Get則爲取值函數,這樣有益於對函數的返回理解更清晰。
2) 注意在使用單詞縮寫時,也使用首字母大寫,如GetHtmlContent而並不是GetHTMLContent,這樣有利於命名規則的統一。測試
1) Shell腳本使用統一後綴:.sh
2) 全部模塊的啓動和中止腳本必須統一命名爲start_{模塊名}.sh和stop_{模塊名}.sh
3) 模塊(及其腳本和二進制程序) 命名應該表明其特性和功能,禁止使用我的名字縮寫等形式命名。
4) 模塊中的腳本和二進制程序命名禁止和其餘腳本和二進制程序重名。
五、 臨時文件的命名
儘可能避免臨時文件,若是必定要使用臨時文件,請使用腳本的pid做爲後綴,並在腳本結束時清除臨時文件。例如:ui
PID=$$ TMP_FILE=」tmp_keywords.」${PID} grep keywords files > ${TMP_FILE} ..... #end rm ${TMP_FILE}
1) 解釋器聲明最好爲 #!/bin/sh(推薦),若是不是再加入crontab計劃任務時要格外注意執行環境。
配置文件/庫函數的引用 source foo_conf.sh
2) 主過程只實現程序主幹,功能實現應該封裝在子函數中;
3) 對於能獨立執行的腳本須要有usage和version函數,能夠輸出腳本用法和版本信息(推薦)url
1) 函數定義時在函數名前加上function保留字
2) 顯示函數返回:在函數的每一個分支在函數的每一個分支都包含顯示的return語句,並跟上返回值。即便是不關心返回值的函數,也可能在後續調用時無心的去判斷它的返回值並進行一系列動做,這種沒必要要的麻煩咱們在一開始就應該注意,顯示的寫return語句並不會帶來多少負擔,相反的,它能讓函數邏輯更加清晰和嚴謹。spa
1) 在使用條件語句及循環時,儘可能使用統一格式,而不是使用「;」分隔;
if [ -d abc ] then Do something fi while [ 1 ] do Do something done for i in * do Do something Done
2) 儘可能使用每一行一條語句,而不是使用」;」將多個語句隔開。儘量多的判斷操做是否成功,並對其進行相應處理,如DoSth && DoRight || DoWrong 。這樣使用簡化了語句,也使語義變得更加清晰明瞭;
3) 要使用簡單的語句。特別是應避免多重管道的命令,多重管道的命令在每次閱讀時都須要關注每條管理的信息,直到最後一個命令,若是將其拆分紅多個語句,可讀性強;
4) 承接上面第3)點,腳本中常常有grep cut awk sed等命令一塊兒配合的複雜語句。這時應儘可能考慮簡化語句。例如多個grep awk操做常常能夠由1個sed替代。
在使用條件語句時,每進行一層循環或是循環內部的操做,就使用一個縮進,縮進通常用TAB鍵。
if [ -d abc ] then cd abc if [ -d bcd ] then DoSth fi cd .. fi
說明模塊主要用途,版本信息,輸入輸出文件,依賴工具及其版本信息, 先後流程腳本(可選),格式統一便可,不作強制要求,可以下:
##! @TODO: url analyse ##! @VERSION: 1.0 ##! @AUTHOR: MM;BB ##! @FILEIN: data/url.crawl ##! 由dedup_crawl.sh生成, 格式爲... ##! @FILEOUT: result/GOOD_GRP ##! 經過檢測的無問題alias組 ##! @FILEOUT: result/WRONG_GRP ##! 未經過檢測的有問題alias組 ##! @DEP: wget 1.10.2 ##! @DEP: lftp 3.0.6 ##! @PREV: dedup_crawl.sh ##! @NEXT: dedup_update.sh
註釋中的路徑給出的相對路徑都必須是相對於該模塊安裝時生成的根目錄。
example:
模塊seek_url安裝在PATH目錄下,安裝後生成了新的目錄seek_url,那麼全部的相對路徑都是相對於PATH/seek_url/的。
推薦爲腳本的配置和在處理流程中位於本腳本以前和以後的腳本寫註釋。以便於測試和新人熟悉模塊流程。 (推薦)
example: ##! @conf conf/config_dedup_check.sh ##! dedup-check的模塊範圍的配置文件 ##! 這裏主要讀取BINPATH 和 ALIAS_FILE設置 處理流程中在本腳本以前的腳本名 ##! @prev dedup_crawl.sh 處理流程中在本腳本以後的腳本名 ##! @next dedup_update.sh
全部腳本都要在腳本或配置文件中寫明:依賴的模塊、工具、腳本 (必須)
example: ##! @dep spuser-ftool ##! 簡要說明 ##! @dep read_di ##! 簡要說明
對於重要函數,需說明函數用途,參數,返回值,做者,版本,格式也不作強制要求,可以下:
##! @TODO: get hostname ##! @AUTHOR: somebody ##! @VERSION: 1.0 ##! @IN: $1 => ip ##! @IN: $2 => port ##! @OUT: 0 => success; 1 => failure
腳本中必定要有十分詳細的註釋,包括變量的定義,函數的定義,返回值的函義,每步操做的目的等,這方面尤爲要增強。註釋儘可能使用標準的英文或是詳細的中文說明。
1. 腳本和C程序同樣,須要有日誌記錄腳本的運行狀態,操做過程等。推薦:每條日誌要以記錄的當前時間爲開頭,而後是記錄的日誌描述信息,描述信息要包括日誌的級別,如FATAL,WARNING,NOTICE等,還要保留充分完整,無歧義的上下文信息,尤爲是FATAL和WARNING日誌更是如此。
2. 每一個腳本程序要有本身的日誌文件,不要將多個腳本的日誌記錄到同一個日誌文件中,即便這些腳本之間有依賴關係也不能夠。
1. 全部模塊之間的接口文件必須在生成的同時生成md5校驗碼,而且一個文件對應一個md5文件,md5文件的命名爲接口文件名後加上「.md5」。
2. 機器之間的數據拷貝推薦使用wget,儘可能減小scp和ssh的使用。可是隻要是wget獲取遠程數據,必須使用md5校驗數據的完整性。
3. 推薦全部接口文件都進行格式檢查,對空文件和不存在的文件判斷方式應該一致。
4. 推薦接口文件最好有相應的flag文件指明生成時間,以便檢查和容錯。
在多個腳本程序協同工做時,應該儘可能使用公共函數庫來完成近似的功能,使用配置文件統一變量及外部數據的引用,這樣便於往後的功能升級及環境的變動操做。若是使用了公共函數庫,建議在配置文件中添加公共函數庫腳本的路徑,即便是在當前目錄下也要進行配置,如FILENAME_PATH=」./」,腳本中的公共函數庫及配置文件使用source ${FILENAME_PATH}/filename.sh方式加載。
1) 全部的腳本必須把功能和配置明確分開;
2) 配置文件,以conf_腳本名.sh 來命名(推薦);
3) 原則上,配置項放在目錄conf/底下,引用時經過source conf/conf_spdata.sh的形式加載;
4) 配置項的命名規範與變量命名規範相同,要求全部的配置項應都有值,避免內容爲空的配置項出現,配置項的內容由雙引號括起,如:
OUTPUT_FILE_PATH=」./output」
5) 路徑參數的配置:腳本中常常須要配置路徑,本地路徑或者遠程機器的路徑。路徑的配置強烈推薦使用全局路徑,全局路徑的配置建議以「/」開頭,末尾沒有「/」,腳本中使用路徑的配置項時,必須以「/」分隔不一樣的配置項,變量或通配符等,不能夠省略「/」。
6) 易變參數的配置:易變參數中主要是指狀態報告和報警的收件人,都必須寫成配置。
7) 機器名,端口和用戶名引用:全部線上腳本都必須經過配置引用機器名、端口和用戶名等信息。
8) 二進制程序引用:當模塊中須要調用非本模塊維護的二進制程序/腳本時,都必須經過一個可配置的路徑來間接引用,禁止直接複製其它模塊的二進制程序到自身目錄使用。
1) 腳本中要檢查配置項是否爲空,尤爲是一些重要的,影響下面腳本正常運行的配置項,必需要進行是否爲空的檢查,避免配置文件中有遺漏等錯誤,檢查格式可以下:
if [ -z ${OUTPUT_FILE_PATH} ] then Do something, such as write log fi
1) 報警郵件的標題(和短信報警)必須爲以下格式:
[報警級別] [服務名] [機器名] [模塊名] 報警信息 [時間]
示例:
echo "[error][image][$(hostname -s)][${0}][ urlmerge for group ${group_no} failed ][$(date +'%Y-%m-%d %H:%M:%S')]"
2) 報警郵件的發件人必須真實,報警短信必須包括髮件機器名。不允許在A機器上發出以B機器名義的報警,推薦使用 `hostname` 命令
3) 線上模塊報警郵件(或短信)的收件人必須包括模塊負責人,指導人,op,禁止將模塊報警(或短信)發給全組。 每一個包含信息相同的報警原則上不得多於3條。(必須)
1) 涉及依賴的機器,需以配置的形式出如今腳本的配置文件;禁止在腳本中隨處定義機器,這樣不易於維護,也容易出錯; (必須)
2) 必需要有基本的日誌輸出;(必須)
3) 要關注腳本的效率和系統消耗,綜合、平衡的考慮;(必須)
4) 函數參數傳遞:在調用函數時,向函數傳遞的參數若是是以變量的方式進行傳遞,必須使用雙引號將變量括起,這是爲了防止某個變量中含有多個以空格分隔的字段,致使函數誤認爲是多個參數,如報警郵件和報警短信的配置項,使用方式以下:
Alert 「some thing」 「${LOG}」 「${ALERT_MAIL}」 「${ALERT_MOBILE}」
5) 避免cat 大文件。好比 for id in `cat id_file`;do … ;done。而是採用readline形式讀入文件。(必須)
6) 全部上一級命令需用 if [ $? ] 來判斷返回值,對於異常分支,需有相應的處理策略:或是打印warning日誌,或是報警退出/重試。(必須)
7) Sort超過1G的數據文件時,必須用-T指定其臨時文件夾,推薦在使用到sort的時候就使用-T指定到自身的TMP目錄。(必須)
8) 避免使用大的while/for循環,若是實在須要,請考慮用awk命令替代。(推薦)
9) 須要配置crontab的腳本,要注意crontab的時間可能會有先後1分鐘以內的波動,對於時間精度要求較嚴格的腳本,不建議配置在好比00分鐘這樣的時刻。
10) 對於一系列有嚴格依賴關係的命令,建議使用 && 來處理,好比:make mydir && mv myfile mydir;而且對於有先後次序的腳本,禁止採用後臺運行 & 命令。(推薦)
11) 腳本運行先後,注意清除過時數據(上次運行生成的數據)(推薦)
12) 腳本開始運行以前需明確當前運行路徑,例如cd /home/img/img;同時必須明確數據生成路徑,例如 data/spdata_stat/splendid.list;(必須)
13) 對於功能較爲複雜的腳本,考慮使用一些函數對功能點進行封裝。這樣可使腳本清晰易讀;(推薦)
14) 任何出錯狀況必須將出錯信息打印到日誌中;嚴重的錯誤必須以郵件或短信報警的形式發出。(必須)
15) 對於邏輯比較複雜的腳本,可使用 set -x 來打印命令執行狀況,便於調試和排錯 (推薦)
16) wget以前,注意先刪除本地文件;(推薦)
17) 拷貝比較大的文件時,最好先將文件cp到一個臨時文件夾,而後mv到目標文件夾。這樣能夠避免下游模塊讀取到了不完整的文件。(推薦)
18) mv,cp等命令,注意要使用 –r –f等遞歸和強制命令(必須)
19) 腳本中,要注意對單引號‘’雙引號「」的轉義。不明確轉義含義的,最好在單元自測的時候多加當心。(推薦)
20) 使用paste命令的時候,注意分清楚,文件是使用tab仍是空格做分隔符。
21) 使用ps axuw|grep來獲取信息時,注意ps打印的最大寬度。建議多打幾個w,例如ps axuwwww|grep … ;(推薦)
22) 使用sort,uniq,join,comm等命令時,要注意兩點:1,是否要求排序(例如uniq,join,comm要求輸入文件是排好序的);2,若是排序,要求以什麼方式排序(例如,comm要求輸入文件是字典序的,而不是數值序);(推薦)
23) 字段匹配日誌的時候,要注意特殊字符,例如
spurl[stargirls]spid[2534969]opusr [stargirls]opuid[6545440]
這樣的日誌,若是隻使用[ 和]做分隔符,就會有問題,由於spurl中就可能含有[或]等特殊字符,從而致使後面的匹配所有出錯。
24) 對特殊信號的處理:在腳本運行時,咱們有時會臨時中斷此腳本(ctrl+c),若是腳本在作多個文件操做,並生成一些臨時文件,那麼咱們在中斷腳本時,就須要恢復或清除一些過程文件。在複雜腳本中,要對一些停止的信號進行特殊的處理。
參考:
本文地址:http://www.cnblogs.com/chinas/p/7073061.html,轉載請註明出處,謝謝!!!