set -e?# Exit the script if an error happens
腳本A?
set +e # don't bail out of bash script if ccache doesn't exist
腳本B
set -e # back to regular "bail out on error" mode
腳本C
如上面一個(gè) 腳本 shell ,
A ?和 C 中的 腳本 執(zhí)行的時(shí)候 如果 ?出現(xiàn)了 返回值 為 非零 ,整個(gè)腳本 就會(huì)立即退出?
B 腳本 中如果 出現(xiàn)了 返回值 為 非零 將 會(huì) 繼續(xù) 執(zhí)行 下面的 腳本 C 。
set?-e
set命令的-e參數(shù),linux自帶的說(shuō)明如下:
"Exit?immediately?if?a?simple?command?exits?with?a?non-zero?status."
也就是說(shuō),在"set?-e"之后出現(xiàn)的代碼,一旦出現(xiàn)了返回值非零,整個(gè)腳本就會(huì)立即退出。有的人喜歡使用這個(gè)參數(shù),是出于保證代碼安全性的考慮。但有的時(shí)候,這種美好的初衷,也會(huì)導(dǎo)致嚴(yán)重的問(wèn)題。
真實(shí)案例:
腳本a.sh開(kāi)頭使用了"set?-e",且能正常運(yùn)行。在幾個(gè)月或更久以后,因需求升級(jí),在腳本中增加了3行hadoop操作:
#!/bin/bash
set?-e
...
/home/work/.../hadoop?dfs?-rmr?/app/.../dir
/home/work/.../hadoop?dfs?-mkdir?/app/.../dir
/home/work/.../hadoop?dfs?-put?file_1?/app/.../dir/
...
這幾行hadoop命令邏輯很簡(jiǎn)單:在hdfs上清除并新建一個(gè)目錄,并將一份本地文件推送至這個(gè)目錄,供后續(xù)使用。將這幾行單拎出來(lái),在命令行下執(zhí)行,除了提示待刪除的目錄不存在,并沒(méi)有什么問(wèn)題,文件還是會(huì)被推送到指定的地方。
但第一次執(zhí)行這個(gè)腳本的時(shí)候,卻失敗退出了,且導(dǎo)致調(diào)用該腳本的程序整體退出,造成了嚴(yán)重的后果。原因是hdfs上還沒(méi)有這個(gè)目錄,rmr這一行會(huì)返回255,這個(gè)值被腳本前方的"set?-e"捕捉到,直接導(dǎo)致了腳本退出。
新增的代碼本身并沒(méi)有問(wèn)題,先刪除再新建目錄,反而是保證數(shù)據(jù)安全的比較規(guī)范的操作,刪除命令本身的容錯(cuò)性,可以保證后續(xù)命令正常執(zhí)行。事實(shí)是這個(gè)腳本有好幾百行,且邏輯比較復(fù)雜,在增加這幾行代碼的時(shí)候,開(kāi)發(fā)人員已經(jīng)不記得這個(gè)腳本里還有個(gè)"set?-e"埋伏著了。
可見(jiàn)設(shè)置"set?-e",在腳本開(kāi)發(fā)過(guò)程中可能很有幫助,而在開(kāi)發(fā)完成后,特別是對(duì)于后期可能有升級(jí)的腳本,則可能是埋下了安全隱患。