工作中經常在shell腳本中看到set的這兩個用法,但就像生活中的很多事情,習慣導緻忽視,直到出現問題才引起關注。
1. set -e
set指令的-e參數,linux自帶的說明如下:
"Exit immediately if a simple command exits with a non-zero status."
也就是說,在"set -e"之後出現的代碼,一旦出現了傳回值非零,整個腳本就會立即退出。有的人喜歡使用這個參數,是出于保證代碼安全性的考慮。但有的時候,這種美好的初衷,也會導緻嚴重的問題。
真實案例:
腳本a.sh開頭使用了"set -e",且能正常運作。在幾個月或更久以後,因需求更新,在腳本中增加了3行hadoop操作:
1
2
3
4
5
6
7
<code>#!/bin/bash</code>
<code>set</code> <code>-e</code>
<code>...</code>
<code>/home/work/</code><code>...</code><code>/hadoop</code> <code>dfs -rmr </code><code>/app/</code><code>...</code><code>/dir</code>
<code>/home/work/</code><code>...</code><code>/hadoop</code> <code>dfs -</code><code>mkdir</code> <code>/app/</code><code>...</code><code>/dir</code>
<code>/home/work/</code><code>...</code><code>/hadoop</code> <code>dfs -put file_1 </code><code>/app/</code><code>...</code><code>/dir/</code>
這幾行hadoop指令邏輯很簡單:在hdfs上清除并建立一個目錄,并将一份本地檔案推送至這個目錄,供後續使用。将這幾行單拎出來,在指令行下執行,除了提示待删除的目錄不存在,并沒有什麼問題,檔案還是會被推送到指定的地方。
但第一次執行這個腳本的時候,卻失敗退出了,且導緻調用該腳本的程式整體退出,造成了嚴重的後果。原因是hdfs上還沒有這個目錄,rmr這一行會傳回255,這個值被腳本前方的"set -e"捕捉到,直接導緻了腳本退出。
新增的代碼本身并沒有問題,先删除再建立目錄,反而是保證資料安全的比較規範的操作,删除指令本身的容錯性,可以保證後續指令正常執行。事實是這個腳本有好幾百行,且邏輯比較複雜,在增加這幾行代碼的時候,開發人員已經不記得這個腳本裡還有個"set -e"埋伏着了。
可見設定"set -e",在腳本開發過程中可能很有幫助,而在開發完成後,特别是對于後期可能有更新的腳本,則可能是埋下了安全隐患。
2. set -o pipefail
對于set指令-o參數的pipefail選項,linux是這樣解釋的:
"If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status,or zero if all commands in the pipeline exit successfully. This option is disabled by default."
設定了這個選項以後,包含管道指令的語句的傳回值,會變成最後一個傳回非零的管道指令的傳回值。聽起來比較繞,其實也很簡單
<code># test.sh</code>
<code>set</code> <code>-o pipefail</code>
<code>ls</code> <code>.</code><code>/a</code><code>.txt |</code><code>echo</code> <code>"hi"</code> <code>></code><code>/dev/null</code>
<code>echo</code> <code>$?</code>
運作test.sh,因為目前目錄并不存在a.txt檔案,輸出:
ls: ./a.txt: No such file or directory
1 #設定了set -o pipefail,傳回從右往左第一個非零傳回值,即ls的傳回值1
注釋掉set -o pipefail這一行,再次運作,輸出:
0 # 沒有set -o pipefail,預設傳回最後一個管道指令的傳回值
本文轉自 Mr_sheng 51CTO部落格,原文連結:http://blog.51cto.com/sf1314/2062784