iredmail是一套以postfix為核心的整合郵件系統的安裝腳本,可以達到快速部署郵件服務器的目的。為了讓自己不遺忘shell的語法,所以閒來無事,學習一下他的代碼。
我從官網下載他的最新版,解壓後,結構如下:
iRedMail.sh 是開始安裝的啟動文件,執行bash iRedMail.sh 後就開始安裝,我們從這個文件看起。
tmprootdir="$(dirname $0)"
dirname的用法是:
(1) 帶全路徑的,例:aguo@auto-test:~> dirname /home/aguo/insert.sql
/home/aguo #獲得文件所在目錄
(2) 僅僅是文件名的,例:aguo@auto-test:~> dirname Environment
. 表示路徑就是當前目錄
$0 在shell中的意思是當前執行腳本的名稱
$() 在shell中起到命令替換的作用,這樣tmprootdir的值就為當前執行腳本的目錄,在下面要對此目錄進行判斷
一個命令涉及了3個知識點,看來學習還是能加深印象的。
第二個命令如下:
echo ${tmprootdir} | grep '^/' >/dev/null 2>&1
| 管道符 ,管道符左邊命令的輸出就會作為管道符右邊命令的輸入。連續使用管道意味著第一個命令的輸出會作為 第二個命令的輸入,第二個命令的輸出又會作為第三個命令的輸入,依此類推。
grep ‘^/’ 查找以/開頭的,grep的正則表達式用法
>/dev/null 2>&1 :
可以將/dev/null看作"黑洞". 它非常等價於一個只寫文件. 所有寫入它的內容都會永遠丟失. 而嘗試從它那兒讀取內容則什麼也讀不到
1 表示stdout標准輸出,系統默認值是1,所以">/dev/null"等同於"1>/dev/null"
2 表示stderr標准錯誤
& 表示等同於的意思,2>&1,表示2的輸出重定向等同於1
很多shell腳本裡都會用到,實際作用就是不讓輸出任何內容
這個命令的整體作用就是為了查找變量tmprootdir的值中以/開頭的,下面會根據狀態碼進行判斷
if [ X"$?" == X"0" ]; then
export ROOTDIR="${tmprootdir}"
else
export ROOTDIR="$(pwd)"
fi
export export命令可以用來設置或顯示環境變量。在shell中,當一個變量創建時,只會在當前的shell中有 效,之後創建的子進程不會有該變量。而命令export可以將一個shell變量變成環境變量,在隨後創建的子進程中也能訪問到該環境變量,但是子進程在 修改了環境變量的值之後,父進程並不能知道,因為子進程將復制父進程的環境變量。因此,當shell退出時,那些在該shell中export出來的環境 變量也會消失。
這樣的話,接下來的腳本中,ROOTDIR的值就會保留下來
[ X"$?" == X"0" ] 中的X 是為了防止$?為空的情況下,而設立的,不過網上資料很少提到
$? 執行命令後返回的狀態,成功為 0 失敗為其他值
if else 判斷語句 根據$?的問號的值,來判斷腳本的絕對路徑
這個判斷是針對多系統的,有的系統裡得到的dirname裡可能會有絕對路徑的值,所以echo ${tmprootdir} | grep '^/' >/dev/null 2>&1,如果有值的話,就可以直接判斷腳本的絕對路徑;如果沒值的話,就用pwd重新獲得。
確定了腳本所在的系統的絕對路徑後,後面就可以對一些函數庫和全局變量進行調用了,接下來的代碼:
cd ${ROOTDIR}
export CONF_DIR="${ROOTDIR}/conf"
export FUNCTIONS_DIR="${ROOTDIR}/functions"
export DIALOG_DIR="${ROOTDIR}/dialog"
export PKG_DIR="${ROOTDIR}/pkgs/pkgs"
export PKG_MISC_DIR="${ROOTDIR}/pkgs/misc"
export SAMPLE_DIR="${ROOTDIR}/samples"
export PATCH_DIR="${ROOTDIR}/patches"
export TOOLS_DIR="${ROOTDIR}/tools"
. ${CONF_DIR}/global
. ${CONF_DIR}/core
基本包含了系統以後要用到的所有配置文件和具體的變量文件,global是全局的變量文件 core是核心文件,後面會繼續分析,從語法看沒什麼難的,只有. 需要解釋一下
. ${CONF_DIR}/global 這樣就把裡面的變量或者函數都引入到了腳本的運行中,後面遇到具體的變量再做分析。