Shell 開發在運維中的經驗總結

     
不管是系統運維,仍是應用運維,都可分爲「純手工」—> 「腳本化」—> 「自動化」—>「智能化」幾個階段,其中自動化階段,主要是將一些重複性人工操做和運維經驗封裝爲程序或腳本,一方面避免重複性操做及風險,另外一方面提升執行效率。在自動化運維的轉變過程當中,常用的可能就是shell腳本了,今天主要分享下shell腳本開發在運維工做中的一些經驗總結。
小腳本有大智慧,別小看幾十行代碼,夾雜着系統設計、代碼規範和操做經驗等等細節,在建設自動化運維的工做中,仍是很值得咱們研究學習的,下面總結這些也都是源於各位腳本達人和咱們在自身工做中「遇到的坑」、「摔過的跟頭」和「排過的雷」,與你們共享。shell

image.png



這裏主要介紹並參考我行已經造成的一些shell編寫規範,編寫時嚴格遵照這些規範,不只使編寫人受益,同時也能提升使用者的執行效率。
1)腳本開頭部分應有腳本功能說明、參數使用說明、做者姓名、建立/修改日期、版本信息,格式爲:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/2.pngimage.png
2)腳本編寫時,注意格式對齊,如全部的循環或者判斷語句先後的語句進行對齊,以及case的選取徹底,如:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/3.png
image.png安全

3)腳本開頭執行時,執行以下命令,在執行過程當中若遇到使用了未定義的變量或命令返回值爲非零,將直接報錯退出:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/4.pngimage.png
4)建議將命令行的每一個參數放在單引號、雙引號中,特別是rm、mv等可能對生產現有數據形成修改的操做,建議使用垃圾箱策略:rm操做轉意爲mv操做,制定文件保存目錄,以防回退,並按期清理:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/5.pngimage.png
5)命令行中參數須要使用‘*’、‘?’通配符的,應依據最精確匹配原則,如能肯定文件、目錄名稱的前綴、後綴、擴展名及其餘可識別關鍵字的,須在參數中包含該信息,如能肯定文件、目錄的長度應使用‘?’通配符,不得使用‘*’,推薦的使用方式:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/6.pngimage.pngbash

不推薦使用的方式:
image.pngfile://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/7.png
禁止使用的方式:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/8.pngimage.png併發

6)給數值型變量的賦值後,需由手段保證變量的值爲數值型,避免在後續的處理中出現異常:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/9.pngimage.png
7)在判斷條件中使用的變量,必須包含在雙引號中,如:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/10.pngimage.png運維

禁止使用的方式:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/11.pngimage.png


8)對文件進行打包備份時,必須使用相對路徑進行打包,如:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/12.pngimage.pngcurl

嚴禁將全路徑打入tar包, 如:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/13.pngimage.pngide

9)對於打包後還需進行壓縮的文件,建議使用管道進行處理,如:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/14.pngimage.png函數

不建議兩部分分開執行:
image.png工具

file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/15.png
10)使用ps命令篩選進程時,如能肯定進程所屬用戶,必須在參數中指定用戶名稱,如其輸出做爲kill命令的輸入,則必須指定進程所屬用戶,如:

file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/16.pngimage.png學習


image.png
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/17.png
這裏介紹的主要是平常shell編寫中遇到比較隱蔽或看似簡單,卻難以發現的「坑」,編寫中應儘可能避免使用,使用更優的方法避免重蹈覆轍。

1)更新文件使用>不用cp
使用>修改和回退文件時,保留原文件的屬組和權限,避免使用cp時權限屬組被修改。
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/18.pngimage.png

2)使用kill前確認
關鍵字用-w 精確匹配字段;
kill先後都保留現場, 兩次ps -ef|grep -w 關鍵字|grep -v grep >>/tmp/kill_進程名_.backup;
刪除前要校驗,獲取進程號是否惟一,避免多殺或誤殺的狀況。
image.png

file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/19.png
3)使用rm前確認
刪除前備份刪除對象信息,避免使用變量,直接使用文件和目錄名;
若是必須使用時,刪除前,建議檢查避免誤刪,刪除目錄和文件信息保留:
image.pngfile://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/20.png


建議禁用find遍歷根目錄進行查找,同時刪除前進行確認,避免多刪或誤刪的狀況。
4)For循環的坑
for循環的in條件按空格來區分,避免進入不正確或死循環。
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/21.pngimage.png

5)while循環的禁忌
若是還想使用循環中的變量,不要while結合管道使用。
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/22.pngimage.png


6)慎用cp
這句話基本上正確,但一樣有空格分詞的問題。因此應當用雙引號:
image.pngfile://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/23.png


可是若是湊巧文件名以 - 開頭,這個文件名會被 cp 看成命令行選項來處理。
能夠試試下面這個:   
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/24.pngimage.png

但也可能再碰上一個不支持 -- 選項的系統,因此最好用下面的方法: 
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/25.pngimage.png


