一些可靠的Linux shell腳本編寫建議

今天小編要跟大家分享的文章是關(guān)于一些可靠的LinuxShell腳本編寫建議超全。本篇文章主要為大家分享一些編寫 shell 腳本的經(jīng)驗和教訓(xùn)咆霜。Linux入門新手和正在Linux學(xué)習(xí)的小伙伴快來看一看吧,希望能夠?qū)Υ蠹矣兴鶐椭?/p>

1嘶朱、指定bash

shell 腳本的第一行蛾坯,#!之后應(yīng)該是什么?

如果拿這個問題去問別人,不同的人的回答可能各不相同疏遏。我見過/usr/bin/env bash脉课,也見過/bin/bash,還有/usr/bin/bash改览,還有/bin/sh下翎,還有/usr/bin/env sh。這算是編程界的“’茴’字四種寫法”了宝当。

在多數(shù)情況下视事,以上五種寫法都是等價的。但是庆揩,寫過程序的人都知道:“少數(shù)情況”里往往隱藏著意想不到的坑俐东。

如果系統(tǒng)的默認(rèn) shell 不是 bash 怎么辦?比如某 Linux 發(fā)行版的某個版本,默認(rèn)的 sh 就不是 bash订晌。

如果系統(tǒng)的 bash 不是在 /usr/bin/bash 怎么辦?

我推薦使用 /usr/bin/env bash 和 /bin/bash虏辫。前者通過env添加一個中間層,讓env在$PATH中搜索bash;后者則是官方背書的锈拨,約定俗成的 bash 位置砌庄,/usr/bin/bash不過是指向它的一個符號鏈接。

2奕枢、set -e 和 set -x

OK娄昆,經(jīng)過一番討論,現(xiàn)在第一行定下來了缝彬。接下來該開始寫第二行了吧?

且慢!在你開始構(gòu)思并寫下具體的代碼邏輯之前萌焰,先插入一行set -e和一行set -x。

set -x會在執(zhí)行每一行 shell 腳本時谷浅,把執(zhí)行的內(nèi)容輸出來腾务。它可以讓你看到當(dāng)前執(zhí)行的情況淳梦,里面涉及的變量也會被替換成實際的值。

set -e會在執(zhí)行出錯時結(jié)束程序,就像其他語言中的“拋出異澄找”一樣段多。(準(zhǔn)確說谋竖,不是所有出錯的時候都會結(jié)束程序尚蝌,見下面的注)

注:set -e結(jié)束程序的條件比較復(fù)雜,在man bash里面磕蒲,足足用了一段話描述各種情景留潦。大多數(shù)執(zhí)行都會在出錯時退出只盹,除非 shell 命令位于以下情況:

一個 pipeline 的非結(jié)尾部分,比如 error | ok

一個組合語句的非結(jié)尾部分兔院,比如 ok && error || other

一連串語句的非結(jié)尾部分殖卑,比如 error; ok

位于判斷語句內(nèi),包括 test坊萝、if孵稽、 while 等等。

這兩個組合在一起用十偶,可以在 debug 的時候替你節(jié)省許多時間菩鲜。出于防御性編程的考慮,有必要在寫第一行具體的代碼之前就插入它們惦积。捫心自問接校,寫代碼的時候能夠一次寫對的次數(shù)有多少?大多數(shù)代碼,在提交之前狮崩,通常都經(jīng)歷過反復(fù)調(diào)試修改的過程蛛勉。與其在焦頭爛額之際才引入這兩個配置,不如一開始就給 debug 留下余地睦柴。在代碼終于可以提交之后诽凌,再考慮是否保留它們也不遲。

3坦敌、帶上shellcheck

好了侣诵,現(xiàn)在我已經(jīng)有了三行(樣板)代碼,具體的業(yè)務(wù)邏輯一行都沒寫呢狱窘。是不是該開始寫了?

且慢!工欲善其事窝趣,必先利其器。這次训柴,我就介紹一個 shell 腳本編寫神器:shellcheck

說來慚愧,雖然寫了幾年 shell 腳本妇拯,有些語法我還是記不清楚幻馁。這時候就要依仗 shellcheck 指點一下了。

