這裡的技術技巧最初是來自谷歌的“Testing on the Toilet” (TOTT)。這裡是一個修訂和擴增版本。
腳本安全
我的所有bash腳本都以下面幾句為開場白:
- #!/bin/bash
- set-o nounset
- set-o errexit
這樣做會避免兩種常見的問題:
- 引用未定義的變量(缺省值為“”)
- 執行失敗的命令被忽略
需要注意的是,有些Linux命令的某些參數可以強制忽略發生的錯誤,例如“mkdir -p” 和 “rm -f”。
還要注意的是,在“errexit”模式下,雖然能有效的捕捉錯誤,但並不能捕捉全部失敗的命令,在某些情況下,一些失敗的命令是無法檢測到的。(更多細節請參考這個帖子。)
腳本函數
在bash裡你可以定義函數,它們就跟其它命令一樣,可以隨意的使用;它們能讓你的腳本更具可讀性:
- ExtractBashComments(){
- egrep "^#"
- }
- cat myscript.sh |ExtractBashComments| wc
- comments=$(ExtractBashComments< myscript.sh)
還有一些例子:
- SumLines(){# iterating over stdin - similar to awk
- local sum=0
- local line=””
- while read line ;do
- sum=$((${sum}+ ${line}))
- done
- echo ${sum}
- }
- SumLines< data_one_number_per_line.txt
- log(){# classic logger
- local prefix="[$(date +%Y/%m/%d\ %H:%M:%S)]: "
- echo "${prefix} $@">&2
- }
- log "INFO""a message"
盡可能的把你的bash代碼移入到函數裡,僅把全局變量、常量和對“main”調用的語句放在最外層。
變量注解
Bash裡可以對變量進行有限的注解。最重要的兩個注解是:
- local(函數內部變量)
- readonly(只讀變量)
- # a useful idiom: DEFAULT_VAL can be overwritten
- # with an environment variable of the same name
- readonly DEFAULT_VAL=${DEFAULT_VAL:-7}
- myfunc(){
- # initialize a local variable with the global default
- local some_var=${DEFAULT_VAL}
- ...
- }
這樣,你可以將一個以前不是只讀變量的變量聲明成只讀變量:
- x=5
- x=6
- readonly x
- x=7# failure
盡量對你bash腳本裡的所有變量使用local或readonly進行注解。
用$()代替反單引號(`)
反單引號很難看,在有些字體裡跟正單引號很相似。$()能夠內嵌使用,而且避免了轉義符的麻煩。
- # both commands below print out: A-B-C-D
- echo "A-`echo B-\`echo C-\\\`echo D\\\`\``"
- echo "A-$(echo B-$(echo C-$(echo D)))"
用[[]](雙層中括號)替代[]
使用[[]]能避免像異常的文件擴展名之類的問題,而且能帶來很多語法上的改進,而且還增加了很多新功能:
操作符 | 功能說明 |
||
邏輯or(僅雙中括號裡使用)
&&
邏輯and(僅雙中括號裡使用)
<
字符串比較(雙中括號裡不需要轉移)
-lt
數字比較
=
字符串相等
==
以Globbing方式進行字符串比較(僅雙中括號裡使用,參考下文)
=~
用正則表達式進行字符串比較(僅雙中括號裡使用,參考下文)
-n
非空字符串
-z
空字符串
-eq
數字相等
-ne
數字不等
單中括號:
- ["${name}" \> "a"-o ${name} \< "m"]
雙中括號
- [["${name}">"a"&&"${name}"<"m"]]
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-04/100750p2.htm