您好,登錄后才能下訂單哦!
如何寫出健壯可靠的shell腳本,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
如果秉承著能跑就行的態(tài)度寫shell腳本,是很自在的,但是如果你想要寫出健壯,可靠的shell腳本,可沒那么容易。那么有什么可操作的經(jīng)驗(yàn)或者方法嗎?
語法檢查
第一個(gè)最簡單的方法就是利用工具對(duì)腳本進(jìn)行檢查,最大程度地發(fā)現(xiàn)shell腳本中存在的語法錯(cuò)誤,如果你還不知道,建議你絕對(duì)不要錯(cuò)過。
而為了保證腳本健壯可靠,那么就需要保證腳本在一些特殊的情況及早出現(xiàn),避免漏網(wǎng)之魚。來看看有哪些可行的技巧。
腳本失敗時(shí)即退出
可以在腳本的開頭設(shè)置如下:
set -e
舉個(gè)例子:
#!/bin/bashset -elp #這里運(yùn)行會(huì)出錯(cuò)date
這種情況下,運(yùn)行一旦出錯(cuò)就會(huì)退出,不放過一個(gè)問題:
$ ./test.shlp: Error - no default destination available.
當(dāng)然了,這也有不好的地方,有時(shí)候命令執(zhí)行本來就可能是失敗的,你還是希望它繼續(xù),可以臨時(shí)加上|| true:
#!/bin/bashset -elp || true date
不過個(gè)人覺得這樣的設(shè)置用處不是特別大,因?yàn)楹芏鄷r(shí)候就是需要處理不同的錯(cuò)誤情況,而這樣只能要么遇到錯(cuò)誤退出,要么認(rèn)為正確,導(dǎo)致無法走到異常分支。
通過set +e設(shè)置回來:
set -e#commandset +e#other command
打印腳本執(zhí)行過程
調(diào)試階段,你可能想知道整個(gè)過程是執(zhí)行了哪些命令,每條命令都具體執(zhí)行了什么,可以利用下面的方式執(zhí)行:
sh -x test.sh
或者,和上面類似,在開頭加上set -x:
//來源:公眾號(hào)【編程珠璣】//作者:守望先生#!/bin/bashset -xif [ $# -lt 1 ]then echo "no para"else echo "para 1 $1"fi
執(zhí)行時(shí),輸出如下:
+ [ 0 -le 1 ]+ echo no parano para
前面帶+的內(nèi)容就是命令實(shí)際執(zhí)行的,你可以看到比較條件是什么,變量被展開成了具體內(nèi)容,走到了哪個(gè)分支,非常清楚。
顯示未定義的變量
shell中變量沒有定義,仍然是可以使用的,但是它的結(jié)果可能不是你所預(yù)期的。舉個(gè)例子:
//來源:公眾號(hào)【編程珠璣】//作者:守望先生#!/bin/bashif [ "$var" = "abc" ]then echo " not abc"else echo " abc "fi
這里本來想判斷var的內(nèi)容是否為abc,實(shí)際上var并沒有定義,但是在這里使用并沒有報(bào)錯(cuò),如果我們想早點(diǎn)發(fā)現(xiàn)這類問題,避免在復(fù)雜的腳本中問題被掩蓋,那么可以在開頭加上:
set -u
再次運(yùn)行就會(huì)提示:
test.sh: 5: test.sh: num: parameter not set
再想象一下,你本來想刪除:
rm -rf $dir/*
然后dir是空的時(shí)候,變成了什么?
是不是有種后背發(fā)涼的感覺?
管道命令一個(gè)失敗時(shí)整個(gè)失敗
有時(shí)候我們可能會(huì)執(zhí)行類似這樣的命令:
cat test.sh |grep if | cut -d ';' -f 2
三條命令一行執(zhí)行,如果我們希望在其中一條失敗,整個(gè)命令就失敗,而避免執(zhí)行后面無意義的命令,那么可以在開始設(shè)置:
set -o pipefail
不設(shè)置的情況下,cat test.sh即使執(zhí)行失敗了,后面的grep實(shí)際上還會(huì)繼續(xù)執(zhí)行,可能會(huì)導(dǎo)致一些意想不到的情況發(fā)生,如果不想這樣的情況發(fā)生,那么這樣設(shè)置是有幫助的。
對(duì)于靜態(tài)變量使用readonly
通常我們會(huì)在腳本開頭定義一些靜態(tài)變量:
MY_PATH=/usr/bin
而為了避免MY_PATH被意外修改,可以這樣:
readonly MY_PATH=/usr/bin
這樣的話,一旦后面有命令嘗試修改,就會(huì)報(bào)錯(cuò)。
#!/bin/bashreadonly MY_PATH=/usr/binMY_PATH=/usr/local/bin
運(yùn)行一下試試:
$ ./test.shtest.sh: 3: test.sh: MY_PATH: is read only
看,給你提示了!
給變量設(shè)置可選的初始值
例如:
name=${1:-shouwang}echo "${name}"
這里讓name為$1,即第一個(gè)參數(shù),而當(dāng)它為空時(shí),令name為shouwang。
多條命令執(zhí)行使用&&
例如:
cmd0;cmd1;cmd1
這里如果cmd0失敗了,后面的命令仍然會(huì)執(zhí)行,而如果不希望后面的命令執(zhí)行,可以使用:
cmd0 && cmd1 && cmd1
使用函數(shù)
腳本本身比較短還好,而腳本一旦變長,不使用函數(shù),將使得腳本很難維護(hù),可讀性也很差。
總結(jié)
實(shí)際上最開始介紹的腳本檢查工具就已經(jīng)非常有效了,基本的錯(cuò)誤都能檢查出來,而其他的內(nèi)容,更多的是關(guān)注于腳本調(diào)試,不放過任何一個(gè)可能的錯(cuò)誤。
最后,還是優(yōu)先推薦shellcheck工具。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。