7)慎用cd
避免使用cd到操做目錄再操做的方式,可能致使進入目錄失敗,誤刪除,如:

file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/26.pngimage.png
建議以下:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/27.pngimage.png


8)     用[[  ]]代替[ ]
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/28.pngimage.png
當$var爲空時,上面的命令就變成了[ ="bar" ]
相似地,當$var包含空格時:
[ space words here = "var" ]二者都會出錯。因此應當用雙引號將變量括起來:
[ "$var" = var ]  幾乎完美了。
可是,當$var以 - 開頭時依然會有問題。在較新的bash中你能夠用下面的方法來代替,[[ ]]關鍵字能正確處理空白、空格、帶橫線等問題。

另注意,[[適用於字符串,若是是數值,要用如:(( $var > 8 ))
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/29.pngimage.png



9)管道操做中不要同時讀寫文件
image.png
你不能在同一條管道操做中同時讀寫一個文件。根據管道的實現方式,file要麼被截斷成0字節,要麼會無限增加直到填滿整個硬盤。若是想改變原文件的內容,只能先將輸出寫到臨時文件中再用mv命令。
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/30.pngimage.png


10)cd的易錯問題
cd 有可能會出錯,致使要執行的命令就會在你預想不到的目錄裏執行了。因此必定要記得判斷cd的返回值。

file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/31.pngimage.png
若是你要根據cd的返回值執行多條命令,能夠用 ||。
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/32.png
image.png

關於目錄的一點題外話,假設你要在shell程序中頻繁變換工做目錄,以下面的代碼:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/33.png
image.png

不如這樣寫:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/34.png

image.png

括號會強制啓動一個子shell,這樣在這個子shell中改變工做目錄不會影響父shell(執行這個腳本的shell),就能夠省掉cd - 的麻煩。

file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/35.png
image.png
目前行裏自動化工具愈來愈多,不管是應用的MAOP或系統的SMDB,自動化實現都仍是平常運維腳本的調用,結合平常運維的一些經驗,腳本中就更須要考慮周全和控制風險。這裏介紹一些結合運維場景的腳本應用,但願規避之前犯過的錯,重點在控制風險。


1)     支持交互式腳本的應用
不少腳本中須要進行交互,在規避風險的同時,須要經過自動化工具發佈來支持交互,可使用expect,示例以下:

file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/36.pngimage.png

image.png


也可使用curl工具來替代簡單的交互:
#FTP SFTP下載
curl-u ftpuser:ftppassword -O "sftp://ftp_ip:ftp_port/pathfile"
 #FTP SFTP上傳
curl-u ftpuser:ftppassword  --ftp-create-dirs-T upfile "sftp://ftp_ip:ftp_port/filepath/upfile"
2)腳本規範執行和日誌追溯
直接執行的腳本很危險,要提示用戶如何使用腳本,並記錄日誌以便跟蹤。
示例以下:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/37.pngimage.png
3)腳本的併發鎖控制
避免多人同時執行或併發同時執行的異常問題,建議增長鎖機制,示例以下:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/38.pngimage.png

image.png

4)控制腳本不退出的風險
週期頻繁執行的腳本,須要防止腳本hang住不退出,致使後續腳本再次執行。
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/39.pngimage.png

5)避免集中發佈腳本形成的風險
使用ftp、sftp傳輸、下載文件,或者集中訪問存儲端口時,儘可能增長髮布對象散列,避免集中操做形成存儲端口擁堵,跨防火牆流量超限報警等影響。
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/40.png
image.png

6)避免文件無限增加的風險
向一個文件中追加數據時,必定要設置閥值,必要時清空,避免文件無限增大:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/41.pngimage.png


目錄增長清理過時文件策略,避免產生的文件愈來愈多,形成文件節點用盡:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/42.pngimage.png
目錄中的文件過多,會報參數太長錯誤沒法刪除,建議放在循環中遍歷刪除:
file://C:\Users\tenghe\AppData\Local\Temp\ct_tmp/43.png
image.png
總結:鑑於以上腳本,咱們能夠從中汲取一些經驗,規避一些風險:經過增長日誌記錄輸出和腳本執行的方法說明,並自動交互和傳遞參數,避免執行腳本的操做風險;利用文件鎖機制和運維中一些規避風險的方法,使得腳本自動執行起來更便捷更安全。1. 經過規範類腳本的定義,標準常量定義、清晰的註釋、函數和變量大小寫用法,細節中能夠看出嚴謹,即便只有幾行,也能體現出一名優秀腳本開發人員的素質。2. 經過易錯類腳本中的「坑」,使得 shell面向過程的編寫更駕輕就熟,讓腳本規範的同時,邏輯也更嚴謹清晰,避免了錯誤,也提升了腳本的開發效率。3. 經過運維場景的腳本應用,規避各類開發和執行過程當中的風險,使得shell腳本不只能支持自動化發佈,更能夠全面智能化的爲運維服務。

相關文章
相關標籤/搜索