shellcheck 除了可以提醒語法問題以外越锈,還能檢查出 shell 腳本編寫常見的 bad code仗嗦。本來我的N條建議里面,還有幾條是關(guān)于這些 bad code 的甘凭,不過考慮到 shellcheck 完全可以發(fā)掘出這些問題稀拐,于是忍痛把它們都剔除在外了。毫無疑問丹弱,使用 shellcheck 給我的 shell 編寫技能帶來了巨大的飛躍德撬。

所謂“站在巨人的肩膀上”铲咨,雖然我們這些新兵蛋子,技能不如老兵們強蜓洪,但是我們可以在裝備上趕上對方啊!動動手安裝一下纤勒,就能結(jié)識一個循循善誘的“老師”,何樂而不為?

順便一提隆檀,shellcheck 居然是用 haskell 寫的摇天。誰說 haskell 只能用來裝逼?

4、變量展開

在 shell 腳本中恐仑,偶爾可以看到這樣的做法:echo $xxx | awk/sed/grep/cut…泉坐。看起來大張形勢的樣子裳仆,其實不過是想修改一個變量的值腕让。

殺雞何必用牛刀?bash 內(nèi)建的變量展開機制已經(jīng)足以滿足你各種需求!還是老方法, read the f**k manaul! man bash 然后搜索Parameter Expansion鉴逞,下面就是你想要的技巧记某。鍵者也寫過一篇相關(guān)的文章,希望能助上一臂之力:玩轉(zhuǎn) Bash變量构捡。

5液南、注意local

隨著代碼越寫越多,你開始把重復(fù)的邏輯提煉成函數(shù)勾徽。有可能你會掉到 bash 的一個坑里滑凉。在 bash,如果不加 local 限定詞喘帚,變量默認(rèn)都是全局的畅姊。變量默認(rèn)全局——這跟 js 和 lua 相似;但相較而言,很少有 bash 教程一開始就告知你這個事實吹由。在頂級作用域里若未,是否是全局變量并不重要。但是在函數(shù)里面倾鲫,聲明一個全局變量可能會污染到其他作用域(尤其在你根本沒有注意到這一點的情況下)粗合。所以,對于在函數(shù)內(nèi)聲明的變量乌昔,請務(wù)必記得加上 local 限定詞隙疚。

6、trap 信號

如果你寫過稍微復(fù)雜點的在后臺運行的程序磕道,應(yīng)該知道 posix 標(biāo)準(zhǔn)里面“信號”是什么一回事供屉。如果不知道,直接看下一段。像其他語言一樣伶丐,shell 也支持處理信號悼做。trap sighandler INT可以在接收到 SIGINT 時調(diào)用 sighandler 函數(shù)。捕獲其他信號的方式以此類推撵割。

不過 trap 的主要應(yīng)用場景可不是捕獲哪個信號贿堰。trap 命令支持“捕獲”許多不同的流程——準(zhǔn)確來說,允許用戶給特定的流程注入函數(shù)調(diào)用啡彬。其中最為常用的是trap func EXIT和trap func ERR羹与。

trap func EXIT允許在腳本結(jié)束時調(diào)用函數(shù)。由于無論正常退出抑或異常退出庶灿,所注冊的函數(shù)都能得以調(diào)用纵搁,在需要調(diào)用一個清理函數(shù)的場景下,我都是用它注冊清理函數(shù)往踢,而不是簡單地在腳本結(jié)尾調(diào)用清理函數(shù)腾誉。

trap func ERR允許在運行出錯時調(diào)用函數(shù)。一個常用的技法是峻呕,使用全局變量ERROR存儲錯誤信息利职,然后在注冊的函數(shù)中根據(jù)存儲的值完成對應(yīng)的錯誤報告。把原本四分五裂的錯誤處理邏輯集中到一處瘦癌,有時候會起奇效猪贪。不過要記住,程序異常退出時讯私,既會調(diào)用EXIT注冊的函數(shù)热押,也會調(diào)用ERR注冊的函數(shù)。

7斤寇、三思后行

以上幾條都是具體的建議桶癣,剩下兩條比較務(wù)虛。

這條建議的名字叫“三思而行”娘锁。其實無論寫什么代碼牙寞,哪怕只是一個輔助腳本,都要三思而行莫秆,切忌粗心大意碎税。不,寫腳本的時候更要記住這點馏锡。畢竟許多時候,一個復(fù)雜的腳本發(fā)端于幾行小小的命令伟端。一開始寫這個腳本的人杯道,也許以為它只是一次性任務(wù)。代碼里難免對一些外部條件有些假定,在當(dāng)時也許是正常的党巾,但是隨著外部環(huán)境的變化萎庭,這些就成了隱藏的暗礁。雪上加霜的是齿拂,幾乎沒有人會給腳本做測試驳规。除非你去運行它,否則不知道它是否還能正常使用署海。

