日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Bash腳本15分鐘進(jìn)階教程

這里的技術(shù)技巧最初是來自谷歌的“Testing on the Toilet” (TOTT)。這里是一個(gè)修訂和擴(kuò)增版本。

創(chuàng)新互聯(lián)是專業(yè)的羅平網(wǎng)站建設(shè)公司,羅平接單;提供成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì),網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行羅平網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

腳本安全

我的所有bash腳本都以下面幾句為開場白:

 
 
  1. #!/bin/bash  
  2. set -o nounset  
  3. set -o errexit 

這樣做會避免兩種常見的問題:

  1. 引用未定義的變量(缺省值為“”)
  2. 執(zhí)行失敗的命令被忽略

需要注意的是,有些Linux命令的某些參數(shù)可以強(qiáng)制忽略發(fā)生的錯(cuò)誤,例如“mkdir -p” 和 “rm -f”。

還要注意的是,在“errexit”模式下,雖然能有效的捕捉錯(cuò)誤,但并不能捕捉全部失敗的命令,在某些情況下,一些失敗的命令是無法檢測到的。(更多細(xì)節(jié)請參考這個(gè)帖子。)

腳本函數(shù)

在bash里你可以定義函數(shù),它們就跟其它命令一樣,可以隨意的使用;它們能讓你的腳本更具可讀性:

 
 
  1. ExtractBashComments() {  
  2.     egrep "^#" 
  3. }   
  4.  
  5. cat myscript.sh | ExtractBashComments | wc   
  6.  
  7. comments=$(ExtractBashComments < myscript.sh) 

還有一些例子:

 
 
  1. SumLines() {  # iterating over stdin - similar to awk        
  2.     local sum=0 
  3.     local line=””  
  4.     while read line ; do 
  5.         sum=$((${sum} + ${line}))  
  6.     done  
  7.     echo ${sum}  
  8. }   
  9.  
  10. SumLines < data_one_number_per_line.txt   
  11.  
  12. log() {  # classic logger  
  13.    local prefix="[$(date +%Y/%m/%d\ %H:%M:%S)]: " 
  14.    echo "${prefix} $@" >&2 
  15. }   
  16.  
  17. log "INFO" "a message" 

盡可能的把你的bash代碼移入到函數(shù)里,僅把全局變量、常量和對“main”調(diào)用的語句放在最外層。

變量注解

Bash里可以對變量進(jìn)行有限的注解。最重要的兩個(gè)注解是:

  1. local(函數(shù)內(nèi)部變量)
  2. readonly(只讀變量)
 
 
  1. # a useful idiom: DEFAULT_VAL can be overwritten  
  2. #       with an environment variable of the same name  
  3. readonly DEFAULT_VAL=${DEFAULT_VAL:-7}   
  4.  
  5. myfunc() {  
  6.    # initialize a local variable with the global default  
  7.    local some_var=${DEFAULT_VAL}  
  8.    ...  

這樣,你可以將一個(gè)以前不是只讀變量的變量聲明成只讀變量:

 
 
  1. x=5 
  2. x=6 
  3. readonly x  
  4. x=7   # failure 

盡量對你bash腳本里的所有變量使用localreadonly進(jìn)行注解。

$()代替反單引號(`)

反單引號很難看,在有些字體里跟正單引號很相似。$()能夠內(nèi)嵌使用,而且避免了轉(zhuǎn)義符的麻煩。

 
 
  1. # both commands below print out: A-B-C-D  
  2. echo "A-`echo B-\`echo C-\\\`echo D\\\`\``" 
  3. echo "A-$(echo B-$(echo C-$(echo D)))" 

[[]](雙層中括號)替代[]

使用[[]]能避免像異常的文件擴(kuò)展名之類的問題,而且能帶來很多語法上的改進(jìn),而且還增加了很多新功能:

操作符 功能說明
||邏輯or(僅雙中括號里使用)
&&邏輯and(僅雙中括號里使用)
<字符串比較(雙中括號里不需要轉(zhuǎn)移)
-lt數(shù)字比較
=字符串相等
==以Globbing方式進(jìn)行字符串比較(僅雙中括號里使用,參考下文)
=~用正則表達(dá)式進(jìn)行字符串比較(僅雙中括號里使用,參考下文)
-n非空字符串
-z空字符串
-eq數(shù)字相等
-ne數(shù)字不等

單中括號:

 
 
  1. [ "${name}" \> "a" -o ${name} \< "m" ] 

雙中括號

 
 
  1. [[ "${name}" > "a" && "${name}" < "m"  ]]

正則表達(dá)式/Globbing

使用雙中括號帶來的好處用下面幾個(gè)例子最能表現(xiàn):

 
 
  1. t="abc123" 
  2. [[ "$t" == abc* ]]# true (globbing比較)  
  3. [[ "$t" == "abc*" ]]# false (字面比較)  
  4. [[ "$t" =~ [abc]+[123]+ ]]# true (正則表達(dá)式比較)  
  5. [[ "$t" =~ "abc*" ]]# false (字面比較) 

注意,從bash 3.2版開始,正則表達(dá)式和globbing表達(dá)式都不能用引號包裹。如果你的表達(dá)式里有空格,你可以把它存儲到一個(gè)變量里:

 
 
  1. r="a b+" 
  2. [[ "a bbb" =~ $r ]]# true 

按Globbing方式的字符串比較也可以用到case語句中:

 
 
  1. case $t in  
  2. abc*)   ;;  
  3. esac 

#p#

字符串操作

Bash里有各種各樣操作字符串的方式,很多都是不可取的。

基本用戶

 
 
  1. f="path1/path2/file.ext"    
  2.  
  3. len="${#f}" # = 20 (字符串長度)   
  4.  
  5. # 切片操作: ${:} or ${::}  
  6. slice1="${f:6}" # = "path2/file.ext" 
  7. slice2="${f:6:5}" # = "path2" 
  8. slice3="${f: -8}" # = "file.ext"(注意:"-"前有空格)  
  9. pos=6 
  10. len=5 
  11. slice4="${f:${pos}:${len}}" # = "path2" 

替換操作(使用globbing)

 
 
  1. f="path1/path2/file.ext"    
  2.  
  3. single_subst="${f/path?/x}"   # = "x/path2/file.ext" 
  4. global_subst="${f//path?/x}"  # = "x/x/file.ext"   
  5.  
  6. # 字符串拆分  
  7. readonly DIR_SEP="/" 
  8. array=(${f//${DIR_SEP}/ })  
  9. second_dir="${arrray[1]}"     # = path2 

刪除頭部或尾部(使用globbing)

 
 
  1. f="path1/path2/file.ext"   
  2.  
  3. # 刪除字符串頭部  
  4. extension="${f#*.}"  # = "ext"   
  5.  
  6. # 以貪婪匹配方式刪除字符串頭部  
  7. filename="${f##*/}"  # = "file.ext"   
  8.  
  9. # 刪除字符串尾部  
  10. dirname="${f%/*}"    # = "path1/path2"   
  11.  
  12. # 以貪婪匹配方式刪除字符串尾部  
  13. root="${f%%/*}"      # = "path1" 

避免使用臨時(shí)文件

有些命令需要以文件名為參數(shù),這樣一來就不能使用管道。這個(gè)時(shí)候 <() 就顯出用處了,它可以接受一個(gè)命令,并把它轉(zhuǎn)換成可以當(dāng)成文件名之類的什么東西:

 
 
  1. # 下載并比較兩個(gè)網(wǎng)頁  
  2. diff <(wget -O - url1) <(wget -O - url2)  

還有一個(gè)非常有用處的是”here documents”,它能讓你在標(biāo)準(zhǔn)輸入上輸入多行字符串。下面的’MARKER’可以替換成任何字詞。

 
 
  1. # 任何字詞都可以當(dāng)作分界符  
  2. command  << MARKER  
  3. ...  
  4. ${var}  
  5. $(cmd)  
  6. ...  
  7. MARKER 

如果文本里沒有內(nèi)嵌變量替換操作,你可以把***個(gè)MARKER用單引號包起來:

 
 
  1. command << 'MARKER' 
  2. ...  
  3. no substitution is happening here.  
  4. $ (dollar sign) is passed through verbatim.  
  5. ...  
  6. MARKER 

內(nèi)置變量

變量 說明
$0腳本名稱
$n傳給腳本/函數(shù)的第n個(gè)參數(shù)
$$腳本的PID
$!上一個(gè)被執(zhí)行的命令的PID(后臺運(yùn)行的進(jìn)程)
$?上一個(gè)命令的退出狀態(tài)(管道命令使用${PIPESTATUS})
$#傳遞給腳本/函數(shù)的參數(shù)個(gè)數(shù)
$@傳遞給腳本/函數(shù)的所有參數(shù)(識別每個(gè)參數(shù))
$*傳遞給腳本/函數(shù)的所有參數(shù)(把所有參數(shù)當(dāng)成一個(gè)字符串)

提示 使用
$*很少是正確的選擇。
$@能夠處理空格參數(shù),而且參數(shù)間的空格也能正確的處理。 使用
$@時(shí)應(yīng)該用雙引號括起來,像”$@”這樣。

調(diào)試

對腳本進(jìn)行語法檢查:

 
 
  1. bash -n myscript.sh 

跟蹤腳本里每個(gè)命令的執(zhí)行:

 
 
  1. bash -v myscripts.sh 

跟蹤腳本里每個(gè)命令的執(zhí)行并附加擴(kuò)充信息:

 
 
  1. bash -x myscript.sh 

你可以在腳本頭部使用set -o verboseset -o xtrace來***指定-v-o。當(dāng)在遠(yuǎn)程機(jī)器上執(zhí)行腳本時(shí),這樣做非常有用,用它來輸出遠(yuǎn)程信息。

什么時(shí)候不應(yīng)該使用bash腳本

  • 你的腳本太長,多達(dá)幾百行
  • 你需要比數(shù)組更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
  • 出現(xiàn)了復(fù)雜的轉(zhuǎn)義問題
  • 有太多的字符串操作
  • 不太需要調(diào)用其它程序和跟其它程序管道交互
  • 擔(dān)心性能

這個(gè)時(shí)候,你應(yīng)該考慮一種腳本語言,比如Python或Ruby。

參考

  • Advanced Bash-Scripting Guide: http://tldp.org/LDP/abs/html/
  • Bash Reference Manual

英文原文:
Better Bash Scripting in 15 Minutes

譯文鏈接:http://www.vaikan.com/bash-scripting/


分享標(biāo)題:Bash腳本15分鐘進(jìn)階教程
文章出自:http://www.dlmjj.cn/article/cdeddpi.html