要想減緩腳本代碼的腐爛速度吗购,需要在編寫的時候辨清哪些是會變的依賴、哪些是腳本正常運行所不可或缺的砸狞。要有適當(dāng)?shù)某橄竽砻悖帉懣勺兏拇a;同時要有防御性編程的意識,給自己的代碼一道護城河刀森。

8踱启、揚長避短

有些時候,使用 shell 寫腳本就意味著難以移植研底、難以統(tǒng)一地進行錯誤處理埠偿、難以利索地處理數(shù)據(jù)。

雖然使用外部的命令可以方便快捷地實現(xiàn)各種復(fù)雜的功能榜晦,但作為硬幣的反面冠蒋,不得不依靠grep、sed芽隆、awk等各種工具把它們粘合在一起浊服。

如果有兼容多平臺的需求,還得小心規(guī)避諸如BSD和GNU coreutils胚吁,bash版本差異之類奇奇怪怪的陷阱牙躺。

由于缺乏完善的數(shù)據(jù)結(jié)構(gòu)以及一致的API,shell 腳本在處理復(fù)雜的邏輯上力不從心腕扶。

解決特定的問題要用合適的工具孽拷。知道什么時候用 shell,什么時候切換到另外一門更通用的腳本語言(比如ruby/Python/perl)半抱,這也是編寫可靠 shell 腳本的訣竅脓恕。如果你的任務(wù)可以組合常見的命令來完成,而且只涉及簡單的數(shù)據(jù)窿侈,那么 shell 腳本就是適合的錘子炼幔。如果你的任務(wù)包含較為復(fù)雜的邏輯,而且數(shù)據(jù)結(jié)構(gòu)復(fù)雜史简,那么你需要用 ruby/Python 之類的語言編寫腳本乃秀。

以上就是小編今天為大家分享的關(guān)于一些可靠的Linux shell腳本編寫建議的文章,希望文章中的內(nèi)容能夠?qū)φ趶氖翷inux相關(guān)工作的小伙伴們有所幫助。想要了解更多Linux相關(guān)知識記得關(guān)注馬哥教育官網(wǎng)跺讯。最后祝愿小伙伴們工作順利枢贿!

標(biāo)簽:Linux入門,Shell腳本

上一篇:Linux系統(tǒng)下的查找命令都有哪些

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市刀脏,隨后出現(xiàn)的幾起案子局荚,更是在濱河造成了極大的恐慌,老刑警劉巖愈污,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耀态,死亡現(xiàn)場離奇詭異,居然都是意外死亡钙畔,警方通過查閱死者的電腦和手機茫陆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擎析,“玉大人簿盅,你說我怎么就攤上這事∽峄辏” “怎么了桨醋?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長现斋。 經(jīng)常有香客問我喜最,道長,這世上最難降的妖魔是什么庄蹋? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任瞬内,我火速辦了婚禮,結(jié)果婚禮上限书,老公的妹妹穿的比我還像新娘虫蝶。我一直安慰自己,他們只是感情好倦西,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布能真。 她就那樣靜靜地躺著,像睡著了一般扰柠。 火紅的嫁衣襯著肌膚如雪粉铐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天卤档,我揣著相機與錄音蝙泼,去河邊找鬼。 笑死劝枣,一個胖子當(dāng)著我的面吹牛踱承,可吹牛的內(nèi)容都是我干的倡缠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼茎活,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了琢唾?” 一聲冷哼從身側(cè)響起载荔,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎采桃,沒想到半個月后懒熙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡普办,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年工扎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衔蹲。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡肢娘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舆驶,到底是詐尸還是另有隱情橱健,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布沙廉,位于F島的核電站拘荡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏撬陵。R本人自食惡果不足惜珊皿,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巨税。 院中可真熱鬧蟋定,春花似錦、人聲如沸垢夹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽果元。三九已至促王,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間而晒,已是汗流浹背蝇狼。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留倡怎,地道東北人迅耘。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓贱枣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親颤专。 傳聞我的和親對象是個殘疾皇子纽哥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容