3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

高级Bash脚本编程指南

發(fā)布時(shí)間:2023/12/31 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高级Bash脚本编程指南 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://www.linuxdiyf.com/viewarticle.php?id=18812

毫無疑問,UNIX/Linux最重要的軟件之一就是shell,目前最流行的shell被稱為Bash(Bourne Again Shell),幾乎所有的Linux和絕大部分的UNIX都可以使用Bash。作為系統(tǒng)與用戶之間的交互接口,shell幾乎是你在UNIX工作平臺(tái)上最親密的朋友,因此,學(xué)好shell,是學(xué)習(xí)Linux/UNIX的的開始,并且它會(huì)始終伴隨你的工作學(xué)習(xí)。

shell是如此地重要,但令人驚奇的是,介紹shell的書沒有真正令人滿意的。所幸的是,我看到了這本被人稱為abs的書,這本書介紹了bash大量的細(xì)節(jié)和廣闊的范圍,我遇到的絕大部分的技術(shù)問題--無論是我忘記的或是以前沒有發(fā)現(xiàn)的--都可以在這本書里找到答案。這本使用大量的例子詳細(xì)地介紹了Bash的語法,各種技巧,調(diào)試等等的技術(shù),以循序漸進(jìn)的學(xué)習(xí)方式,讓你了解Bash的所有特性,在書中還有許多練習(xí)可以引導(dǎo)你思考,以得到更深入的知識(shí)。無論你是新手還是老手,或是使用其他語言的程序員,我能肯定你能在此書用受益。而本書除了介紹BASH的知識(shí)之外,也有許多有用的關(guān)于Linux/UNIX的知識(shí)和其他shell的介紹。

在看到本書的英文版后,我決定把它翻譯出來,在Linuxsir論壇上結(jié)識(shí)了譯者之一楊春敏共同翻譯這本書,600多頁的書是本大部頭的書,我們花了6個(gè)月的業(yè)余時(shí)間才翻譯完了。

關(guān)于版權(quán)的問題,英文版的作者M(jìn)endel Cooper對(duì)英文版的版權(quán)做了詳細(xì)的約定,請(qǐng)參考:Appendix Q. Copyright。中文版版權(quán)由譯者楊春敏和黃毅共同所有,在遵守英文版版權(quán)相應(yīng)條款的條件下,歡迎在保留本書譯者名字和版權(quán)說明以非盈利的方式自由發(fā)布此中文版,以盈利目的的所有行為必須聯(lián)系英文作者和兩位中文譯者以獲得許可。

本書得以成稿,我(黃毅)要多謝我的女朋友,本該給予她的時(shí)間我用來了翻譯,多謝你的理解,你是一個(gè)很棒的女朋友!

譯者 楊春敏 黃毅
2006.5.15

Advanced Bash-Scripting Guide
<<高級(jí)Bash腳本編程指南>>
一本深入學(xué)習(xí)shell腳本藝術(shù)的書籍

Version 3.7.2
2005/11/16

作者:Mendel Cooper

mail:thegrendel@theriver.com

這本書假定你沒有任何腳本或一般程序的編程知識(shí),但是如果你有相關(guān)的知識(shí),那么你將很容易
達(dá)到中高級(jí)的水平...all the while sneaking in little snippets of UNIX? wisdom and
lore(這句不知道怎么譯).你可以把本書作為教材,自學(xué)手冊(cè),或者你獲得shell腳本技術(shù)的文檔.
書中的練習(xí)和例子腳本中的注釋將會(huì)與讀者有更好的互動(dòng),但是最關(guān)鍵的前提是:
想真正學(xué)習(xí)腳本編程的唯一途徑就是編寫腳本.

這本書也可作為教材來講解一般的編程概念.

下載本書最新版本, http://personal.riverusers.com/~thegrendel/abs-guide-3.7.tar.bz2,
這是一個(gè)以tar和bzip2進(jìn)行打包的,并且是以HTML來發(fā)行的.當(dāng)然,你也可以獲得本書的pdf版本
在 http://www.tldp.org/LDP/abs/abs-guide.pdf.可以在
http://personal.riverusers.com/~thegrendel/Change.log中查看修訂歷史.

譯者:楊春敏,黃毅
mail:chunmin.yang@gmail.com

一直想好好學(xué)習(xí)一下bash,可惜網(wǎng)上的資料都雜亂不堪,我還是喜歡通過一本書系統(tǒng)的學(xué)習(xí).這本
書來得正是時(shí)候.本書的作者真是非常的嚴(yán)謹(jǐn),從例子里的改進(jìn)人名單就能看出來.可惜我水平真
的是非常有限,好多地方估計(jì)譯得都有問題.希望閱讀的朋友們多多提些修改建議.我會(huì)盡我的最
大努力去修正它.

目錄
++++
第一部分. 熱身

1. 為什么使用shell編程
2. 帶著一個(gè)Sha-Bang出發(fā)(Sha-Bang指的是#!)

2.1. 調(diào)用一個(gè)腳本
2.2. 初步的練習(xí)

第二部分. 基本

3. 特殊字符
4. 變量和參數(shù)的介紹

4.1. 變量替換
4.2. 變量賦值
4.3. Bash變量是不分類型的
4.4. 特殊的變量類型

5. 引用(翻譯的可能有問題,特指引號(hào))

5.1. 引用變量
5.2. 轉(zhuǎn)義(\)

6. 退出和退出狀態(tài)
7. Tests

7.1. Test結(jié)構(gòu)
7.2. 文件測(cè)試操作
7.3. 其他比較操作
7.4. 嵌套的if/then條件test
7.5. 檢查你的test知識(shí)

8. 操作符和相關(guān)的主題

8.1. 操作符
8.2. 數(shù)字常量

第三部分. 超越基本

9. 變量重游

9.1. 內(nèi)部變量
9.2. 操作字符串
9.3. 參數(shù)替換
9.4. 指定類型的變量:declare或者typeset
9.5. 變量的間接引用
9.6. $RANDOM: 產(chǎn)生隨機(jī)整數(shù)
9.7. 雙圓括號(hào)結(jié)構(gòu)

10. 循環(huán)和分支

10.1. 循環(huán)
10.2. 嵌套循環(huán)
10.3. 循環(huán)控制
10.4. 測(cè)試與分支(case和select結(jié)構(gòu))

11. 內(nèi)部命令與內(nèi)建

11.1. 作業(yè)控制命令

12. 外部過濾器,程序和命令

12.1. 基本命令
12.2. 復(fù)雜命令
12.3. 時(shí)間/日期 命令
12.4. 文本處理命令
12.5. 文件與歸檔命令
12.6. 通訊命令
12.7. 終端控制命令
12.8. 數(shù)學(xué)計(jì)算命令
12.9. 混雜命令

13. 系統(tǒng)與管理命令

13.1. 分析一個(gè)系統(tǒng)腳本

14. 命令替換
15. 算術(shù)擴(kuò)展
16. I/O 重定向

16.1. 使用exec
16.2. 代碼塊的重定向
16.3. 應(yīng)用

17. Here Documents

17.1. Here Strings

18. 休息時(shí)間

Part 4. 高級(jí)

19. 正則表達(dá)式

19.1. 一個(gè)簡要的正則表達(dá)式介紹
19.2. 通配

20. 子shell(Subshells)
21. 受限shell(Restricted Shells)
22. 進(jìn)程替換
23. 函數(shù)

23.1. 復(fù)雜函數(shù)和函數(shù)復(fù)雜性
23.2. 局部變量
23.3. 不使用局部變量的遞歸

24. 別名(Aliases)
25. 列表結(jié)構(gòu)
26. 數(shù)組
27. /dev 和 /proc

27.1. /dev
27.2. /proc

28. 關(guān)于Zeros和Nulls
29. 調(diào)試
30. 選項(xiàng)
31. Gotchas
32. 腳本編程風(fēng)格

32.1. 非官方的Shell腳本風(fēng)格

33. 雜項(xiàng)

33.1. 交互式和非交互式的shells和腳本
33.2. Shell 包裝
33.3. 測(cè)試和比較: 另一種方法
33.4. 遞歸
33.5. 彩色腳本
33.6. 優(yōu)化
33.7. 各種小技巧
33.8. 安全話題

33.8.1. 被感染的腳本
33.8.2. 隱藏Shell腳本源碼

33.9. 移植話題
33.10. 在Windows下進(jìn)行Shell編程

34. Bash, 版本 2 和 3

34.1. Bash, 版本2
34.2. Bash, 版本3

35. 后記

35.1. 作者后記
35.2. 關(guān)于作者
35.3. 哪里可以取得幫助?
35.4. 制作這本書的工具

35.4.1. 硬件
35.4.2. 軟件和排版軟件

35.5. Credits

Bibliography
A. Contributed Scripts
B. Reference Cards
C. A Sed and Awk Micro-Primer

C.1. Sed
C.2. Awk

D. Exit Codes With Special Meanings
E. A Detailed Introduction to I/O and I/O Redirection
F. Standard Command-Line Options
G. Important Files
H. Important System Directories
I. Localization
J. History Commands
K. A Sample .bashrc File
L. Converting DOS Batch Files to Shell Scripts
M. Exercises

M.1. Analyzing Scripts
M.2. Writing Scripts

N. Revision History
O. Mirror Sites
P. To Do List
Q. Copyright

表格清單:

11-1. 作業(yè)標(biāo)識(shí)符
30-1. Bash 選項(xiàng)
33-1. 轉(zhuǎn)義序列中數(shù)值和彩色的對(duì)應(yīng)
B-1. Special Shell Variables
B-2. TEST Operators: Binary Comparison
B-3. TEST Operators: Files
B-4. Parameter Substitution and Expansion
B-5. String Operations
B-6. Miscellaneous Constructs
C-1. Basic sed operators
C-2. Examples of sed operators
D-1. "Reserved" Exit Codes
L-1. Batch file keywords / variables / operators, and their shell equivalents
L-2. DOS commands and their UNIX equivalents
N-1. Revision History

例子清單:

2-1. 清除:清除/var/log下的log文件
2-2. 清除:一個(gè)改良的清除腳本
2-3. cleanup:一個(gè)增強(qiáng)的和廣義的刪除logfile的腳本
3-1. 代碼塊和I/O重定向
3-2. 將一個(gè)代碼塊的結(jié)果保存到文件
3-3. 在后臺(tái)運(yùn)行一個(gè)循環(huán)
3-4. 備份最后一天所有修改的文件.
4-1. 變量賦值和替換
4-2. 一般的變量賦值
4-3. 變量賦值,一般的和比較特殊的
4-4. 整型還是string?
4-5. 位置參數(shù)
4-6. wh,whois節(jié)點(diǎn)名字查詢
4-7. 使用shift
5-1. echo一些詭異的變量
5-2. 轉(zhuǎn)義符
6-1. exit/exit狀態(tài)
6-2. 否定一個(gè)條件使用!
7-1. 什么情況下為真?
7-2. 幾個(gè)等效命令test,/usr/bin/test,[],和/usr/bin/[
7-3. 算數(shù)測(cè)試使用(( ))
7-4. test死的鏈接文件
7-5. 數(shù)字和字符串比較
7-6. 測(cè)試字符串是否為null
7-7. zmore
8-1. 最大公約數(shù)
8-2. 使用算術(shù)操作符
8-3. 使用&&和||進(jìn)行混合狀態(tài)的test
8-4. 數(shù)字常量的處理
9-1. $IFS和空白
9-2. 時(shí)間輸入
9-3. 再來一個(gè)時(shí)間輸入
9-4. Timed read
9-5. 我是root?
9-6. arglist:通過$*和$@列出所有的參數(shù)
9-7. 不一致的$*和$@行為
9-8. 當(dāng)$IFS為空時(shí)的$*和$@
9-9. 下劃線變量
9-10. 在一個(gè)文本文件的段間插入空行
9-11. 利用修改文件名,來轉(zhuǎn)換圖片格式
9-12. 模仿getopt命令
9-13. 提取字符串的一種可選的方法
9-14. 使用參數(shù)替換和error messages
9-15. 參數(shù)替換和"usage"messages
9-16. 變量長度
9-17. 參數(shù)替換中的模式匹配
9-18. 重命名文件擴(kuò)展名
9-19. 使用模式匹配來分析比較特殊的字符串
9-20. 對(duì)字符串的前綴或后綴使用匹配模式
9-21. 使用declare來指定變量的類型
9-22. 間接引用
9-23. 傳遞一個(gè)間接引用給awk
9-24. 產(chǎn)生隨機(jī)數(shù)
9-25. 從一副撲克牌中取出一張隨機(jī)的牌
9-26. 兩個(gè)指定值之間的隨機(jī)數(shù)
9-27. 使用隨機(jī)數(shù)來搖一個(gè)骰子
9-28. 重新分配隨機(jī)數(shù)種子
9-29. 使用awk產(chǎn)生偽隨機(jī)數(shù)
9-30. C風(fēng)格的變量處理
10-1. 循環(huán)的一個(gè)簡單例子
10-2. 每個(gè)
  • 元素帶兩個(gè)參數(shù)的for循環(huán)
    10-3. 文件信息:對(duì)包含在變量中的文件列表進(jìn)行操作
    10-4. 在for循環(huán)中操作文件
    10-5. 在for循環(huán)中省略

    • 10-6. 使用命令替換來產(chǎn)生for循環(huán)的

      • 10-7. 對(duì)于二進(jìn)制文件的一個(gè)grep替換
        10-8. 列出系統(tǒng)上的所有用戶
        10-9. 在目錄的所有文件中查找源字串
        10-10. 列出目錄中所有的符號(hào)連接文件
        10-11. 將目錄中的符號(hào)連接文件名保存到一個(gè)文件中
        10-12. 一個(gè)C風(fēng)格的for循環(huán)
        10-13. 在batch mode中使用efax
        10-14. 簡單的while循環(huán)
        10-15. 另一個(gè)while循環(huán)
        10-16. 多條件的while循環(huán)
        10-17. C風(fēng)格的while循環(huán)
        10-18. until循環(huán)
        10-19. 嵌套循環(huán)
        10-20. break和continue命令在循環(huán)中的效果
        10-21. 多層循環(huán)的退出
        10-22. 多層循環(huán)的continue
        10-23. 在實(shí)際的任務(wù)中使用"continue N"
        10-24. 使用case
        10-25. 使用case來創(chuàng)建菜單
        10-26. 使用命令替換來產(chǎn)生case變量
        10-27. 簡單字符串匹配
        10-28. 檢查是否是字母輸入
        10-29. 用select來創(chuàng)建菜單
        10-30. 用函數(shù)中select結(jié)構(gòu)來創(chuàng)建菜單
        11-1. 一個(gè)fork出多個(gè)自己實(shí)例的腳本
        11-2. printf
        11-3. 使用read,變量分配
        11-4. 當(dāng)使用一個(gè)不帶變量參數(shù)的read命令時(shí),將會(huì)發(fā)生什么?
        11-5. read命令的多行輸入
        11-6. 檢測(cè)方向鍵
        11-7. 通過文件重定向來使用read
        11-8. 管道輸出到read中的問題
        11-9. 修改當(dāng)前的工作目錄
        11-10. 用"let"命令來作算術(shù)操作.
        11-11. 顯示eval命令的效果
        11-12. 強(qiáng)制登出(log-off)
        11-13. 另一個(gè)"rot13"的版本
        11-14. 在Perl腳本中使用eval命令來強(qiáng)制變量替換
        11-15. 使用set來改變腳本的位置參數(shù)
        11-16. 重新分配位置參數(shù)
        11-17. Unset一個(gè)變量
        11-18. 使用export命令傳遞一個(gè)變量到一個(gè)內(nèi)嵌awk的腳本中
        11-19. 使用getopts命令來讀取傳遞給腳本的選項(xiàng)/參數(shù).
        11-20. "Including"一個(gè)數(shù)據(jù)文件
        11-21. 一個(gè)沒什么用的,source自身的腳本
        11-22. exec的效果
        11-23. 一個(gè)exec自身的腳本
        11-24. 在繼續(xù)處理之前,等待一個(gè)進(jìn)程的結(jié)束
        11-25. 一個(gè)結(jié)束自身的腳本.
        12-1. 使用ls命令來創(chuàng)建一個(gè)燒錄CDR的內(nèi)容列表
        12-2. Hello or Good-bye
        12-3. 刪除當(dāng)前目錄下文件名中包含一些特殊字符(包括空白)的文件..
        12-4. 通過文件的 inode 號(hào)來刪除文件
        12-5. Logfile: 使用 xargs 來監(jiān)控系統(tǒng) log
        12-6. 把當(dāng)前目錄下的文件拷貝到另一個(gè)文件中
        12-7. 通過名字Kill進(jìn)程
        12-8. 使用xargs分析單詞出現(xiàn)的頻率
        12-9. 使用 expr
        12-10. 使用 date 命令
        12-11. 分析單詞出現(xiàn)的頻率
        12-12. 那個(gè)文件是腳本?
        12-13. 產(chǎn)生10進(jìn)制隨機(jī)數(shù)
        12-14. 使用 tail 命令來監(jiān)控系統(tǒng)log
        12-15. 在一個(gè)腳本中模仿 "grep" 的行為
        12-16. 在1913年的韋氏詞典中查找定義
        12-17. 檢查列表中單詞的正確性
        12-18. 轉(zhuǎn)換大寫: 把一個(gè)文件的內(nèi)容全部轉(zhuǎn)換為大寫.
        12-19. 轉(zhuǎn)換小寫: 將當(dāng)前目錄下的所有文全部轉(zhuǎn)換為小寫.
        12-20. Du: DOS 到 UNIX 文本文件的轉(zhuǎn)換.
        12-21. rot13: rot13, 弱智加密.
        12-22. Generating "Crypto-Quote" Puzzles
        12-23. 格式化文件列表.
        12-24. 使用 column 來格式化目錄列表
        12-25. nl: 一個(gè)自己計(jì)算行號(hào)的腳本.
        12-26. manview: 查看格式化的man頁
        12-27. 使用 cpio 來拷貝一個(gè)目錄樹
        12-28. 解包一個(gè) rpm 歸檔文件
        12-29. 從 C 文件中去掉注釋
        12-30. Exploring /usr/X11R6/bin
        12-31. 一個(gè)"改進(jìn)過"的 strings 命令
        12-32. 在一個(gè)腳本中使用 cmp 來比較2個(gè)文件.
        12-33. basename 和 dirname
        12-34. 檢查文件完整性
        12-35. Uudecod 編碼后的文件
        12-36. 查找濫用的連接來報(bào)告垃圾郵件發(fā)送者
        12-37. 分析一個(gè)垃圾郵件域
        12-38. 獲得一份股票報(bào)價(jià)
        12-39. 更新 Fedora Core 4
        12-40. 使用 ssh
        12-41. 一個(gè)可以mail自己的腳本
        12-42. 按月償還貸款
        12-43. 數(shù)制轉(zhuǎn)換
        12-44. 使用 "here document" 來調(diào)用 bc
        12-45. 計(jì)算圓周率
        12-46. 將10進(jìn)制數(shù)字轉(zhuǎn)換為16進(jìn)制數(shù)字
        12-47. 因子分解
        12-48. 計(jì)算直角三角形的斜邊
        12-49. 使用 seq 來產(chǎn)生循環(huán)參數(shù)
        12-50. 字母統(tǒng)計(jì)
        12-51. 使用getopt來分析命令行選項(xiàng)
        12-52. 一個(gè)拷貝自身的腳本
        12-53. 練習(xí)dd
        12-54. 記錄按鍵
        12-55. 安全的刪除一個(gè)文件
        12-56. 文件名產(chǎn)生器
        12-57. 將米轉(zhuǎn)換為英里
        12-58. 使用 m4
        13-1. 設(shè)置一個(gè)新密碼
        13-2. 設(shè)置一個(gè)擦除字符
        13-3. 關(guān)掉終端對(duì)于密碼的echo
        13-4. 按鍵檢測(cè)
        13-5. Checking a remote server for identd
        13-6. pidof 幫助殺掉一個(gè)進(jìn)程
        13-7. 檢查一個(gè)CD鏡像
        13-8. 在一個(gè)文件中創(chuàng)建文件系統(tǒng)
        13-9. 添加一個(gè)新的硬盤驅(qū)動(dòng)器
        13-10. 使用umask來將輸出文件隱藏起來
        13-11. killall, 來自于 /etc/rc.d/init.d
        14-1. 愚蠢的腳本策略
        14-2. 從循環(huán)的輸出中產(chǎn)生一個(gè)變量
        14-3. 找anagram(回文構(gòu)詞法, 可以將一個(gè)有意義的單詞, 變換為1個(gè)或多個(gè)有意義的單詞, 但是還是原來的子母集合)
        16-1. 使用exec重定向標(biāo)準(zhǔn)輸入
        16-2. 使用exec來重定向stdout
        16-3. 使用exec在同一腳本中重定向stdin和stdout
        16-4. 避免子shell
        16-5. while循環(huán)的重定向
        16-6. 另一種while循環(huán)的重定向
        16-7. until循環(huán)重定向
        16-8. for循環(huán)重定向
        16-9. for循環(huán)重定向 loop (將標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出都重定向了)
        16-10. 重定向if/then測(cè)試結(jié)構(gòu)
        16-11. 用于上面例子的"names.data"數(shù)據(jù)文件
        16-12. 記錄日志事件
        17-1. 廣播: 發(fā)送消息給每個(gè)登錄上的用戶
        17-2. 仿造文件: 創(chuàng)建一個(gè)兩行的仿造文件
        17-3. 使用cat的多行消息
        17-4. 帶有抑制tab功能的多行消息
        17-5. 使用參數(shù)替換的here document
        17-6. 上傳一個(gè)文件對(duì)到"Sunsite"的incoming目錄
        17-7. 關(guān)閉參數(shù)替換
        17-8. 一個(gè)產(chǎn)生另外一個(gè)腳本的腳本
        17-9. Here documents與函數(shù)
        17-10. "匿名" here Document
        17-11. 注釋掉一段代碼塊
        17-12. 一個(gè)自文檔化(self-documenting)的腳本
        17-13. 在一個(gè)文件的開頭添加文本
        20-1. 子shell中的變量作用域
        20-2. 列出用戶的配置文件
        20-3. 在子shell里進(jìn)行串行處理
        21-1. 在受限的情況下運(yùn)行腳本
        23-1. 簡單函數(shù)
        23-2. 帶著參數(shù)的函數(shù)
        23-3. 函數(shù)和被傳給腳本的命令行參數(shù)
        23-4. 傳遞間接引用給函數(shù)
        23-5. 解除傳遞給函數(shù)的參數(shù)引用
        23-6. 再次嘗試解除傳遞給函數(shù)的參數(shù)引用
        23-7. 兩個(gè)數(shù)中的最大者
        23-8. 把數(shù)字轉(zhuǎn)化成羅馬數(shù)字
        23-9. 測(cè)試函數(shù)最大的返回值
        23-10. 比較兩個(gè)大整數(shù)
        23-11. 用戶名的真實(shí)名
        23-12. 局部變量的可見范圍
        23-13. 用局部變量來遞歸
        23-14. 漢諾塔
        24-1. 腳本中的別名
        24-2. unalias: 設(shè)置和刪除別名
        25-1. 使用"與列表(and list)"來測(cè)試命令行參數(shù)
        25-2. 用"與列表"的另一個(gè)命令行參數(shù)測(cè)試
        25-3. "或列表"和"與列表"的結(jié)合使用
        26-1. 簡單的數(shù)組用法
        26-2. 格式化一首詩
        26-3. 多種數(shù)組操作
        26-4. 用于數(shù)組的字符串操作符
        26-5. 將腳本的內(nèi)容傳給數(shù)組
        26-6. 一些數(shù)組專用的工具
        26-7. 關(guān)于空數(shù)組和空數(shù)組元素
        26-8. 初始化數(shù)組
        26-9. 復(fù)制和連接數(shù)組
        26-10. 關(guān)于連接數(shù)組的更多信息
        26-11. 一位老朋友: 冒泡排序
        26-12. 內(nèi)嵌數(shù)組和間接引用
        26-13. 復(fù)雜數(shù)組應(yīng)用: 埃拉托色尼素?cái)?shù)篩子
        26-14. 模擬下推的堆棧
        26-15. 復(fù)雜的數(shù)組應(yīng)用: 列出一種怪異的數(shù)學(xué)序列
        26-16. 模擬二維數(shù)組,并使它傾斜
        27-1. 利用/dev/tcp 來檢修故障
        27-2. 搜索與一個(gè)PID相關(guān)的進(jìn)程
        27-3. 網(wǎng)絡(luò)連接狀態(tài)
        28-1. 隱藏cookie而不再使用
        28-2. 用/dev/zero創(chuàng)建一個(gè)交換臨時(shí)文件
        28-3. 創(chuàng)建ramdisk
        29-1. 一個(gè)錯(cuò)誤的腳本
        29-2. 丟失關(guān)鍵字(keyword)
        29-3. 另一個(gè)錯(cuò)誤腳本
        29-4. 用"assert"測(cè)試條件
        29-5. 捕捉 exit
        29-6. 在Control-C后清除垃圾
        29-7. 跟蹤變量
        29-8. 運(yùn)行多進(jìn)程 (在多處理器的機(jī)器里)
        31-1. 數(shù)字和字符串比較是不相等同的
        31-2. 子SHELL缺陷
        31-3. 把echo的輸出用管道輸送給read命令
        33-1. shell 包裝
        33-2. 稍微復(fù)雜一些的shell包裝
        33-3. 寫到日志文件的shell包裝
        33-4. 包裝awk的腳本
        33-5. 另一個(gè)包裝awk的腳本
        33-6. 把Perl嵌入Bash腳本
        33-7. Bash 和 Perl 腳本聯(lián)合使用
        33-8. 遞歸調(diào)用自己本身的(無用)腳本
        33-9. 遞歸調(diào)用自己本身的(有用)腳本
        33-10. 另一個(gè)遞歸調(diào)用自己本身的(有用)腳本
        33-11. 一個(gè) "彩色的" 地址資料庫
        33-12. 畫盒子
        33-13. 顯示彩色文本
        33-14. "賽馬" 游戲
        33-15. 返回值技巧
        33-16. 整型還是string?
        33-17. 傳遞和返回?cái)?shù)組
        33-18. anagrams游戲
        33-19. 在shell腳本中調(diào)用的窗口部件
        34-1. 字符串?dāng)U展
        34-2. 間接變量引用 - 新方法
        34-3. 使用間接變量引用的簡單數(shù)據(jù)庫應(yīng)用
        34-4. 用數(shù)組和其他的小技巧來處理四人隨機(jī)打牌

        A-1. mailformat: Formatting an e-mail message
        A-2. rn: A simple-minded file rename utility
        A-3. blank-rename: renames filenames containing blanks
        A-4. encryptedpw: Uploading to an ftp site, using a locally encrypted password
        A-5. copy-cd: Copying a data CD
        A-6. Collatz series
        A-7. days-between: Calculate number of days between two dates
        A-8. Make a "dictionary"
        A-9. Soundex conversion
        A-10. "Game of Life"
        A-11. Data file for "Game of Life"
        A-12. behead: Removing mail and news message headers
        A-13. ftpget: Downloading files via ftp
        A-14. password: Generating random 8-character passwords
        A-15. fifo: Making daily backups, using named pipes
        A-16. Generating prime numbers using the modulo operator
        A-17. tree: Displaying a directory tree
        A-18. string functions: C-like string functions
        A-19. Directory information
        A-20. Object-oriented database
        A-21. Library of hash functions
        A-22. Colorizing text using hash functions
        A-23. Mounting USB keychain storage devices
        A-24. Preserving weblogs
        A-25. Protecting literal strings
        A-26. Unprotecting literal strings
        A-27. Spammer Identification
        A-28. Spammer Hunt
        A-29. Making wget easier to use
        A-30. A "podcasting" script
        A-31. Basics Reviewed
        A-32. An expanded cd command
        C-1. Counting Letter Occurrences
        K-1. Sample .bashrc file
        L-1. VIEWDATA.BAT: DOS Batch File
        L-2. viewdata.sh: Shell Script Conversion of VIEWDATA.BAT
        P-1. Print the server environment

        第一部分 熱身
        ++++++++++++++++
        shell是一個(gè)命令解釋器.是介于操作系統(tǒng)kernel與用戶之間的一個(gè)絕緣層.準(zhǔn)確地說,它也是一
        一種強(qiáng)力的計(jì)算機(jī)語言.一個(gè)shell程序,被稱為一個(gè)腳本,是一種很容易使用的工具,它可以通過
        將系統(tǒng)調(diào)用,公共程序,工具,和編譯過的二進(jìn)制程序粘合在一起來建立應(yīng)用.事實(shí)上,所有的UNIX
        命令和工具再加上公共程序,對(duì)于shell腳本來說,都是可調(diào)用的.如果這些你還覺得不夠,那么
        shell內(nèi)建命令,比如test與循環(huán)結(jié)構(gòu),也會(huì)給腳本添加強(qiáng)力的支持和增加靈活性.Shell腳本對(duì)于
        管理系統(tǒng)任務(wù)和其它的重復(fù)工作的例程來說,表現(xiàn)的非常好,根本不需要那些華而不實(shí)的成熟
        緊湊的程序語言.

        第1章 為什么使用shell編程
        ===========================
        沒有程序語言是完美的.甚至沒有一個(gè)唯一最好的語言,只有對(duì)于特定目的,比較適合和不適合
        的程序語言.
        Herbert Mayer

        對(duì)于任何想適當(dāng)精通一些系統(tǒng)管理知識(shí)的人來說,掌握shell腳本知識(shí)都是最基本的,即使這些
        人可能并不打算真正的編寫一些腳本.想一下Linux機(jī)器的啟動(dòng)過程,在這個(gè)過程中,必將運(yùn)行
        /etc/rc.d目錄下的腳本來存儲(chǔ)系統(tǒng)配置和建立服務(wù).詳細(xì)的理解這些啟動(dòng)腳本對(duì)于分析系統(tǒng)的
        行為是非常重要的,并且有時(shí)候可能必須修改它.

        學(xué)習(xí)如何編寫shell腳本并不是一件很困難的事,因?yàn)槟_本可以分為很小的塊,并且相對(duì)于shell
        特性的操作和選項(xiàng)[1]部分,只需要學(xué)習(xí)很小的一部分就可以了.語法是簡單并且直觀的,編寫腳
        本很像是在命令行上把一些相關(guān)命令和工具連接起來,并且只有很少的一部分規(guī)則需要學(xué)習(xí).
        絕大部分腳本第一次就可以正常的工作,而且即使調(diào)試一個(gè)長一些的腳本也是很直觀的.

        一個(gè)shell腳本是一個(gè)類似于小吃店的(quick and dirty)方法,在你使用原型設(shè)計(jì)一個(gè)復(fù)雜的
        應(yīng)用的時(shí)候.在工程開發(fā)的第一階段,即使從功能中取得很有限的一個(gè)子集放到shell腳本中來
        完成往往都是非常有用的.使用這種方法,程序的結(jié)果可以被測(cè)試和嘗試運(yùn)行,并且在處理使用
        諸如C/C++,Java或者Perl語言編寫的最終代碼前,主要的缺陷和陷阱往往就被發(fā)現(xiàn)了.

        Shell腳本遵循典型的UNIX哲學(xué),就是把大的復(fù)雜的工程分成小規(guī)模的子任務(wù),并且把這些部件
        和工具組合起來.許多人認(rèn)為這種辦法更好一些,至少這種辦法比使用那種高\(yùn)大\全的語言更
        美,更愉悅,更適合解決問題.比如Perl就是這種能干任何事能適合任何人的語言,但是代價(jià)就是
        你需要強(qiáng)迫自己使用這種語言來思考解決問題的辦法.

        什么時(shí)候不使用Shell腳本

        資源密集型的任務(wù),尤其在需要考慮效率時(shí)(比如,排序,hash等等)

        需要處理大任務(wù)的數(shù)學(xué)操作,尤其是浮點(diǎn)運(yùn)算,精確運(yùn)算,或者復(fù)雜的算術(shù)運(yùn)算
        (這種情況一般使用C++或FORTRAN來處理)

        有跨平臺(tái)移植需求(一般使用C或Java)

        復(fù)雜的應(yīng)用,在必須使用結(jié)構(gòu)化編程的時(shí)候(需要變量的類型檢查,函數(shù)原型,等等)

        對(duì)于影響系統(tǒng)全局性的關(guān)鍵任務(wù)應(yīng)用。

        對(duì)于安全有很高要求的任務(wù),比如你需要一個(gè)健壯的系統(tǒng)來防止入侵,破解,惡意破壞等等.

        項(xiàng)目由連串的依賴的各個(gè)部分組成。

        需要大規(guī)模的文件操作

        需要多維數(shù)組的支持

        需要數(shù)據(jù)結(jié)構(gòu)的支持,比如鏈表或數(shù)等數(shù)據(jù)結(jié)構(gòu)

        需要產(chǎn)生或操作圖形化界面GUI

        需要直接操作系統(tǒng)硬件

        需要I/O或socket接口

        需要使用庫或者遺留下來的老代碼的接口

        私人的,閉源的應(yīng)用(shell腳本把代碼就放在文本文件中,全世界都能看到)

        如果你的應(yīng)用符合上邊的任意一條,那么就考慮一下更強(qiáng)大的語言吧--或許是Perl,Tcl,Python,
        Ruby -- 或者是更高層次的編譯語言比如C/C++,或者是Java.即使如此,你會(huì)發(fā)現(xiàn),使用shell
        來原型開發(fā)你的應(yīng)用,在開發(fā)步驟中也是非常有用的.

        我們將開始使用Bash,Bash是"Bourne-Again shell"首字母的縮寫,也是Stephen Bourne的經(jīng)典
        的Bourne shell的一個(gè)雙關(guān)語,(譯者:說實(shí)話,我一直搞不清這個(gè)雙關(guān)語是什么意思,為什么叫
        "Bourn-Again shell",這其中應(yīng)該有個(gè)什么典故吧,哪位好心,告訴我一下^^).Bash已經(jīng)成為了
        所有UNIX中shell腳本的事實(shí)上的標(biāo)準(zhǔn)了.同時(shí)這本書也覆蓋了絕大部分的其他一些shell的原
        則,比如Korn Shell,Bash從ksh中繼承了一部分特性,[2]C Shell和它的變種.(注意:C Shell
        編程是不被推薦的,因?yàn)橐恍┨囟ǖ膬?nèi)在問題,Tom Christiansen在1993年10月指出了這個(gè)問題
        請(qǐng)?jiān)趆ttp://www.etext.org/Quartz/computer/unix/csh.harmful.gz中查看具體內(nèi)容.)

        接下來是腳本的一些說明.在展示shell不同的特征之前,它可以減輕一些閱讀書中例子
        的負(fù)擔(dān).本書中的例子腳本,都在盡可能的范圍內(nèi)進(jìn)行了測(cè)試,并且其中的一些將使用在真
        實(shí)的生活中.讀者可以運(yùn)行這些例子腳本(使用scriptname.sh或者scriptname.bash的形式),
        [3]并給這些腳本執(zhí)行權(quán)限(chmod u+rx scriptname),然后執(zhí)行它們,看看發(fā)生了什么.如果存
        檔的腳本不可用,那么就從本書的HTML,pdf或者text的發(fā)行版本中把它們拷貝粘貼出來.考慮到
        這些腳本中的內(nèi)容在我們還沒解釋它之前就被列在這里,可能會(huì)影響讀者的理解,這就需要讀者
        暫時(shí)忽略這些內(nèi)容.

        除非特別注明,本書作者編寫了本書中的絕大部分例子腳本.

        注意事項(xiàng):
        [1] 這些在builtins章節(jié)被引用,這些是shell的內(nèi)部特征.
        [2] ksh88的許多特性,甚至是一些ksh93的特性都被合并到Bash中了.
        [3] 根據(jù)慣例,用戶編寫的Bourne shell腳本應(yīng)該在腳本的名字后邊加上.sh擴(kuò)展名.
        一些系統(tǒng)腳本,比如那些在/etc/rc.d中的腳本,則不遵循這種命名習(xí)慣.



        第2章 帶著一個(gè)Sha-Bang出發(fā)(Sha-Bang指的是#!)
        ==============================================
        在一個(gè)最簡單的例子中,一個(gè)shell腳本其實(shí)就是將一堆系統(tǒng)命令列在一個(gè)文件中.它的最基本的
        用處就是,在你每次輸入這些特定順序的命令時(shí)可以少敲一些字.

        Example 2-1 清除:清除/var/log下的log文件
        ################################Start Script#######################################
        1 # Cleanup
        2 # 當(dāng)然要使用root身份來運(yùn)行這個(gè)腳本
        3
        4 cd /var/log
        5 cat /dev/null > messages
        6 cat /dev/null > wtmp
        7 echo "Logs cleaned up."
        ################################End Script#########################################
        這根本就沒什么稀奇的, 只不過是命令的堆積, 來讓從console或者xterm中一個(gè)一個(gè)的輸入命
        令更方便一些.好處就是把所有命令都放在一個(gè)腳本中,不用每次都敲它們.這樣的話,對(duì)于特定
        的應(yīng)用來說,這個(gè)腳本就很容易被修改或定制.

        Example 2-2 清除:一個(gè)改良的清除腳本
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # 一個(gè)Bash腳本的正確的開頭部分.
        3
        4 # Cleanup, 版本 2
        5
        6 # 當(dāng)然要使用root身份來運(yùn)行.
        7 # 在此處插入代碼,來打印錯(cuò)誤消息,并且在不是root身份的時(shí)候退出.
        8
        9 LOG_DIR=/var/log
        10 # 如果使用變量,當(dāng)然比把代碼寫死的好.
        11 cd $LOG_DIR
        12
        13 cat /dev/null > messages
        14 cat /dev/null > wtmp
        15
        16
        17 echo "Logs cleaned up."
        18
        19 exit # 這個(gè)命令是一種正確并且合適的退出腳本的方法.
        ################################End Script#########################################

        現(xiàn)在,讓我們看一下一個(gè)真正意義的腳本.而且我們可以走得更遠(yuǎn)...
        Example 2-3. cleanup:一個(gè)增強(qiáng)的和廣義的刪除logfile的腳本
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # 清除, 版本 3
        3
        4 # Warning:
        5 # -------
        6 # 這個(gè)腳本有好多特征,這些特征是在后邊章節(jié)進(jìn)行解釋的,大概是進(jìn)行到本書的一半的
        7 # 時(shí)候,
        8 # 你就會(huì)覺得它沒有什么神秘的了.
        9 #
        10
        11
        12
        13 LOG_DIR=/var/log
        14 ROOT_UID=0 # $UID為0的時(shí)候,用戶才具有根用戶的權(quán)限
        15 LINES=50 # 默認(rèn)的保存行數(shù)
        16 E_XCD=66 # 不能修改目錄?
        17 E_NOTROOT=67 # 非根用戶將以error退出
        18
        19
        20 # 當(dāng)然要使用根用戶來運(yùn)行
        21 if [ "$UID" -ne "$ROOT_UID" ]
        22 then
        23 echo "Must be root to run this script."
        24 exit $E_NOTROOT
        25 fi
        26
        27 if [ -n "$1" ]
        28 # 測(cè)試是否有命令行參數(shù)(非空).
        29 then
        30 lines=$1
        31 else
        32 lines=$LINES # 默認(rèn),如果不在命令行中指定
        33 fi
        34
        35
        36 # Stephane Chazelas 建議使用下邊
        37 #+ 的更好方法來檢測(cè)命令行參數(shù).
        38 #+ 但對(duì)于這章來說還是有點(diǎn)超前.
        39 #
        40 # E_WRONGARGS=65 # 非數(shù)值參數(shù)(錯(cuò)誤的參數(shù)格式)
        41 #
        42 # case "$1" in
        43 # "" ) lines=50;;
        44 # *[!0-9]*) echo "Usage: `basename $0` file-to-cleanup"; exit $E_WRONGARGS;;
        45 # * ) lines=$1;;
        46 # esac
        47 #
        48 #* 直到"Loops"的章節(jié)才會(huì)對(duì)上邊的內(nèi)容進(jìn)行詳細(xì)的描述.
        49
        50
        51 cd $LOG_DIR
        52
        53 if [ `pwd` != "$LOG_DIR" ] # 或者 if[ "$PWD" != "$LOG_DIR" ]
        54 # 不在 /var/log中?
        55 then
        56 echo "Can't change to $LOG_DIR."
        57 exit $E_XCD
        58 fi # 在處理log file之前,再確認(rèn)一遍當(dāng)前目錄是否正確.
        59
        60 # 更有效率的做法是
        61 #
        62 # cd /var/log || {
        63 # echo "Cannot change to necessary directory." >&2
        64 # exit $E_XCD;
        65 # }
        66
        67
        68
        69
        70 tail -$lines messages > mesg.temp # 保存log file消息的最后部分.
        71 mv mesg.temp messages # 變?yōu)樾碌膌og目錄.
        72
        73
        74 # cat /dev/null > messages
        75 #* 不再需要了,使用上邊的方法更安全.
        76
        77 cat /dev/null > wtmp # ': > wtmp' 和 '> wtmp'具有相同的作用
        78 echo "Logs cleaned up."
        79
        80 exit 0
        81 # 退出之前返回0,返回0表示成功.
        82 #
        ################################End Script#########################################

        因?yàn)槟憧赡芟M麑⑾到y(tǒng)log全部消滅,這個(gè)版本留下了log消息最后的部分.你將不斷地找到新
        的方法來完善這個(gè)腳本,并提高效率.

        要注意,在每個(gè)腳本的開頭都使用"#!",這意味著告訴你的系統(tǒng)這個(gè)文件的執(zhí)行需要指定一個(gè)解
        釋器.#!實(shí)際上是一個(gè)2字節(jié)[1]的魔法數(shù)字,這是指定一個(gè)文件類型的特殊標(biāo)記, 換句話說, 在
        這種情況下,指的就是一個(gè)可執(zhí)行的腳本(鍵入man magic來獲得關(guān)于這個(gè)迷人話題的更多詳細(xì)
        信息).在#!之后接著是一個(gè)路徑名.這個(gè)路徑名指定了一個(gè)解釋腳本中命令的程序,這個(gè)程序可
        以是shell,程序語言或者是任意一個(gè)通用程序.這個(gè)指定的程序從頭開始解釋并且執(zhí)行腳本中
        的命令(從#!行下邊的一行開始),忽略注釋.[2]
        如:
        1 #!/bin/sh
        2 #!/bin/bash
        3 #!/usr/bin/perl
        4 #!/usr/bin/tcl
        5 #!/bin/sed -f
        6 #!/usr/awk -f

        上邊每一個(gè)腳本頭的行都指定了一個(gè)不同的命令解釋器,如果是/bin/sh,那么就是默認(rèn)shell
        (在Linux系統(tǒng)中默認(rèn)是Bash).[3]使用#!/bin/sh,在大多數(shù)商業(yè)發(fā)行的UNIX上,默認(rèn)是Bourne
        shell,這將讓你的腳本可以正常的運(yùn)行在非Linux機(jī)器上,雖然這將會(huì)犧牲Bash一些獨(dú)特的特征.
        腳本將與POSIX[4] 的sh標(biāo)準(zhǔn)相一致.

        注意: #! 后邊給出的路徑名必須是正確的,否則將會(huì)出現(xiàn)一個(gè)錯(cuò)誤消息,通常是
        "Command not found",這將是你運(yùn)行這個(gè)腳本時(shí)所得到的唯一結(jié)果.

        當(dāng)然"#!"也可以被忽略,不過這樣你的腳本文件就只能是一些命令的集合,不能夠使用shell內(nèi)建
        的指令了,如果不能使用變量的話,當(dāng)然這也就失去了腳本編程的意義了.

        注意:這個(gè)例子鼓勵(lì)你使用模塊化的方式來編寫腳本,平時(shí)也要注意收集一些零碎的代碼,
        這些零碎的代碼可能用在你將來編寫的腳本中.這樣你就可以通過這些代碼片段來構(gòu)
        造一個(gè)較大的工程用例. 以下邊腳本作為序,來測(cè)試腳本被調(diào)用的參數(shù)是否正確.
        ################################Start Script#######################################
        1 E_WRONG_ARGS=65
        2 script_parameters="-a -h -m -z"
        3 # -a = all, -h = help, 等等.
        4
        5 if [ $# -ne $Number_of_expected_args ]
        6 then
        7 echo "Usage: `basename $0` $script_parameters"
        8 # `basename $0`是這個(gè)腳本的文件名
        9 exit $E_WRONG_ARGS
        10 fi
        ################################End Script#########################################
        大多數(shù)情況下,你需要編寫一個(gè)腳本來執(zhí)行一個(gè)特定的任務(wù),在本章中第一個(gè)腳本就是一個(gè)這樣
        的例子, 然后你會(huì)修改它來完成一個(gè)不同的,但比較相似的任務(wù).用變量來代替寫死的常量,就是
        一個(gè)好方法,將重復(fù)的代碼放到一個(gè)函數(shù)中,也是一種好習(xí)慣.


        2.1 調(diào)用一個(gè)腳本
        ----------------
        編寫完腳本之后,你可以使用sh scriptname,[5]或者bash scriptname來調(diào)用它.
        (不推薦使用sh <SCRIPTNAME,因?yàn)檫@禁用了腳本從STDIN中讀數(shù)據(jù)的功能.)
        更方便的方法是讓腳本本身就具有可執(zhí)行權(quán)限,通過chmod命令可以修改.

        比如:
        chmod 555 scriptname (允許任何人都具有 可讀和執(zhí)行權(quán)限) [6]
        或:
        chmod +rx scriptname (允許任何人都具有 可讀和執(zhí)行權(quán)限)
        chmod u+rx scriptname (只給腳本的所有者 可讀和執(zhí)行權(quán)限)

        既然腳本已經(jīng)具有了可執(zhí)行權(quán)限,現(xiàn)在你可以使用./scriptname.[7]來測(cè)試它了.如果這個(gè)腳本
        以一個(gè)"#!"行開頭,那么腳本將會(huì)調(diào)用合適的命令解釋器來運(yùn)行.

        最后一步,在腳本被測(cè)試和debug之后,你可能想把它移動(dòng)到/usr/local/bin(當(dāng)然是以root身份)
        ,來讓你的腳本對(duì)所有用戶都有用.這樣用戶就可以直接敲腳本名字來運(yùn)行了.

        注意事項(xiàng):
        [1] 那些具有UNIX味道的腳本(基于4.2BSD)需要一個(gè)4字節(jié)的魔法數(shù)字,在#!后邊需要一個(gè)
        空格#! /bin/sh.
        [2] 腳本中的#!行的最重要的任務(wù)就是命令解釋器(sh或者bash).因?yàn)檫@行是以#開始的,
        當(dāng)命令解釋器執(zhí)行這個(gè)腳本的時(shí)候,會(huì)把它作為一個(gè)注釋行.當(dāng)然,在這之前,這行語句
        已經(jīng)完成了它的任務(wù),就是調(diào)用命令解釋器.

        如果在腳本的里邊還有一個(gè)#!行,那么bash將把它認(rèn)為是一個(gè)一般的注釋行.
        1 #!/bin/bash
        2
        3 echo "Part 1 of script."
        4 a=1
        5
        6 #!/bin/bash
        7 # 這將不會(huì)開始一個(gè)新腳本.
        8
        9 echo "Part 2 of script."
        10 echo $a # Value of $a stays at 1.
        [3] 這里可以玩一些小技巧.
        1 #!/bin/rm
        2 # 自刪除腳本.
        3
        4 # 當(dāng)你運(yùn)行這個(gè)腳本時(shí),基本上什么都不會(huì)發(fā)生...除非這個(gè)文件消失不見.
        5
        6 WHATEVER=65
        7
        8 echo "This line will never print (betcha!)."
        9
        10 exit $WHATEVER # 沒關(guān)系,腳本是不會(huì)在這退出的.
        當(dāng)然,你還可以試試在一個(gè)README文件的開頭加上#!/bin/more,并讓它具有執(zhí)行權(quán)限.
        結(jié)果將是文檔自動(dòng)列出自己的內(nèi)容.(一個(gè)使用cat命令的here document可能是一個(gè)
        更好的選則,--見Example 17-3).
        [4] 可移植的操作系統(tǒng)接口,標(biāo)準(zhǔn)化類UNIX操作系統(tǒng)的一種嘗試.POSIX規(guī)范可以在
        http://www.opengroup.org/onlinepubs/007904975/toc.htm中查閱.
        [5] 小心:使用sh scriptname來調(diào)用腳本的時(shí)候?qū)?huì)關(guān)閉一些Bash特定的擴(kuò)展,腳本可能
        因此而調(diào)用失敗.
        [6] 腳本需要讀和執(zhí)行權(quán)限,因?yàn)閟hell需要讀這個(gè)腳本.
        [7] 為什么不直接使用scriptname來調(diào)用腳本?如果你當(dāng)前的目錄下($PWD)正好有你想要
        執(zhí)行的腳本,為什么它運(yùn)行不了呢?失敗的原因是,出于安全考慮,當(dāng)前目錄并沒有被
        加在用戶的$PATH變量中.因此,在當(dāng)前目錄下調(diào)用腳本必須使用./scriptname這種
        形式.


        2.2 初步的練習(xí)
        --------------
        1. 系統(tǒng)管理員經(jīng)常會(huì)為了自動(dòng)化一些常用的任務(wù)而編寫腳本.舉出幾個(gè)這種有用的腳本的實(shí)例.
        2. 編寫一個(gè)腳本,顯示時(shí)間和日期,列出所有的登錄用戶,顯示系統(tǒng)的更新時(shí)間.然后這個(gè)腳本
        將會(huì)把這些內(nèi)容保存到一個(gè)log file中.


        第二部分 基本
        ++++++++++++++++

        第3章 特殊字符
        ================

        # 注釋,行首以#開頭為注釋(#!是個(gè)例外).

        1 # This line is a comment.

        注釋也可以存在于本行命令的后邊.

        1 echo "A comment will follow." # 注釋在這里
        2 # ^ 注意#前邊的空白

        注釋也可以在本行空白的后邊.

        1 # A tab precedes this comment.

        注意:命令是不能跟在同一行上注釋的后邊的,沒有辦法,在同一行上,注釋的后邊想
        要再使用命令,只能另起一行.
        當(dāng)然,在echo命令中被轉(zhuǎn)義的#是不能作為注釋的.
        同樣的,#也可以出現(xiàn)在特定的參數(shù)替換結(jié)構(gòu)中或者是數(shù)字常量表達(dá)式中.

        1 echo "The # here does not begin a comment."
        2 echo 'The # here does not begin a comment.'
        3 echo The \# here does not begin a comment.
        4 echo The # 這里開始一個(gè)注釋
        5
        6 echo ${PATH#*:} # 參數(shù)替換,不是一個(gè)注釋
        7 echo $(( 2#101011 )) # 數(shù)制轉(zhuǎn)換,不是一個(gè)注釋
        8
        9 # Thanks, S.C.

        標(biāo)準(zhǔn)的引用和轉(zhuǎn)義字符("'\)可以用來轉(zhuǎn)義#

        ; 命令分隔符,可以用來在一行中來寫多個(gè)命令.

        1 echo hello; echo there
        2
        3
        4 if [ -x "$filename" ]; then # 注意:"if"和"then"需要分隔
        5 # 為啥?
        6 echo "File $filename exists."; cp $filename $filename.bak
        7 else
        8 echo "File $filename not found."; touch $filename
        9 fi; echo "File test complete."

        有時(shí)候需要轉(zhuǎn)義

        ;; 終止"case"選項(xiàng).

        1 case "$variable" in
        2 abc) echo "\$variable = abc" ;;
        3 xyz) echo "\$variable = xyz" ;;
        4 esac

        . .命令等價(jià)于source命令(見Example 11-20).這是一個(gè)bash的內(nèi)建命令.

        . .作為文件名的一部分.如果作為文件名的前綴的話,那么這個(gè)文件將成為隱藏文件.
        將不被ls命令列出.

        bash$ touch .hidden-file
        bash$ ls -l
        total 10
        -rw-r--r-- 1 bozo 4034 Jul 18 22:04 data1.addressbook
        -rw-r--r-- 1 bozo 4602 May 25 13:58 data1.addressbook.bak
        -rw-r--r-- 1 bozo 877 Dec 17 2000 employment.addressbook


        bash$ ls -al
        total 14
        drwxrwxr-x 2 bozo bozo 1024 Aug 29 20:54 ./
        drwx------ 52 bozo bozo 3072 Aug 29 20:51 ../
        -rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.addressbook
        -rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.addressbook.bak
        -rw-r--r-- 1 bozo bozo 877 Dec 17 2000 employment.addressbook
        -rw-rw-r-- 1 bozo bozo 0 Aug 29 20:54 .hidden-file

        .命令如果作為目錄名的一部分的話,那么.表達(dá)的是當(dāng)前目錄.".."表示上一級(jí)目錄.

        bash$ pwd
        /home/bozo/projects

        bash$ cd .
        bash$ pwd
        /home/bozo/projects

        bash$ cd ..
        bash$ pwd
        /home/bozo/

        .命令經(jīng)常作為一個(gè)文件移動(dòng)命令的目的地.

        bash$ cp /home/bozo/current_work/junk/* .

        . .字符匹配,這是作為正則表達(dá)是的一部分,用來匹配任何的單個(gè)字符.

        " 部分引用."STRING"阻止了一部分特殊字符,具體見第5章.

        ' 全引用. 'STRING' 阻止了全部特殊字符,具體見第5章.

        , 逗號(hào)鏈接了一系列的算術(shù)操作,雖然里邊所有的內(nèi)容都被運(yùn)行了,但只有最后一項(xiàng)被
        返回.

        如:
        1 let "t2 = ((a = 9, 15 / 3))" # Set "a = 9" and "t2 = 15 / 3"

        \ 轉(zhuǎn)義字符,如\X等價(jià)于"X"或'X',具體見第5章.

        / 文件名路徑分隔符.或用來做除法操作.

        ` 后置引用,命令替換,具體見第14章

        : 空命令,等價(jià)于"NOP"(no op,一個(gè)什么也不干的命令).也可以被認(rèn)為與shell的內(nèi)建命令(true)作用相同.":"命令是一
        個(gè)bash的內(nèi)建命令,它的返回值為0,就是shell返回的true.

        如:
        1 :
        2 echo $? # 0

        死循環(huán),如:

        1 while :
        2 do
        3 operation-1
        4 operation-2
        5 ...
        6 operation-n
        7 done
        8
        9 # 與下邊相同:
        10 # while true
        11 # do
        12 # ...
        13 # done

        在if/then中的占位符,如:
        1 if condition
        2 then : # 什么都不做,引出分支.
        3 else
        4 take-some-action
        5 fi

        在一個(gè)2元命令中提供一個(gè)占位符,具體見Example 8-2,和"默認(rèn)參數(shù)".如:
        1 : ${username=`whoami`}
        2 # ${username=`whoami`} 如果沒有":"的話,將給出一個(gè)錯(cuò)誤,除非"username"是
        3 # 個(gè)命令
        在here document中提供一個(gè)占位符,見Example 17-10.

        使用"參數(shù)替換"來評(píng)估字符串變量(見Example 9-14).如:
        1 : ${HOSTNAME?} ${USER?} ${MAIL?}
        2 # 如果一個(gè)或多個(gè)必要的環(huán)境變量沒被設(shè)置的話,
        3 #+ 就打印錯(cuò)誤信息.

        "變量擴(kuò)展/子串替換"
        在和 > (重定向操作符)結(jié)合使用時(shí),把一個(gè)文件截?cái)嗟?長度,沒有修改它的權(quán)限.
        如果文件在之前并不存在,那么就創(chuàng)建它.如:
        1 : > data.xxx #文件"data.xxx"現(xiàn)在被清空了.
        2
        3 #與 cat /dev/null >data.xxx 的作用相同
        4 #然而,這不會(huì)產(chǎn)生一個(gè)新的進(jìn)程,因?yàn)?#34;:"是一個(gè)內(nèi)建命令.
        具體參見Example 12-14.

        在和>>重定向操作符結(jié)合使用時(shí),將不會(huì)對(duì)想要附加的文件產(chǎn)生任何影響.
        如果文件不存在,將創(chuàng)建.
        注意: 這只適用于正規(guī)文件,而不是管道,符號(hào)連接,和某些特殊文件.

        也可能用來作為注釋行,雖然我們不推薦這么做.使用#來注釋的話,將關(guān)閉剩余行的
        錯(cuò)誤檢查,所以可以在注釋行中寫任何東西.然而,使用:的話將不會(huì)這樣.如:
        1 : This is a comment thar generates an error,(if [ $x -eq 3] ).

        ":"還用來在/etc/passwd和$PATH變量中用來做分隔符.
        bash$ echo $PATH
        /usr/local/bin:/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games
        ! 取反操作符,將反轉(zhuǎn)"退出狀態(tài)"結(jié)果,(見Example 6-2).也會(huì)反轉(zhuǎn)test操作符的意義.比
        如修改=為!=.!操作是Bash的一個(gè)關(guān)鍵字.

        在一個(gè)不同的上下文中,!也會(huì)出現(xiàn)在"間接變量引用"見Example 9-22.

        在另一種上下文中,!還能反轉(zhuǎn)bash的"history mechanism"(見附錄J 歷史命令)
        需要注意的是,在一個(gè)腳本中,"history mechanism"是被禁用的.

        * 萬能匹配字符,用于文件名匹配(這個(gè)東西有個(gè)專有名詞叫file globbing),或者是正則
        表達(dá)式中.注意:在正則表達(dá)式匹配中的作用和在文件名匹配中的作用是不同的.
        bash$ echo *
        abs-book.sgml add-drive.sh agram.sh alias.sh
        * 數(shù)學(xué)乘法.
        **是冪運(yùn)算.
        ? 測(cè)試操作.在一個(gè)確定的表達(dá)式中,用?來測(cè)試結(jié)果.
        (())結(jié)構(gòu)可以用來做數(shù)學(xué)計(jì)算或者是寫c代碼,那?就是c語言的3元操作符的
        一個(gè).
        在"參數(shù)替換"中,?測(cè)試一個(gè)變量是否被set了.
        ? 在file globbing中和在正則表達(dá)式中一樣匹配任意的單個(gè)字符.

        $ 變量替換
        1 var1=5
        2 var2=23skidoo
        3
        4 echo $var1 # 5
        5 echo $var2 # 23skidoo
        $ 在正則表達(dá)式中作為行結(jié)束符.
        ${} 參數(shù)替換,見9.3節(jié).
        $*,$@ 位置參數(shù)
        $? 退出狀態(tài)變量.$?保存一個(gè)命令/一個(gè)函數(shù)或者腳本本身的退出狀態(tài).
        $$ 進(jìn)程ID變量.這個(gè)$$變量保存運(yùn)行腳本進(jìn)程ID
        () 命令組.如:
        1 (a=hello;echo $a)
        注意:在()中的命令列表,將作為一個(gè)子shell來運(yùn)行.
        在()中的變量,由于是在子shell中,所以對(duì)于腳本剩下的部分是不可用的.
        如:
        1 a=123
        2 ( a=321; )
        3
        4 echo "a = $a" # a = 123
        5 # 在圓括號(hào)中a變量,更像是一個(gè)局部變量.

        用在數(shù)組初始化,如:
        1 Array=(element1,element2,element3)

        {xxx,yyy,zzz...}
        大括號(hào)擴(kuò)展,如:
        1 cat {file1,file2,file3} > combined_file
        2 # 把file1,file2,file3連接在一起,并且重定向到combined_file中.
        3
        4
        5 cp file22.{txt,backup}
        6 # 拷貝"file22.txt" 到"file22.backup"中

        一個(gè)命令可能會(huì)對(duì)大括號(hào)中的以逗號(hào)分割的文件列表起作用[1]. file globbing將對(duì)
        大括號(hào)中的文件名作擴(kuò)展.
        注意: 在大括號(hào)中,不允許有空白,除非這個(gè)空白是有意義的.
        echo {file1,file2}\ :{\ A," B",' C'}
        file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C
        {} 代碼塊.又被稱為內(nèi)部組.事實(shí)上,這個(gè)結(jié)構(gòu)創(chuàng)建了一個(gè)匿名的函數(shù).但是與函數(shù)不同的
        是,在其中聲明的變量,對(duì)于腳本其他部分的代碼來說還是可見的.如:
        bash$
        {
        local a;
        a= 123;
        }
        bash中的local申請(qǐng)的變量只能夠用在函數(shù)中.

        1 a=123
        2 { a=321; }
        3 echo "a = $a" # a = 321 (說明在代碼塊中對(duì)變量a所作的修改,影響了外邊的變量a)
        4
        5 # Thanks, S.C.

        下邊的代碼展示了在{}結(jié)構(gòu)中代碼的I/O重定向.

        Example 3-1. 代碼塊和I/O重定向
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # 從 /etc/fstab中讀行
        3
        4 File=/etc/fstab
        5
        6 {
        7 read line1
        8 read line2
        9 } < $File
        10
        11 echo "First line in $File is:"
        12 echo "$line1"
        13 echo
        14 echo "Second line in $File is:"
        15 echo "$line2"
        16
        17 exit 0
        18
        19 # 現(xiàn)在,你怎么分析每行的分割域
        20 # 暗示: 使用 awk.
        ################################End Script#########################################

        Example 3-2. 將一個(gè)代碼塊的結(jié)果保存到文件
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # rpm-check.sh
        3
        4 # 這個(gè)腳本的目的是為了描述,列表,和確定是否可以安裝一個(gè)rpm包.
        5 # 在一個(gè)文件中保存輸出.
        6 #
        7 # 這個(gè)腳本使用一個(gè)代碼塊來展示
        8
        9 SUCCESS=0
        10 E_NOARGS=65
        11
        12 if [ -z "$1" ]
        13 then
        14 echo "Usage: `basename $0` rpm-file"
        15 exit $E_NOARGS
        16 fi
        17
        18 {
        19 echo
        20 echo "Archive Description:"
        21 rpm -qpi $1 # 查詢說明
        22 echo
        23 echo "Archive Listing:"
        24 rpm -qpl $1 # 查詢列表
        25 echo
        26 rpm -i --test $1 # 查詢r(jià)pm包是否可以被安裝
        27 if [ "$?" -eq $SUCCESS ]
        28 then
        29 echo "$1 can be installed."
        30 else
        31 echo "$1 cannot be installed."
        32 fi
        33 echo
        34 } > "$1.test" # 把代碼塊中的所有輸出都重定向到文件中
        35
        36 echo "Results of rpm test in file $1.test"
        37
        38 # 查看rpm的man頁來查看rpm的選項(xiàng)
        39
        40 exit 0
        ################################End Script#########################################
        注意: 與()中的命令不同的是,{}中的代碼塊將不能正常地開啟一個(gè)新shell.[2]

        {} \; 路徑名.一般都在find命令中使用.這不是一個(gè)shell內(nèi)建命令.
        注意: ";"用來結(jié)束find命令序列的-exec選項(xiàng).

        [] test.
        test的表達(dá)式將在[]中.
        值得注意的是[是shell內(nèi)建test命令的一部分,并不是/usr/bin/test中的擴(kuò)展命令
        的一個(gè)連接.

        [[]] test.
        test表達(dá)式放在[[]]中.(shell關(guān)鍵字)
        具體查看[[]]結(jié)構(gòu)的討論.

        [] 數(shù)組元素
        Array[1]=slot_1
        echo ${Array[1]}

        [] 字符范圍
        在正則表達(dá)式中使用,作為字符匹配的一個(gè)范圍

        (()) 數(shù)學(xué)計(jì)算的擴(kuò)展
        在(())結(jié)構(gòu)中可以使用一些數(shù)字計(jì)算.
        具體參閱((...))結(jié)構(gòu).

        >&>>&>><
        重定向.
        scriptname >filename 重定向腳本的輸出到文件中.覆蓋文件原有內(nèi)容.
        command &>filename 重定向stdout和stderr到文件中
        command >&2 重定向command的stdout到stderr
        scriptname >>filename 重定向腳本的輸出到文件中.添加到文件尾端,如果沒有文件,
        則創(chuàng)建這個(gè)文件.

        進(jìn)程替換,具體見"進(jìn)程替換部分",跟命令替換極其類似.
        (command)>
        <(command)

        <和> 可用來做字符串比較
        <和> 可用在數(shù)學(xué)計(jì)算比較

        << 重定向,用在"here document"

        <<< 重定向,用在"here string"

        <,> ASCII比較
        1 veg1=carrots
        2 veg2=tomatoes
        3
        4 if [[ "$veg1" < "$veg2" ]]
        5 then
        6 echo "Although $veg1 precede $veg2 in the dictionary,"
        7 echo "this implies nothing about my culinary preferences."
        8 else
        9 echo "What kind of dictionary are you using, anyhow?"
        10 fi

        \<,\> 正則表達(dá)式中的單詞邊界.如:
        bash$grep '\' textfile

        | 管道.分析前邊命令的輸出,并將輸出作為后邊命令的輸入.這是一種產(chǎn)生命令鏈的
        好方法.
        1 echo ls -l | sh
        2 # 傳遞"echo ls -l"的輸出到shell中,
        3 #+ 與一個(gè)簡單的"ls -l"結(jié)果相同.
        4
        5
        6 cat *.lst | sort | uniq
        7 # 合并和排序所有的".lst"文件,然后刪除所有重復(fù)的行.

        管道是進(jìn)程間通訊的一個(gè)典型辦法,將一個(gè)進(jìn)程的stdout放到另一個(gè)進(jìn)程的stdin中.
        標(biāo)準(zhǔn)的方法是將一個(gè)一般命令的輸出,比如cat或echo,傳遞到一個(gè)過濾命令中(在這個(gè)
        過濾命令中將處理輸入),得到結(jié)果,如:
        cat $filename1 | $filename2 | grep $search_word

        當(dāng)然輸出的命令也可以傳遞到腳本中.如:
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # uppercase.sh : 修改輸出,全部轉(zhuǎn)換為大寫
        3
        4 tr 'a-z' 'A-Z'
        5 # 字符范圍必須被""引用起來
        6 #+ 來阻止產(chǎn)生單字符的文件名.
        7
        8 exit 0
        ################################End Script#########################################

        現(xiàn)在讓我們輸送ls -l的輸出到一個(gè)腳本中.
        bash$ ls -l | ./uppercase.sh
        -RW-RW-R-- 1 BOZO BOZO 109 APR 7 19:49 1.TXT
        -RW-RW-R-- 1 BOZO BOZO 109 APR 14 16:48 2.TXT
        -RW-R--R-- 1 BOZO BOZO 725 APR 20 20:56 DATA-FILE

        注意:管道中的一個(gè)進(jìn)程的stdout必須被下一個(gè)進(jìn)程作為stdin讀入.否則,數(shù)據(jù)流會(huì)阻
        塞,并且管道將產(chǎn)生非預(yù)期的行為.
        如:
        1 cat file1 file2 | ls -l | sort
        2 #從"cat file1 file2"中的輸出并沒出現(xiàn)

        作為子進(jìn)程的運(yùn)行的管道,不能夠改變腳本的變量.
        1 variable="initial_value"
        2 echo "new_value" | read variable
        3 echo "variable = $variable" #variable = initial_value
        如果管道中的某個(gè)命令產(chǎn)生了一個(gè)異常,并中途失敗,那么這個(gè)管道將過早的終止.
        這種行為被叫做a broken pipe,并且這種狀態(tài)下將發(fā)送一個(gè)SIGPIPE信號(hào).

        >| 強(qiáng)制重定向(即使設(shè)置了noclobber選項(xiàng)--就是-C選項(xiàng)).這將強(qiáng)制的覆蓋一個(gè)現(xiàn)存文件.

        || 或-邏輯操作.

        & 后臺(tái)運(yùn)行命令.一個(gè)命令后邊跟一個(gè)&,將表示在后臺(tái)運(yùn)行.
        bash$sleep 10 &
        [1] 850
        [1]+ Done sleep 10
        在一個(gè)腳本中,命令和循環(huán)都可能運(yùn)行在后臺(tái).

        Example 3-3. 在后臺(tái)運(yùn)行一個(gè)循環(huán)
        ################################Start Script#######################################
        1 #!/bin/bash
        2 #background-loop.sh
        3
        4 for i in 1 2 3 4 5 6 7 8 9 10 #第一個(gè)循環(huán)
        5 do
        6 echo -n "$i"
        7 done& #在后臺(tái)運(yùn)行這個(gè)循環(huán)
        8 #在第2個(gè)循環(huán)之后,將在某些時(shí)候執(zhí)行.
        9
        10 echo #這個(gè)'echo'某些時(shí)候?qū)⒉粫?huì)顯示.
        11
        12 for i in 11 12 13 14 15 16 17 18 19 20 #第二個(gè)循環(huán)
        13 do
        14 echo -n "$i"
        15 done
        16
        17 echo #這個(gè)'echo'某些時(shí)候?qū)⒉粫?huì)顯示.
        18
        19 #--------------------------------------------------------
        20
        21 #期望的輸出應(yīng)該是
        22 #1 2 3 4 5 6 7 8 9 10
        23 #11 12 13 14 15 16 17 18 19 20
        24
        25 #然而實(shí)際的結(jié)果有可能是
        26 #11 12 13 14 15 16 17 18 19 20
        27 #1 2 3 4 5 6 7 8 9 10 bozo $
        28 #(第2個(gè)'echo'沒執(zhí)行,為什么?)
        29
        30 #也可能是
        31 #1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
        32 #(第1個(gè)'echo'沒執(zhí)行,為什么?)
        33
        34 #非常少見的執(zhí)行結(jié)果,也有可能是:
        35 #11 12 13 1 2 3 4 5 6 7 8 9 10 14 15 16 17 18 19 20
        36 #前臺(tái)的循環(huán)先于后臺(tái)的執(zhí)行
        37
        38 exit 0
        39
        40 # Nasimuddin Ansari 建議加一句 sleep 1
        41 #+ 在 6行和14行的 echo -n "$i"之后加
        42 #+ 將看到一些樂趣
        ################################End Script#########################################
        注意:在一個(gè)腳本內(nèi)后臺(tái)運(yùn)行一個(gè)命令,有可能造成這個(gè)腳本的掛起,等待一個(gè)按鍵
        響應(yīng).幸運(yùn)的是,我們可以在Example 11-24附近,看到這個(gè)問題的解決辦法.

        && 與-邏輯操作.

        - 選項(xiàng),前綴.在所有的命令內(nèi)如果想使用選項(xiàng)參數(shù)的話,前邊都要加上"-".

        COMMAND -[Option1][Option2][...]
        ls -al
        sort -dfu $filename
        set -- $variable

        1 if [ $file1 -ot $file2 ]
        2 then
        3 echo "File $file1 is older than $file2."
        4 fi
        5
        6 if [ "$a" -eq "$b" ]
        7 then
        8 echo "$a is equal to $b."
        9 fi
        10
        11 if [ "$c" -eq 24 -a "$d" -eq 47 ]
        12 then
        13 echo "$c equals 24 and $d equals 47."
        14 fi

        - 用于重定向 stdin 或 stdout.

        ################################Start Script#######################################
        1 (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
        2 # 從一個(gè)目錄移動(dòng)整個(gè)目錄樹到另一個(gè)目錄
        3 # [courtesy Alan Cox <a.cox@swansea.ac.uk>, with a minor change]
        4
        5 # 1) cd /source/directory 源目錄
        6 # 2) && 與操作,如果cd命令成功了,那么就執(zhí)行下邊的命令
        7 # 3) tar cf - . 'c'創(chuàng)建一個(gè)新文檔,'f'后邊跟'-'指定目標(biāo)文件作為stdout
        8 # '-'后邊的'f'(file)選項(xiàng),指明作為stdout的目標(biāo)文件.
        9 # 并且在當(dāng)前目錄('.')執(zhí)行.
        10 # 4) | 管道...
        11 # 5) ( ... ) 一個(gè)子shell
        12 # 6) cd /dest/directory 改變當(dāng)前目錄到目標(biāo)目錄.
        13 # 7) && 與操作,同上.
        14 # 8) tar xpvf - 'x'解檔,'p'保證所有權(quán)和文件屬性,
        15 # 'v'發(fā)完整消息到stdout
        16 # 'f'后邊跟'-',從stdin讀取數(shù)據(jù)
        17 #
        18 # 注意:'x' 是一個(gè)命令, 'p', 'v', 'f' 是選項(xiàng).
        19 # Whew!
        20
        21
        22
        23 # 更優(yōu)雅的寫法應(yīng)該是
        24 # cd source/directory
        25 # tar cf - . | (cd ../dest/directory; tar xpvf -)
        26 #
        27 # 當(dāng)然也可以這么寫:
        28 # cp -a /source/directory/* /dest/directory
        29 # 或者:
        30 # cp -a /source/directory/* /source/directory/.[^.]* /dest/directory
        31 # 如果在/source/directory中有隱藏文件的話.
        ################################End Script#########################################

        ################################Start Script#######################################
        1 bunzip2 linux-2.6.13.tar.bz2 | tar xvf -
        2 # --未解壓的tar文件-- | --然后把它傳遞到"tar"中--
        3 # 如果 "tar" 沒能夠正常的處理"bunzip2",
        4 # 這就需要使用管道來執(zhí)行2個(gè)單獨(dú)的步驟來完成它.
        5 # 這個(gè)練習(xí)的目的是解檔"bzipped"的kernel源文件.
        ################################End Script#########################################
        注意:在上邊這個(gè)例子中'-'不太象是bash的操作符,而更像是tar的參數(shù).
        bash$echo "whatever" | cat -
        whatever

        在需要一個(gè)文件名的地方,-重定向輸出到stdout(如在tar和cf命令中),或者從
        stdin中接受輸入,而不是從一個(gè)文件中接受輸入.這是在管道中作為一個(gè)過濾
        器,來使用文件定位工具的一種辦法.
        bash$file
        用法: file [-bciknvzl] [-f namefile] [-m magicfiles] file...
        上邊這個(gè)例子file將會(huì)出錯(cuò),提示你如何使用file命令.

        添加一個(gè)"-"將得到一個(gè)更有用的結(jié)果.這將使得shell等待用戶輸入.
        bash$file -
        abc
        standard input: ASCII text

        bash$file -
        #!/bin/bash
        standard input: Bourn-Again shell script tesxt executable

        現(xiàn)在命令從stdin中接受了輸入,并分析它.

        "-"常用于管道后邊的命令,具體參看33.7節(jié),來看使用技巧.
        使用diff命令來和另一個(gè)文件的一部分進(jìn)行比較.
        grep Linux file1 | diff file2 -

        最后,一個(gè)真實(shí)世界的使用tar命令的例子.

        Example 3-4. 備份最后一天所有修改的文件.
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 # 在一個(gè)"tarball"中(經(jīng)過tar和gzip處理過的文件)
        4 #+ 備份最后24小時(shí)當(dāng)前目錄下d所有修改的文件.
        5
        6 BACKUPFILE=backup-$(date +%m-%d-%Y)
        7 # 在備份文件中嵌入時(shí)間.
        8 # Thanks, Joshua Tschida, for the idea.
        9 archive=${1:-$BACKUPFILE}
        10 # 如果在命令行中沒有指定備份文件的文件名,
        11 #+ 那么將默認(rèn)使用"backup-MM-DD-YYYY.tar.gz".
        12
        13 tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
        14 gzip $archive.tar
        15 echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."
        16
        17
        18 # Stephane Chazelas指出上邊代碼,
        19 #+ 如果在發(fā)現(xiàn)太多的文件的時(shí)候,或者是如果文件
        20 #+ 名包括空格的時(shí)候,將執(zhí)行失敗.
        21
        22 # Stephane Chazelas建議使用下邊的兩種代碼之一
        23 # -------------------------------------------------------------------
        24 # find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
        25 # 使用gnu版本的find.
        26
        27
        28 # find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;
        29 # 對(duì)于其他風(fēng)格的UNIX便于移植,但是比較慢.
        30 # -------------------------------------------------------------------
        31
        32
        33 exit 0
        ################################End Script#########################################

        注意:以"-"開頭的文件名在使用"-"作為重定向操作符的時(shí)候,可能會(huì)產(chǎn)生問題.
        應(yīng)該寫一個(gè)腳本來檢查這個(gè)問題,并給這個(gè)文件加上合適的前綴.如:
        ./-FILENAME, $PWD/-FILENAME,或$PATHNAME/-FILENAME.

        如果變量的值以"-"開頭,可能也會(huì)引起問題.
        1 var="-n"
        2 echo $var
        3 #具有"echo -n"的效果了,這樣什么都不會(huì)輸出的.

        - 之前工作的目錄."cd -"將回到之前的工作目錄,具體請(qǐng)參考"$OLDPWD"環(huán)境變量.
        注意:一定要和之前討論的重定向功能分開,但是只能依賴上下文區(qū)分.

        - 算術(shù)減號(hào).

        = 算術(shù)等號(hào),有時(shí)也用來比較字符串.
        1 a=28
        2 echo $a # 28

        + 算術(shù)加號(hào),也用在正則表達(dá)式中.
        + 選項(xiàng),對(duì)于特定的命令來說使用"+"來打開特定的選項(xiàng),用"-"來關(guān)閉特定的選項(xiàng).

        % 算術(shù)取模運(yùn)算.也用在正則表達(dá)式中.

        ~ home目錄.相當(dāng)于$HOME變量.~bozo是bozo的home目錄,并且ls ~bozo將列出其中的
        內(nèi)容. ~/就是當(dāng)前用戶的home目錄,并且ls ~/將列出其中的內(nèi)容,如:
        bash$ echo ~bozo
        /home/bozo

        bash$ echo ~
        /home/bozo

        bash$ echo ~/
        /home/bozo/

        bash$ echo ~:
        /home/bozo:

        bash$ echo ~nonexistent-user
        ~nonexistent-user

        ~+ 當(dāng)前工作目錄,相當(dāng)于$PWD變量.

        ~- 之前的工作目錄,相當(dāng)于$OLDPWD內(nèi)部變量.

        =~ 用于正則表達(dá)式,這個(gè)操作將在正則表達(dá)式匹配部分講解,只有version3才支持.

        ^ 行首,正則表達(dá)式中表示行首."^"定位到行首.


        控制字符
        修改終端或文本顯示的行為.控制字符以CONTROL + key組合.
        控制字符在腳本中不能正常使用.
        Ctl-B 光標(biāo)后退,這應(yīng)該依賴于bash輸入的風(fēng)格,默認(rèn)是emacs風(fēng)格的.
        Ctl-C Break,終止前臺(tái)工作.
        Ctl-D 從當(dāng)前shell登出(和exit很像)
        "EOF"(文件結(jié)束符).這也能從stdin中終止輸入.
        在console或者在xterm window中輸入的時(shí)候,Ctl-D將刪除光標(biāo)下字符.
        當(dāng)沒有字符時(shí),Ctrl-D將退出當(dāng)前會(huì)話.在xterm window也有關(guān)閉窗口
        的效果.
        Ctl-G beep.在一些老的終端,將響鈴.
        Ctl-H backspace,刪除光標(biāo)前邊的字符.如:
        1 #!/bin/bash
        2 # 在一個(gè)變量中插入Ctl-H
        3
        4 a="^H^H" # 兩個(gè) Ctl-H (backspaces).
        5 echo "abcdef" # abcdef
        6 echo -n "abcdef$a " # abcd f
        7 # 注意結(jié)尾的空格 ^ ^ 兩個(gè) twice.
        8 echo -n "abcdef$a" # abcdef
        9 # 結(jié)尾沒有空格 沒有 backspace 的效果了(why?).
        10 # 結(jié)果并不像期望的那樣
        11 echo; echo
        Ctl-I 就是tab鍵.
        Ctl-J 新行.
        Ctl-K 垂直tab.(垂直tab?新穎,沒聽過)
        作用就是刪除光標(biāo)到行尾的字符.
        Ctl-L clear,清屏.
        Ctl-M 回車
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # Thank you, Lee Maschmeyer, for this example.
        3
        4 read -n 1 -s -p $'Control-M leaves cursor at beginning of this line. Press Enter. \x0d'
        5 #當(dāng)然,'0d'就是二進(jìn)制的回車.
        6 echo >&2 # '-s'參數(shù)使得任何輸入都不將回顯出來
        7 #+ 所以,明確的重起一行是必要的.
        8
        9 read -n 1 -s -p $'Control-J leaves cursor on next line. \x0a'
        10 echo >&2 # Control-J 是換行.
        11
        12 ###
        13
        14 read -n 1 -s -p $'And Control-K\x0bgoes straight down.'
        15 echo >&2 # Control-K 是垂直制表符.
        16
        17 # 關(guān)于垂直制表符效果的一個(gè)更好的例子見下邊:
        18
        19 var=$'\x0aThis is the bottom line\x0bThis is the top line\x0a'
        20 echo "$var"
        21 # 這句與上邊的例子使用的是同樣的辦法,然而:
        22 echo "$var" | col
        23 # 這將造成垂直制表符右邊的部分在左邊部分的上邊.
        24 # 這也解釋了為什么我們要在行首和行尾加上一個(gè)換行符--
        25 #+ 來避免一個(gè)混亂的屏幕輸出.
        26
        27 # Lee Maschmeyer的解釋:
        28 # ---------------------
        29 # In the [first vertical tab example] . . . the vertical tab
        29 # 在這里[第一個(gè)垂直制表符的例子中] . . . 這個(gè)垂直制表符
        30 #+ makes the printing go straight down without a carriage return.
        31 # This is true only on devices, such as the Linux console,
        32 #+ that can't go "backward."
        33 # The real purpose of VT is to go straight UP, not down.
        34 # It can be used to print superscripts on a printer.
        34 # 它可以用來在一個(gè)打印機(jī)上打印上標(biāo).
        35 # col的作用,可以用來模仿VT的合適的行為.
        36
        37 exit 0
        ################################End Script#########################################
        Ctl-Q 繼續(xù)(等價(jià)于XON字符),這個(gè)繼續(xù)的標(biāo)準(zhǔn)輸入在一個(gè)終端里
        Ctl-S 掛起(等價(jià)于XOFF字符),這個(gè)被掛起的stdin在一個(gè)終端里,用Ctl-Q恢復(fù)
        Ctl-U 刪除光標(biāo)到行首的所有字符,在某些設(shè)置下,刪除全行.
        Ctl-V 當(dāng)輸入字符時(shí),Ctl-V允許插入控制字符.比如,下邊2個(gè)例子是等價(jià)的
        echo -e '\x0a'
        echo
        Ctl-V在文本編輯器中十分有用,在vim中一樣.
        Ctl-W 刪除當(dāng)前光標(biāo)到前邊的最近一個(gè)空格之間的字符.
        在某些設(shè)置下,刪除到第一個(gè)非字母或數(shù)字的字符.
        Ctl-Z 終止前臺(tái)工作.

        空白部分
        分割命令或者是變量.包括空格,tab,空行,或任何它們的組合.
        在一些特殊情況下,空白是不允許的,如變量賦值時(shí),會(huì)引起語法錯(cuò)誤.
        空白行在腳本中沒有效果.
        "$IFS",對(duì)于某些命令輸入的特殊變量分割域,默認(rèn)使用的是空白.
        如果想保留空白,使用引用.

        注意事項(xiàng):
        [1] shell做大括號(hào)的命令擴(kuò)展.但是命令本身需要對(duì)擴(kuò)展的結(jié)果作處理.
        [2] 例外:在pipe中的一個(gè)大括號(hào)中的代碼段可能運(yùn)行在一個(gè)子shell中.
        1 ls | { read firstline; read secondline; }
        2 # 錯(cuò)誤,在打括號(hào)中的代碼段,將運(yùn)行到子shell中.
        3 #+ 所以ls的輸出將不能傳遞到代碼塊中.
        4 echo "First line is $firstline; second line is $secondline" # 不能工作
        5
        6 # Thanks, S.C.
        [3] 換行符也被認(rèn)為是空白.這也解釋了為什么一個(gè)空行也會(huì)被認(rèn)為是空白.



        第4章 變量和參數(shù)的介紹
        ======================

        4.1 變量替換
        ------------
        $ 變量替換操作符
        只有在變量被聲明,賦值,unset或exported或者是在變量代表一個(gè)signal的時(shí)候,
        變量才會(huì)是以本來的面目出現(xiàn)在腳本里.變量在被賦值的時(shí)候,可能需要使用"=",
        read狀態(tài)或者是在循環(huán)的頭部.
        在""中還是會(huì)發(fā)生變量替換,這被叫做部分引用,或叫弱引用.而在''中就不會(huì)發(fā)生變
        量替換,這叫做全引用,也叫強(qiáng)引用.具體見第5章的討論.

        注意:$var與${var}的區(qū)別,不加{},在某些上下文將引起錯(cuò)誤,為了安全,使用2.
        具體見9.3節(jié) 參數(shù)替換.

        Example 4-1. 變量賦值和替換
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 # 變量賦值和替換
        4
        5 a=375
        6 hello=$a
        7
        8 #-------------------------------------------------------------------------
        9 # 強(qiáng)烈注意,在賦值的前后一定不要有空格.
        10 # 如果有空格會(huì)發(fā)生什么?
        11
        12 # 如果"VARIABLE =value",
        13 # ^
        14 #+ 腳本將嘗試運(yùn)行一個(gè)"VARIABLE"的命令,帶著一個(gè)"=value"參數(shù).
        15
        16 # 如果"VARIABLE= value",
        17 # ^
        18 #+ script tries to run "value" command with
        18 #+ 腳本將嘗試運(yùn)行一個(gè)"value"的命令,帶著
        19 #+ the environmental variable "VARIABLE" set to "".
        19 #+ 一個(gè)被賦成""值的環(huán)境變量"VARIABLE".
        20 #-------------------------------------------------------------------------
        21
        22
        23 echo hello # 沒有變量引用,不過是個(gè)hello字符串
        24
        25 echo $hello
        26 echo ${hello} # 同上
        27
        28 echo "$hello"
        29 echo "${hello}"
        30
        31 echo
        32
        33 hello="A B C D"
        34 echo $hello # A B C D
        35 echo "$hello" # A B C D
        36 # 就象你看到的echo $hello 和 echo "$hello" 將給出不同的結(jié)果.
        37 # ^ ^
        38 # Quoting a variable preserves whitespace.
        38 # 引用一個(gè)變量將保留其中的空白,當(dāng)然,如果是變量替換就不會(huì)保留了.
        39
        40 echo
        41
        42 echo '$hello' # $hello
        43 # ^ ^
        44 # 全引用的作用
        45 #+ 將導(dǎo)致"$"變成一個(gè)單獨(dú)的字符.
        46
        47 # 注意兩種引用不同的效果
        48
        49
        50 hello= # 設(shè)置為空值
        51 echo "\$hello (null value) = $hello"
        52 # 注意設(shè)置一個(gè)變量為空,與unset它,不是一回事,雖然看起來一樣
        53 #
        54
        55 # --------------------------------------------------------------
        56
        57 # 可以在同一行上設(shè)置多個(gè)變量.
        58 #+ 要以空白分隔
        59 # 小心,這會(huì)降低可讀性,和可移植性.
        60
        61 var1=21 var2=22 var3=$V3
        62 echo
        63 echo "var1=$var1 var2=$var2 var3=$var3"
        64
        65 # 在老版本的"sh"上,可能會(huì)有問題.
        66
        67 # --------------------------------------------------------------
        68
        69 echo; echo
        70
        71 numbers="one two three"
        72 # ^ ^
        73 other_numbers="1 2 3"
        74 # ^ ^
        75 # 如果變量中有空白,那么引用就必要了.
        76 #
        77 echo "numbers = $numbers"
        78 echo "other_numbers = $other_numbers" # other_numbers = 1 2 3
        79 echo
        80
        81 echo "uninitialized_variable = $uninitialized_variable"
        82 # Uninitialized變量為空值(根本就沒賦值).
        83 uninitialized_variable= # 聲明,但是沒被初始化
        84 #+ 其實(shí)和前邊設(shè)置為空值得作用是一樣的.
        85 echo "uninitialized_variable = $uninitialized_variable"
        86 # 還是一個(gè)空值
        87
        88 uninitialized_variable=23 # 賦值
        89 unset uninitialized_variable # Unset it.
        90 echo "uninitialized_variable = $uninitialized_variable"
        91 # 還是空值
        92 echo
        93
        94 exit 0
        ################################End Script#########################################
        注意: 一個(gè)空值變量,或者是根本就沒聲明的變量,在賦值之前使用它可能會(huì)引起問題.
        但是還是可以用來做算術(shù)運(yùn)算
        ################################Start Script#######################################
        1 echo "$uninitialized" # (blank line)
        2 let "uninitialized += 5" # Add 5 to it.
        3 echo "$uninitialized" # 5
        4
        5 # 結(jié)論:
        6 # 對(duì)于一個(gè)空值變量在做算術(shù)操作的時(shí)候,就好像它的值為0一樣.
        8 # This is undocumented (and probably non-portable) behavior.
        7 # 這并沒被文檔化(可能是不可移植)的行為.
        ################################End Script#########################################
        具體參考 Example 11-21


        4.2 變量賦值
        ------------
        = 賦值操作符(前后都不能有空白)
        不要與-eq混淆,那個(gè)是test,并不是賦值.
        注意,=也可被用來做test操作,這依賴于上下文.

        Example 4-2. 一般的變量賦值
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # "裸體"變量
        3
        4 echo
        5
        6 # 變量什么時(shí)候是"裸體"的,比如前邊少了$的時(shí)候.
        7 # 當(dāng)它被賦值的時(shí)候,而不是被引用的時(shí)候.
        8
        9 # 賦值
        10 a=879
        11 echo "The value of \"a\" is $a."
        12
        13 # 使用let賦值
        14 let a=16+5
        15 echo "The value of \"a\" is now $a."
        16
        17 echo
        18
        19 # 在for循環(huán)中
        20 echo -n "Values of \"a\" in the loop are: "
        21 for a in 7 8 9 11
        22 do
        23 echo -n "$a "
        24 done
        25
        26 echo
        27 echo
        28
        29 # 在read命令狀態(tài)中
        30 echo -n "Enter \"a\" "
        31 read a
        32 echo "The value of \"a\" is now $a."
        33
        34 echo
        35
        36 exit 0
        ################################End Script#########################################

        Example 4-3. 變量賦值,一般的和比較特殊的
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 a=23 # Simple case
        4 echo $a
        5 b=$a
        6 echo $b
        7
        8 # 現(xiàn)在讓我們來點(diǎn)小變化
        9
        10 a=`echo Hello!` # 把echo命令的結(jié)果傳給變量a
        11 echo $a
        12 # 注意,如果在命令擴(kuò)展結(jié)構(gòu)中使用一個(gè)(!)的話,在命令行中將不能工作
        13 #+ 因?yàn)檫@觸發(fā)了Bash的"歷史機(jī)制".
        14 # 但是,在校本里邊使用的話,歷史功能是被關(guān)閉的,所以就能夠正常運(yùn)行.
        15
        16
        17 a=`ls -l` # 把ls -l的結(jié)果給a
        18 echo $a # 別忘了,這么引用的話,ls的結(jié)果中的所有空白部分都沒了(包括換行)
        19 echo
        20 echo "$a" # 這么引用就正常了,保留了空白
        21 # (具體參閱章節(jié)"引用")
        22
        23 exit 0
        ################################End Script#########################################
        使用$(...)機(jī)制進(jìn)行的變量賦值(除去使用``來賦值的另外一種新方法).事實(shí)上這兩種方法都是
        命令替換的一種形式.
        # 來自于/ect/rc.d/rc.local
        R=$(cat /ect/redhat-release)
        arch=$(uname -m)


        4.3 Bash變量是不分類型的
        ------------------------
        不像其他程序語言一樣,Bash并不對(duì)變量區(qū)分"類型".本質(zhì)上,Bash變量都是字符串.
        但是依賴于上下文,Bash也允許比較操作和算術(shù)操作.決定這些的關(guān)鍵因素就是,變量中的值
        是否只有數(shù)字.

        Example 4-4 整型還是string?
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # int-or-string.sh: 整形還是string?
        3
        4 a=2334 # 整型
        5 let "a += 1"
        6 echo "a = $a " # a = 2335
        7 echo # 還是整型
        8
        9
        10 b=${a/23/BB} # 將23替換成BB
        11 # 這將把b變量從整型變?yōu)閟tring
        12 echo "b = $b" # b = BB35
        13 declare -i b # 即使使用declare命令也不會(huì)對(duì)此有任何幫助,9.4節(jié)有解釋
        14 echo "b = $b" # b = BB35
        15
        16 let "b += 1" # BB35 + 1 =
        17 echo "b = $b" # b = 1
        18 echo
        19
        20 c=BB34
        21 echo "c = $c" # c = BB34
        22 d=${c/BB/23} # S將BB替換成23
        23 # 這使得$d變?yōu)橐粋€(gè)整形
        24 echo "d = $d" # d = 2334
        25 let "d += 1" # 2334 + 1 =
        26 echo "d = $d" # d = 2335
        27 echo
        28
        29 # 關(guān)于空變量怎么樣?
        30 e=""
        31 echo "e = $e" # e =
        32 let "e += 1" # 算術(shù)操作允許一個(gè)空變量?
        33 echo "e = $e" # e = 1
        34 echo # 空變量將轉(zhuǎn)換成一個(gè)整型變量
        35
        36 # 關(guān)于未聲明的變量怎么樣?
        37 echo "f = $f" # f =
        38 let "f += 1" # 算術(shù)操作允許么?
        39 echo "f = $f" # f = 1
        40 echo # 未聲明的變量將轉(zhuǎn)換成一個(gè)整型變量
        41
        42
        43
        44 # 所以說Bash中的變量都是無類型的.
        45
        46 exit 0
        ################################End Script#########################################


        4.4 特殊的變量類型
        ------------------
        local variables
        這種變量只有在代碼塊或者是函數(shù)中才可見(具體見23.2和23章)
        environmental variables
        這種變量將改變用戶接口和shell的行為.

        在一般的上下文中,每個(gè)進(jìn)程都有自己的環(huán)境,就是一組保持進(jìn)程可能引用的信息的
        變量.這種情況下,shell于一個(gè)一般進(jìn)程是相同的.

        每次當(dāng)shell啟動(dòng)時(shí),它都將創(chuàng)建自己的環(huán)境變量.更新或者添加新的環(huán)境變量,將導(dǎo)
        致shell更新它的環(huán)境,同時(shí)也會(huì)影響所有繼承自這個(gè)環(huán)境的所有子進(jìn)程(由這個(gè)命令
        導(dǎo)致的).

        注意:分配給環(huán)境變量的空間是受限的.創(chuàng)建太多的環(huán)境變量將引起空間溢出,這會(huì)引
        起問題.
        關(guān)于eval命令,具體見第11章
        bash$ eval "`seq 10000 | sed -e 's/.*/export var&=ZZZZZZZZZZZZZZ/'`"
        bash$ du
        bash: /usr/bin/du: Argument list too long

        如果一個(gè)腳本設(shè)置了環(huán)境變量,需要export它,來通知本腳本的環(huán)境,這是export
        命令的功能,關(guān)于export命令,具體見11章.

        腳本只能對(duì)它產(chǎn)生的子進(jìn)程export變量.一個(gè)從命令行被調(diào)用的腳本export的變量,將
        不能影響調(diào)用這個(gè)腳本的那個(gè)命令行shell的環(huán)境.

        positional parameters
        就是從命令行中傳進(jìn)來的參數(shù),$0, $1, $2, $3...

        $0就是腳本文件的名字,$1是第一個(gè)參數(shù),$2為第2個(gè)...,參見[1](有$0的說明),$9
        以后就需要打括號(hào)了,如${10},${11},${12}...
        兩個(gè)值得注意的變量$*和$@(第9章有具體的描述),表示所有的位置參數(shù).

        Example 4-5 位置參數(shù)
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 # 作為用例,調(diào)用這個(gè)腳本至少需要10個(gè)參數(shù),如
        4 # ./scriptname 1 2 3 4 5 6 7 8 9 10
        5 MINPARAMS=10
        6
        7 echo
        8
        9 echo "The name of this script is \"$0\"."
        10 # 添加./是為了當(dāng)前目錄
        11 echo "The name of this script is \"`basename $0`\"."
        12 # 去掉目錄信息,具體見'basename'命令
        13
        14 echo
        15
        16 if [ -n "$1" ] # 測(cè)試變量被被引用
        17 then
        18 echo "Parameter #1 is $1" # "#"沒被轉(zhuǎn)義
        19 fi
        20
        21 if [ -n "$2" ]
        22 then
        23 echo "Parameter #2 is $2"
        24 fi
        25
        26 if [ -n "$3" ]
        27 then
        28 echo "Parameter #3 is $3"
        29 fi
        30
        31 # ...
        32
        33
        34 if [ -n "${10}" ] # 大于9的參數(shù)必須出現(xiàn)在{}中.
        35 then
        36 echo "Parameter #10 is ${10}"
        37 fi
        38
        39 echo "-----------------------------------"
        40 echo "All the command-line parameters are: "$*""
        41
        42 if [ $# -lt "$MINPARAMS" ] #$#是傳到腳本里的位置參數(shù)的個(gè)數(shù)
        43 then
        44 echo
        45 echo "This script needs at least $MINPARAMS command-line arguments!"
        46 fi
        47
        48 echo
        49
        50 exit 0
        ################################End Script#########################################
        {}標(biāo)記法是一種很好的使用位置參數(shù)的方法.這也需要間接引用(見Example 34-2)
        1 args=$# # 位置參數(shù)的個(gè)數(shù)
        2 lastarg=${!args}
        3 # 或: lastarg=${!#}
        4 # 注意 lastarg=${!$#} 將報(bào)錯(cuò)

        一些腳本可能會(huì)依賴于使用不同的調(diào)用名字,而表現(xiàn)出不同的行為,這樣一般都需要
        判斷$0,而其他的名字都是通過ln命令產(chǎn)生的鏈接.(具體參見Example 12-2)

        如果腳本需要一個(gè)命令行參數(shù),而調(diào)用的時(shí)候,沒用這個(gè)參數(shù),這就有可能造成分配一個(gè)
        空變量,這樣估計(jì)就會(huì)引起問題.一種解決辦法就是在這個(gè)位置參數(shù),和相關(guān)的變量后
        邊,都添加一個(gè)額外的字符.具體見下邊的例子.
        ################################Start Script#######################################
        1 variable1_=$1_ # 而不是 variable1=$1
        2 # 這將阻止一個(gè)錯(cuò)誤,即使在調(diào)用時(shí)沒使用這個(gè)位置參數(shù).
        3
        4 critical_argument01=$variable1_
        5
        6 # 這個(gè)擴(kuò)展的字符是可以被消除掉的,就像這樣.
        7 variable1=${variable1_/_/}
        8 # 副作用就是$variable1_多了一個(gè)下劃線
        9 # 這里使用了一個(gè)參數(shù)替換模版(后邊會(huì)有具體的討論)
        10 # (Leaving out the replacement pattern results in a deletion.)
        10 # (在一個(gè)刪除動(dòng)作中,節(jié)省了一個(gè)替換模式)
        11
        12
        13 # 一個(gè)解決這種問題的更簡單的做法就是,判斷一下這個(gè)位置參數(shù)是否傳遞下來了
        14 if [ -z $1 ]
        15 then
        16 exit $E_MISSING_POS_PARAM
        17 fi
        18
        19
        20 # 但是上邊的方法將可能產(chǎn)生一個(gè)意外的副作用
        21 # 參數(shù)替換的更好的辦法應(yīng)該是:
        22 # ${1:-$DefaultVal}
        23 # 具體察看"Parameter Substition"節(jié)
        24 #+ 在第9章
        ################################End Script#########################################


        Example 4-6 wh,whois節(jié)點(diǎn)名字查詢
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # ex18.sh
        3
        4 # Does a 'whois domain-name' lookup on any of 3 alternate servers:
        5 # ripe.net, cw.net, radb.net
        6
        7 # 把這個(gè)腳本重命名為'wh',然后放到/usr/local/bin下
        8
        9 # 需要3個(gè)符號(hào)鏈接
        10 # ln -s /usr/local/bin/wh /usr/local/bin/wh-ripe
        11 # ln -s /usr/local/bin/wh /usr/local/bin/wh-cw
        12 # ln -s /usr/local/bin/wh /usr/local/bin/wh-radb
        13
        14 E_NOARGS=65
        15
        16
        17 if [ -z "$1" ]
        18 then
        19 echo "Usage: `basename $0` [domain-name]"
        20 exit $E_NOARGS
        21 fi
        22
        23 # Check script name and call proper server.
        23 # 檢查腳本名字,然后調(diào)用合適的服務(wù)器
        24 case `basename $0` in # Or: case ${0##*/} in
        25 "wh" ) whois $1@whois.ripe.net;;
        26 "wh-ripe") whois $1@whois.ripe.net;;
        27 "wh-radb") whois $1@whois.radb.net;;
        28 "wh-cw" ) whois $1@whois.cw.net;;
        29 * ) echo "Usage: `basename $0` [domain-name]";;
        30 esac
        31
        32 exit $?
        ################################End Script#########################################

        shift shift命令重新分配位置參數(shù),其實(shí)就是向左移動(dòng)一個(gè)位置.
        $1 <--- $2, $2 <--- $3, $3 <--- $4, 等等.
        老的$1將消失,但是$0(腳本名)是不會(huì)改變的.如果你使用了大量的位置參數(shù),那么
        shift命令允許你存取超過10個(gè)參數(shù).雖然{}表示法也允許這樣.


        Example 4-7 使用shift
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # 使用'shift'來穿過所有的位置參數(shù).
        3
        4 # 把這個(gè)腳本命名為shft,
        5 #+ 并且使用一些參數(shù)來調(diào)用它,如:
        6 # ./shft a b c def 23 skidoo
        7
        8 until [ -z "$1" ] # 知道所有參數(shù)都用光
        9 do
        10 echo -n "$1 "
        11 shift
        12 done
        13
        14 echo # 額外的換行.
        15
        16 exit 0
        ################################End Script#########################################
        在將參數(shù)傳遞到函數(shù)中時(shí),shift的工作方式也基本差不多.具體見Example 33-15

        注意事項(xiàng):
        [1] 進(jìn)程調(diào)用設(shè)置$0參數(shù)的腳本.一般的,這個(gè)參數(shù)就是腳本名字.具體察看execv的man頁.



        第5章 引用(翻譯的可能有問題,特指引號(hào))
        ======================================
        引號(hào)的特殊效果就是,保護(hù)字符串中的特殊字符不被shell或者是shell腳本重新解釋或者擴(kuò)展.
        (我們這里所說的"特殊"指的是一些字符在shell中具有的特殊意義,比如*)
        如:
        bash$ ls -l [Vv]*
        -rw-rw-r-- 1 bozo bozo 324 Apr 2 15:05 VIEWDATA.BAT
        -rw-rw-r-- 1 bozo bozo 507 May 4 14:25 vartrace.sh
        -rw-rw-r-- 1 bozo bozo 539 Apr 14 17:11 viewdata.sh

        bash$ ls -l '[Vv]*'
        ls: [Vv]*: No such file or directory

        在我們一般的生活中,引號(hào)內(nèi)的內(nèi)容往往有特殊的含義,而在Bash中,當(dāng)我們引用一個(gè)字符串,
        我們是保護(hù)它的字面含義.

        特定的程序和工具能夠重新解釋或擴(kuò)展特殊的字符.引用的一個(gè)重要的作用就是保護(hù)命令行中
        的參數(shù),但還是允許正在調(diào)用的程序來擴(kuò)展它.
        bash$ grep '[Ff]irst' *.txt
        file1.txt:This is the first line of file1.txt.
        file2.txt:This is the First line of file2.txt.

        注意 grep [Ff]irst *.txt在Bash下的行為(其實(shí)就是正則表達(dá)式么),[1]

        引用還可以抑制echo命令的換行作用.

        bash$ echo $(ls -l)
        total 8 -rw-rw-r-- 1 bozo bozo 130 Aug 21 12:57 t222.sh -rw-rw-r-- 1 bozo bozo 78 Aug 21 12:57 t71.sh

        bash$ echo "$(ls -l)"
        total 8
        -rw-rw-r-- 1 bozo bozo 130 Aug 21 12:57 t222.sh
        -rw-rw-r-- 1 bozo bozo 78 Aug 21 12:57 t71.sh


        5.1 引用變量
        ------------
        在一個(gè)雙引號(hào)中直接使用變量名,一般都是沒有問題的.它阻止了所有在引號(hào)中的特殊字符的
        重新解釋--包括變量名[2]--但是$,`和\除外.[3]保留$,作為特殊字符的意義,是為了能夠在雙
        引號(hào)中也能夠正常地引用變量("$var").這樣在""中可以使用變量所表達(dá)的值(Example 4-1).

        使用""來防止單詞分割.[4]如果在參數(shù)列表中使用雙引號(hào),將使得雙引號(hào)中的參數(shù)作為一個(gè)參
        數(shù).即使雙引號(hào)中的字符串包含多個(gè)單詞(也就是包含空白部分),也不會(huì)變?yōu)槎鄠€(gè)參數(shù),如:
        1 variable1="a variable containing five words"
        2 COMMAND This is $variable1 # COMMAND將以7個(gè)參數(shù)來執(zhí)行
        3 # "This" "is" "a" "variable" "containing" "five" "words"
        4
        5 COMMAND "This is $variable1" # COMMAND將以1個(gè)參數(shù)來執(zhí)行
        6 # "This is a variable containing five words"
        7
        8
        9 variable2="" # 空值
        10
        11 COMMAND $variable2 $variable2 $variable2 # COMMAND將不帶參數(shù)執(zhí)行
        12 COMMAND "$variable2" "$variable2" "$variable2" # COMMAND將以3個(gè)空參數(shù)來執(zhí)行
        13 COMMAND "$variable2 $variable2 $variable2" # COMMAND將以1個(gè)參數(shù)來執(zhí)行(2空格)
        用雙引號(hào)把參數(shù)封到echo中是很有必要的,只有在單詞分隔或時(shí)保留空白時(shí)的時(shí)候可能
        有些問題.

        Example 5-1 echo一些詭異的變量
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # weirdvars.sh: echo詭異的變量
        3
        4 var="'(]\\{}\$\""
        5 echo $var # '(]\{}$"
        6 echo "$var" # '(]\{}$" 并沒有什么不同
        7
        8 echo
        9
        10 IFS='\'
        11 echo $var # '(] {}$" \ 轉(zhuǎn)換成空格了?明顯和IFS有關(guān)系么!又不傻!
        12 echo "$var" # '(]\{}$"
        13
        14 exit 0
        ################################End Script#########################################

        單引號(hào)操作總體上和""很像,但不允許引用變量.因?yàn)?的特殊含義被關(guān)閉了.在''中除了',其他
        字符都沒有特殊的含義了.所以單引號(hào)比雙引號(hào)嚴(yán)格.
        因?yàn)榧词故荺,在''中都被關(guān)閉了,所以你想在''中顯示'的含義,將得不到預(yù)期的效果.
        1 echo "Why can't I write 's between single quotes"
        2
        3 echo
        4
        5 # 一種繞彎的方法
        6 echo 'Why can'\''t I write '"'"'s between single quotes'
        7 # |-------| |----------| |-----------------------|
        8 # 包含了2個(gè)單引號(hào)字符,原書好像有錯(cuò)誤

        注意事項(xiàng):
        [1] 除非當(dāng)前目錄下,正好有個(gè)叫first的文件.
        [2] 即使是變量的值也是有副作用的(見下邊)
        [3] 如果在""中包含"!"的話,在命令行中將會(huì)出現(xiàn)錯(cuò)誤.因?yàn)檫@個(gè)"!"被當(dāng)作歷史命令來解釋了.
        在一個(gè)腳本中,這種情況是不會(huì)發(fā)生的,因?yàn)樵谀_本中,Bash歷史記錄被關(guān)閉了.

        下邊是一些關(guān)于"\"一些不協(xié)調(diào)的行為.
        bash$ echo hello\!
        hello!

        bash$ echo "hello\!"
        hello\!

        bash$ echo -e x\ty
        xty

        bash$ echo -e "x\ty"
        x y

        [4] "單詞分隔",在這個(gè)上下文中意味著,將一個(gè)字符串分隔為一些分離的參數(shù).


        5.2 轉(zhuǎn)義(\)
        -----------
        轉(zhuǎn)義是一種引用單個(gè)字符的方法.一個(gè)具有特殊含義的字符前邊放上一個(gè)轉(zhuǎn)義符(\)就告訴shell
        這個(gè)字符失去了特殊的含義.
        值得注意的是,在某些特定的命令和工具中,比如echo和sed,轉(zhuǎn)義符往往會(huì)起到相反的效果,
        它反倒有可能引發(fā)出這個(gè)字符特殊的含義.

        對(duì)于特定的轉(zhuǎn)義符的特殊的含義
        在echo和sed中所使用的
        \n 意味著新的一行
        \r 回車
        \t tab鍵
        \v vertical tab(垂直tab),查前邊的Ctl-K
        \b backspace,查前邊的Ctl-H
        \a "alert"(如beep或flash)
        \0xx 轉(zhuǎn)換成8進(jìn)制ASCII解碼,等價(jià)于oxx

        Example 5-2 轉(zhuǎn)義符
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # escaped.sh: 轉(zhuǎn)義符
        3
        4 echo; echo
        5
        6 echo "\v\v\v\v" # 逐字的打印\v\v\v\v .
        7 # 使用-e選項(xiàng)的echo命令來打印轉(zhuǎn)義符
        8 echo "============="
        9 echo "VERTICAL TABS"
        10 echo -e "\v\v\v\v" # Prints 4 vertical tabs.
        11 echo "=============="
        12
        13 echo "QUOTATION MARK"
        14 echo -e "\042" # 打印" (引號(hào), 8進(jìn)制的ASCII 碼就是42).
        15 echo "=============="
        16
        17 # The $'\X' construct makes the -e option unnecessary.
        17 # 如果使用$'\X'結(jié)構(gòu),那-e選項(xiàng)就不必要了
        18 echo; echo "NEWLINE AND BEEP"
        19 echo $'\n' # 新行.
        20 echo $'\a' # Alert (beep).
        21
        22 echo "==============="
        23 echo "QUOTATION MARKS"
        24 # 版本2以后Bash允許使用$'\nnn'結(jié)構(gòu)
        25 # 注意這種情況,'\nnn\是8進(jìn)制
        26 echo $'\t \042 \t' # Quote (") framed by tabs.
        27
        28 # 當(dāng)然,也可以使用16進(jìn)制的值,使用$'\xhhh' 結(jié)構(gòu)
        29 echo $'\t \x22 \t' # Quote (") framed by tabs.
        30
        31 # 早一點(diǎn)的Bash版本允許'\x022'這種形式
        32 echo "==============="
        33 echo
        34
        35
        36 # 分配ASCII字符到變量中
        37 # ---------------------
        38 quote=$'\042' # \042是",分配到變量中
        39 echo "$quote This is a quoted string, $quote and this lies outside the quotes."
        40
        41 echo
        42
        43 # Concatenating ASCII chars in a variable.
        43 # 變量中的連續(xù)的ASCII char.
        44 triple_underline=$'\137\137\137' # 137 是8進(jìn)制的ASCII 碼'_'.
        45 echo "$triple_underline UNDERLINE $triple_underline"
        46
        47 echo
        48
        49 ABC=$'\101\102\103\010' # 101, 102, 103 是8進(jìn)制的碼A, B, C.
        50 echo $ABC
        51
        52 echo; echo
        53
        54 escape=$'\033' # 033 是8進(jìn)制碼for escape.
        55 echo "\"escape\" echoes as $escape"
        56 #"escape" echoes as 沒有變量被輸出
        57
        58 echo; echo
        59
        60 exit 0
        ################################End Script#########################################
        另一個(gè)關(guān)于$''字符串?dāng)U展結(jié)果的例子見Example 34-1

        \" 表達(dá)引號(hào)本身
        1 echo "Hello" # Hello
        2 echo "\"Hello\", he said." # "Hello", he said.

        \$ $號(hào)本身,跟在\$后的變量名,將不能擴(kuò)展
        1 echo "\$variable01" # 結(jié)果是$variable01

        \\ \號(hào)本身.
        1 echo "\\" # 結(jié)果是\
        2
        3 # 相反的 . . .
        4
        5 echo "\" # 這會(huì)出現(xiàn)第2個(gè)命令提示符,說白了就是提示你命令不全,你再補(bǔ)個(gè)"就
        6 # 好了.如果是在腳本里,就會(huì)給出一個(gè)錯(cuò)誤.

        注意:\的行為依賴于它是否被轉(zhuǎn)義,被"",或者是否在"命令替換"和"here document"中.
        ################################Start Script#######################################
        1 # 簡單的轉(zhuǎn)義和""
        2 echo \z # z
        3 echo \\z # \z
        4 echo '\z' # \z
        5 echo '\\z' # \\z
        6 echo "\z" # \z
        7 echo "\\z" # \z
        8
        9 # 命令替換
        10 echo `echo \z` # z
        11 echo `echo \\z` # z
        12 echo `echo \\\z` # \z
        13 echo `echo \\\\z` # \z
        14 echo `echo \\\\\\z` # \z
        15 echo `echo \\\\\\\z` # \\z
        16 echo `echo "\z"` # \z
        17 echo `echo "\\z"` # \z
        18
        19 # Here document
        20 cat <<EOF
        21 \z
        22 EOF # \z
        23
        24 cat <<EOF
        25 \\z
        26 EOF # \z
        ################################End Script#########################################

        分配給變量的字符串的元素也會(huì)被轉(zhuǎn)義,但是只把一個(gè)轉(zhuǎn)義符分配給變量將會(huì)報(bào)錯(cuò).
        ################################Start Script#######################################
        1 variable=\
        2 echo "$variable"
        3 # Will not work - gives an error message:
        3 # 將不能正常工作- 將給出一個(gè)錯(cuò)誤消息:
        4 # test.sh: : command not found
        5 # 一個(gè)"裸體的" 轉(zhuǎn)義符將不能夠安全的分配給變量.
        6 #
        7 # What actually happens here is that the "\" escapes the newline and
        7 # 這里其實(shí)真正發(fā)生的是variable=\,這句被shell認(rèn)為是沒有完成,\被認(rèn)為是一個(gè)續(xù)行符
        8 #+ 這樣,下邊的這句echo,也被認(rèn)為是上一行的補(bǔ)充.所以,總的來說就是一個(gè)非法變量分配
        9
        10 variable=\
        11 23skidoo
        12 echo "$variable" # 23skidoo
        13 # 這句就可以使用,因?yàn)檫@是一個(gè)合法的變量分配
        14
        15 variable=\
        16 # \^ 轉(zhuǎn)義一個(gè)空格
        17 echo "$variable" # 顯示空格
        18
        19 variable=\\
        20 echo "$variable" # \
        21
        22 variable=\\\
        23 echo "$variable"
        24 # 不能正常工作,給出一個(gè)錯(cuò)誤
        25 # test.sh: \: command not found
        26 #
        27 # 第一個(gè)轉(zhuǎn)義符把第2個(gè)\轉(zhuǎn)義了,但是第3個(gè)又變成"裸體的"了,
        28 #+ 與上邊的例子的原因相同
        29
        30 variable=\\\\
        31 echo "$variable" # \\
        32 # 轉(zhuǎn)了兩個(gè)\
        33 # 沒問題
        ################################End Script#########################################

        轉(zhuǎn)義一個(gè)空格,在命令行參數(shù)列表中將會(huì)阻止單詞分隔問題.
        ################################Start Script#######################################
        1 file_list="/bin/cat /bin/gzip /bin/more /usr/bin/less /usr/bin/emacs-20.7"
        2 # 列出的文件都作為命令的參數(shù).
        3
        4 # Add two files to the list, and list all.
        4 # 加2個(gè)文件到list中,并且列出全部.
        5 ls -l /usr/X11R6/bin/xsetroot /sbin/dump $file_list
        6
        7 echo "-------------------------------------------------------------------------"
        8
        9 # 如果我們轉(zhuǎn)義2個(gè)空格,會(huì)發(fā)生什么?
        10 ls -l /usr/X11R6/bin/xsetroot\ /sbin/dump\ $file_list
        11 # 錯(cuò)誤: 因?yàn)榍?個(gè)路徑名被合并成一個(gè)參數(shù)傳給了'ls -l'
        12 # 因?yàn)?個(gè)轉(zhuǎn)義符阻止了參數(shù)(單詞)分離
        ################################End Script#########################################

        轉(zhuǎn)義符也提供續(xù)行功能.一般,每一行都包含一個(gè)不同的命令,但如果在行尾加上\,那就會(huì)接受
        新行的輸入,作為這一行的補(bǔ)充.
        1 (cd /source/directory && tar cf - . ) | \
        2 (cd /dest/directory && tar xpvf -)
        3 # 重復(fù)了 Alan Cox的目錄樹拷貝命令
        4 # 為了增加可讀性分成2行.
        5
        6 # 也可以使用如下方式:
        7 tar cf - -C /source/directory . |
        8 tar xpvf - -C /dest/directory
        9 # 察看下邊的注意事項(xiàng)

        注意:如果一個(gè)腳本以|(管道字符)結(jié)束.那么一個(gè)\(轉(zhuǎn)義符),就不用非加上不可了.
        但是一個(gè)好的shell腳本編寫風(fēng)格,還是應(yīng)該在行尾加上\,以增加可讀性.
        ################################Start Script#######################################
        1 echo "foo
        2 bar"
        3 #foo
        4 #bar
        5
        6 echo
        7
        8 echo 'foo
        9 bar' # 沒區(qū)別
        10 #foo
        11 #bar
        12
        13 echo
        14
        15 echo foo\
        16 bar # 續(xù)行
        17 #foobar
        18
        19 echo
        20
        21 echo "foo\
        22 bar" # 與上邊一樣,\還是作為續(xù)行符
        23 #foobar
        24
        25 echo
        26
        27 echo 'foo\
        28 bar' # 由于是強(qiáng)引用,所以\沒被解釋成續(xù)行符
        29 #foo\
        30 #bar
        ################################End Script#########################################



        第6章 退出和退出狀態(tài)
        ====================
        exit命令被用來結(jié)束腳本,就像C語言一樣.他也會(huì)返回一個(gè)值來傳給父進(jìn)程,父進(jìn)程會(huì)判斷是否
        可用.

        每個(gè)命令都會(huì)返回一個(gè)exit狀態(tài)(有時(shí)候也叫return狀態(tài)).成功返回0,如果返回一個(gè)非0值,通
        常情況下都會(huì)被認(rèn)為是一個(gè)錯(cuò)誤碼.一個(gè)編寫良好的UNIX命令,程序,和工具都會(huì)返回一個(gè)0作為
        退出碼來表示成功,雖然偶爾也會(huì)有例外.

        同樣的,腳本中的函數(shù)和腳本本身都會(huì)返回退出狀態(tài).在腳本或者是腳本函數(shù)中執(zhí)行的最后的命
        令會(huì)決定退出狀態(tài).在腳本中,exit nnn命令將會(huì)把nnn退出碼傳遞給shell(nnn必須是10進(jìn)制數(shù)
        0-255).

        當(dāng)一個(gè)腳本以不帶參數(shù)exit來結(jié)束時(shí),腳本的退出狀態(tài)就由腳本中最后執(zhí)行命令來決定.
        1 #!/bin/bash
        2
        3 COMMAND_1
        4
        5 . . .
        6
        7 # 將以最后的命令來決定退出狀態(tài)
        8 COMMAND_LAST
        9
        10 exit $?

        1 #!/bin/bash
        2
        3 COMMAND1
        4
        5 . . .
        6
        7 # 將以最后的命令來決定退出狀態(tài)
        8 COMMAND_LAST

        $?讀取最后執(zhí)行命令的退出碼.函數(shù)返回后,$?給出函數(shù)最后執(zhí)行的那條命令的退出碼.這種給
        函數(shù)返回值的方法是Bash的方法.對(duì)于腳本來說也一樣.總之,一般情況下,0為成功,非0失敗W.
        Example 6-1 exit/exit狀態(tài)
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 echo hello
        4 echo $? # 返回0,因?yàn)閳?zhí)行成功
        5
        6 lskdf # 不認(rèn)識(shí)的命令.
        7 echo $? # 返回非0值,因?yàn)槭×?
        8
        9 echo
        10
        11 exit 113 # 將返回113給shell.
        12 # To verify this, type "echo $?" after script terminates.
        12 # 為了驗(yàn)證這個(gè),在腳本結(jié)束的地方使用"echo $?"
        ################################End Script#########################################

        $?對(duì)于測(cè)試腳本中的命令的結(jié)果特別有用(見Example 12-32和Example 12-17).
        注意: !邏輯非操作,將會(huì)反轉(zhuǎn)test命令的結(jié)果,并且這會(huì)影響exit狀態(tài).
        Example 6-2 否定一個(gè)條件使用!
        ################################Start Script#######################################
        1 true # true是shell內(nèi)建命令,什么事都不做,就是shell返回0
        2 echo "exit status of \"true\" = $?" # 0
        3
        4 ! true
        5 echo "exit status of \"! true\" = $?" # 1
        6 # 注意:"!"需要一個(gè)空格
        7 # !true 將導(dǎo)致一個(gè)"command not found"錯(cuò)誤
        8 #
        9 # 如果一個(gè)命令以'!'開頭,那么將使用Bash的歷史機(jī)制.就是顯示這個(gè)命令被使用的歷史.
        10
        11 true
        12 !true
        13 # 這次就沒有錯(cuò)誤了.
        14 # 他不過是重復(fù)了之前的命令(true).
        ################################End Script#########################################

        注意事項(xiàng):
        特定的退出碼都有預(yù)定的含義(見附錄D),用戶不應(yīng)該在自己的腳本中指定他.



        第7章 Tests
        ===========
        每個(gè)完整的合理的編程語言都具有條件判斷的功能.Bash具有test命令,不同的[]和()操作,和
        if/then結(jié)構(gòu).


        7.1 Test結(jié)構(gòu)
        ------------
        一個(gè)if/then結(jié)構(gòu)可以測(cè)試命令的返回值是否為0(因?yàn)?表示成功),如果是的話,執(zhí)行更多命令.

        有一個(gè)專用命令"["(左中括號(hào),特殊字符).這個(gè)命令與test命令等價(jià),但是出于效率上的考慮,
        它是一個(gè)內(nèi)建命令.這個(gè)命令把它的參數(shù)作為比較表達(dá)式或是文件測(cè)試,并且根據(jù)比較的結(jié)果,
        返回一個(gè)退出碼.

        在版本2.02的Bash中,推出了一個(gè)新的[[...]]擴(kuò)展test命令.因?yàn)檫@種表現(xiàn)形式可能對(duì)某些語
        言的程序員來說更加熟悉.注意"[["是一個(gè)關(guān)鍵字,并不是一個(gè)命令.

        Bash把[[ $a -lt $b ]]看作一個(gè)單獨(dú)的元素,并且返回一個(gè)退出碼.

        ((...))和let...結(jié)果也能夠返回一個(gè)退出碼,當(dāng)它們所測(cè)試的算術(shù)表達(dá)式的結(jié)果為非0的時(shí)候,
        他們的退出碼將返回0.這些算術(shù)擴(kuò)展(見第15章)結(jié)構(gòu)被用來做算術(shù)比較.
        1 let "1<2" returns 0 (as "1<2" expands to "1")
        2 (( 0 && 1 )) returns 1 (as "0 && 1" expands to "0")

        if命令可以測(cè)試任何命令,不僅僅是括號(hào)中的條件.
        1 if cmp a b &> /dev/null # 阻止輸出.
        2 then echo "Files a and b are identical."
        3 else echo "Files a and b differ."
        4 fi
        5
        6 # 非常有用的"if-grep" 結(jié)構(gòu):
        7 # ------------------------
        8 if grep -q Bash file
        9 then echo "File contains at least one occurrence of Bash."
        10 fi
        11
        12 word=Linux
        13 letter_sequence=inu
        14 if echo "$word" | grep -q "$letter_sequence"
        15 # "-q"選項(xiàng)是用來阻止輸出
        16 then
        17 echo "$letter_sequence found in $word"
        18 else
        19 echo "$letter_sequence not found in $word"
        20 fi
        21
        22
        23 if COMMAND_WHOSE_EXIT_STATUS_IS_0_UNLESS_ERROR_OCCURRED
        24 then echo "Command succeeded."
        25 else echo "Command failed."
        26 fi

        一個(gè)if/then結(jié)構(gòu)可以包含多級(jí)比較和tests.

        1 if echo "Next *if* is part of the comparison for the first *if*."
        2
        3 if [[ $comparison = "integer" ]]
        4 then (( a < b ))
        5 else
        6 [[ $a < $b ]]
        7 fi
        8
        9 then
        10 echo '$a is less than $b'
        11 fi

        Example 7-1 什么情況下為真?
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 # 技巧:
        4 # 如果你不確定一個(gè)特定的條件如何判斷.
        5 #+ 在一個(gè)if-test結(jié)構(gòu)中測(cè)試它.
        6
        7 echo
        8
        9 echo "Testing \"0\""
        10 if [ 0 ] # zero
        11 then
        12 echo "0 is true."
        13 else
        14 echo "0 is false."
        15 fi # 0 is true.
        16
        17 echo
        18
        19 echo "Testing \"1\""
        20 if [ 1 ] # one
        21 then
        22 echo "1 is true."
        23 else
        24 echo "1 is false."
        25 fi # 1 is true.
        26
        27 echo
        28
        29 echo "Testing \"-1\""
        30 if [ -1 ] # -1
        31 then
        32 echo "-1 is true."
        33 else
        34 echo "-1 is false."
        35 fi # -1 is true.
        36
        37 echo
        38
        39 echo "Testing \"NULL\""
        40 if [ ] # NULL (控狀態(tài))
        41 then
        42 echo "NULL is true."
        43 else
        44 echo "NULL is false."
        45 fi # NULL is false.
        46
        47 echo
        48
        49 echo "Testing \"xyz\""
        50 if [ xyz ] # 字符串
        51 then
        52 echo "Random string is true."
        53 else
        54 echo "Random string is false."
        55 fi # Random string is true.
        56
        57 echo
        58
        59 echo "Testing \"\$xyz\""
        60 if [ $xyz ] # 測(cè)試$xyz是否為null,但是...(明顯沒人定義么!)
        61 # 只不過是一個(gè)未定義的變量
        62 then
        63 echo "Uninitialized variable is true."
        64 else
        65 echo "Uninitialized variable is false."
        66 fi # Uninitialized variable is false.
        67
        68 echo
        69
        70 echo "Testing \"-n \$xyz\""
        71 if [ -n "$xyz" ] # 更學(xué)究的的檢查
        72 then
        73 echo "Uninitialized variable is true."
        74 else
        75 echo "Uninitialized variable is false."
        76 fi # Uninitialized variable is false.
        77
        78 echo
        79
        80
        81 xyz= # 初始化了,但是將其設(shè)為空值
        82
        83 echo "Testing \"-n \$xyz\""
        84 if [ -n "$xyz" ]
        85 then
        86 echo "Null variable is true."
        87 else
        88 echo "Null variable is false."
        89 fi # Null variable is false.
        90
        91
        92 echo
        93
        94
        95 # 什么時(shí)候"flase"為true?
        96
        97 echo "Testing \"false\""
        98 if [ "false" ] # 看起來"false"只不過是個(gè)字符串而已.
        99 then
        100 echo "\"false\" is true." #+ 并且它test的結(jié)果就是true.
        101 else
        102 echo "\"false\" is false."
        103 fi # "false" is true.
        104
        105 echo
        106
        107 echo "Testing \"\$false\"" # 再來一個(gè),未聲明的變量
        108 if [ "$false" ]
        109 then
        110 echo "\"\$false\" is true."
        111 else
        112 echo "\"\$false\" is false."
        113 fi # "$false" is false.
        114 # 現(xiàn)在我們終于得到了期望的結(jié)果
        115
        116 # 如果我們test這個(gè)變量"$true"會(huì)發(fā)生什么結(jié)果?答案是和"$flase"一樣,都為空,因?yàn)槲?br /> 117 #+ 們并沒有定義它.
        118 echo
        119
        120 exit 0
        ################################End Script#########################################
        練習(xí).解釋上邊例子的行為(我想我解釋的已經(jīng)夠清楚了)

        1 if [ condition-true ]
        2 then
        3 command 1
        4 command 2
        5 ...
        6 else
        7 # 可選的(如果不需要可以省去)
        8 # 如果原始的條件測(cè)試結(jié)果是false,那么添加默認(rèn)的代碼來執(zhí)行.
        9 command 3
        10 command 4
        11 ...
        12 fi

        注意:當(dāng)if和then在一個(gè)條件測(cè)試的同一行中的話,必須使用";"來終止if表達(dá)式.if和then都是
        關(guān)鍵字.關(guān)鍵字(或者命令)作為一個(gè)表達(dá)式的開頭,并且在一個(gè)新的表達(dá)式開始之前,必須
        結(jié)束上一個(gè)表達(dá)式.
        1 if [ -x "$filename" ]; then

        Else if和elif

        elif
        elif是else if的縮減形式.
        1 if [ condition1 ]
        2 then
        3 command1
        4 command2
        5 command3
        6 elif [ condition2 ]
        7 # Same as else if
        8 then
        9 command4
        10 command5
        11 else
        12 default-command
        13 fi

        使用if test condition-true這種形式和if[condition-true]這種形式是等價(jià)的.向我們前邊
        所說的"["是test的標(biāo)記.并且以"]"結(jié)束.在if/test中并不應(yīng)該這么嚴(yán)厲,但是新版本的Bash
        需要它.

        注意:test命令是Bash的內(nèi)建命令,用來測(cè)試文件類型和比較字符串.因此,在Bash腳本中,test
        并不調(diào)用/usr/bin/test的二進(jìn)制版本(這是sh-utils工具包的一部分).同樣的,[并不調(diào)用
        /usr/bin/[,被連接到/usr/bin/test.
        bash$ type test
        test is a shell builtin
        bash$ type '['
        [ is a shell builtin
        bash$ type '[['
        [[ is a shell keyword
        bash$ type ']]'
        ]] is a shell keyword
        bash$ type ']'
        bash: type: ]: not found

        Example 7-2 幾個(gè)等效命令test,/usr/bin/test,[],和/usr/bin/[
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 echo
        4
        5 if test -z "$1"
        6 then
        7 echo "No command-line arguments."
        8 else
        9 echo "First command-line argument is $1."
        10 fi
        11
        12 echo
        13
        14 if /usr/bin/test -z "$1" # 與內(nèi)建的test結(jié)果相同
        15 then
        16 echo "No command-line arguments."
        17 else
        18 echo "First command-line argument is $1."
        19 fi
        20
        21 echo
        22
        23 if [ -z "$1" ] # 與上邊代碼的作用相同
        24 # if [ -z "$1" 應(yīng)該工作,但是...
        25 #+ Bash相應(yīng)一個(gè)缺少關(guān)閉中括號(hào)的錯(cuò)誤消息.
        26 then
        27 echo "No command-line arguments."
        28 else
        29 echo "First command-line argument is $1."
        30 fi
        31
        32 echo
        33
        34
        35 if /usr/bin/[ -z "$1" ] # 再來一個(gè),與上邊代碼的作用相同
        36 # if /usr/bin/[ -z "$1" # 工作,但是給個(gè)錯(cuò)誤消息
        37 # # 注意:
        38 # This has been fixed in Bash, version 3.x.
        38 # 在ver 3.x上,這個(gè)bug已經(jīng)被Bash修正了.
        39 then
        40 echo "No command-line arguments."
        41 else
        42 echo "First command-line argument is $1."
        43 fi
        44
        45 echo
        46
        47 exit 0
        ###############################End Script#########################################

        [[]]結(jié)構(gòu)比Bash的[]更加靈活,這是一個(gè)擴(kuò)展的test命令,從ksh88繼承過來的.
        注意:在[[]]結(jié)構(gòu)中,將沒有文件擴(kuò)展或者是單詞分離,但是會(huì)發(fā)生參數(shù)擴(kuò)展和命令替換.
        1 file=/etc/passwd
        2
        3 if [[ -e $file ]]
        4 then
        5 echo "Password file exists."
        6 fi
        注意:使用[[]],而不是[],能夠阻止腳本中的許多邏輯錯(cuò)誤.比如,盡管在[]中將給出一個(gè)錯(cuò)誤,
        但是&&,||,<>操作還是能夠工作在一個(gè)[[]]test之中.
        注意:在if后邊,test命令和[]或[[]]都不是必須的.如下:
        1 dir=/home/bozo
        2
        3 if cd "$dir" 2>/dev/null; then # "2>/dev/null" hides error message.
        4 echo "Now in $dir."
        5 else
        6 echo "Can't change to $dir."
        7 fi
        if命令將返回if后邊的命令的退出碼.

        與此相似,當(dāng)在一個(gè)在使用與或列表結(jié)構(gòu)的時(shí)候,test或中括號(hào)的使用,也并不一定非的有if不可
        1 var1=20
        2 var2=22
        3 [ "$var1" -ne "$var2" ] && echo "$var1 is not equal to $var2"
        4
        5 home=/home/bozo
        6 [ -d "$home" ] || echo "$home directory does not exist."

        (())結(jié)構(gòu)擴(kuò)展并計(jì)算一個(gè)算術(shù)表達(dá)式的結(jié)果.如果表達(dá)式的結(jié)果為0,它將返回1作為退出碼,或
        者是"false".而一個(gè)非0表達(dá)式的結(jié)果將返回0作為退出碼,或者是"true".

        Example 7-3 算數(shù)測(cè)試使用(( ))
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # 算數(shù)測(cè)試
        3
        4 # The (( ... )) construct evaluates and tests numerical expressions.
        4 # (( ... ))結(jié)構(gòu)計(jì)算并測(cè)試算數(shù)表達(dá)式的結(jié)果.
        5 # 退出碼將與[ ... ]結(jié)構(gòu)相反!
        6
        7 (( 0 ))
        8 echo "Exit status of \"(( 0 ))\" is $?." # 1
        9
        10 (( 1 ))
        11 echo "Exit status of \"(( 1 ))\" is $?." # 0
        12
        13 (( 5 > 4 )) # true
        14 echo "Exit status of \"(( 5 > 4 ))\" is $?." # 0
        15
        16 (( 5 > 9 )) # false
        17 echo "Exit status of \"(( 5 > 9 ))\" is $?." # 1
        18
        19 (( 5 - 5 )) # 0
        20 echo "Exit status of \"(( 5 - 5 ))\" is $?." # 1
        21
        22 (( 5 / 4 )) # 除法也行
        23 echo "Exit status of \"(( 5 / 4 ))\" is $?." # 0
        24
        25 (( 1 / 2 )) # 出發(fā)結(jié)果<1
        26 echo "Exit status of \"(( 1 / 2 ))\" is $?." # 結(jié)果將為0
        27 # 1
        28
        29 (( 1 / 0 )) 2>/dev/null # 除數(shù)為0的錯(cuò)誤
        30 # ^^^^^^^^^^^
        31 echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1
        32
        33 # What effect does the "2>/dev/null" have?
        33 # "2>/dev/null"的作用是什么?
        34 # 如果刪除"2>dev/null"將會(huì)發(fā)生什么?
        35 # Try removing it, then rerunning the script.
        35 # 嘗試刪除它,然后再運(yùn)行腳本.
        36
        37 exit 0
        ################################End Script#########################################


        7.2 文件測(cè)試操作
        ----------------
        返回true如果...

        -e 文件存在
        -a 文件存在
        這個(gè)選項(xiàng)的效果與-e相同.但是它已經(jīng)被棄用了,并且不鼓勵(lì)使用
        -f file是一個(gè)regular文件(不是目錄或者設(shè)備文件)
        -s 文件長度不為0
        -d 文件是個(gè)目錄
        -b 文件是個(gè)塊設(shè)備(軟盤,cdrom等等)
        -c 文件是個(gè)字符設(shè)備(鍵盤,modem,聲卡等等)
        -p 文件是個(gè)管道
        -h 文件是個(gè)符號(hào)鏈接
        -L 文件是個(gè)符號(hào)鏈接
        -S 文件是個(gè)socket
        -t 關(guān)聯(lián)到一個(gè)終端設(shè)備的文件描述符
        這個(gè)選項(xiàng)一般都用來檢測(cè)是否在一個(gè)給定腳本中的stdin[-t0]或[-t1]是一個(gè)終端
        -r 文件具有讀權(quán)限(對(duì)于用戶運(yùn)行這個(gè)test)
        -w 文件具有寫權(quán)限(對(duì)于用戶運(yùn)行這個(gè)test)
        -x 文件具有執(zhí)行權(quán)限(對(duì)于用戶運(yùn)行這個(gè)test)
        -g set-group-id(sgid)標(biāo)志到文件或目錄上
        如果一個(gè)目錄具有sgid標(biāo)志,那么一個(gè)被創(chuàng)建在這個(gè)目錄里的文件,這個(gè)目錄屬于創(chuàng)建
        這個(gè)目錄的用戶組,并不一定與創(chuàng)建這個(gè)文件的用戶的組相同.對(duì)于workgroup的目錄
        共享來說,這非常有用.見<>第58頁.
        -u set-user-id(suid)標(biāo)志到文件上
        如果運(yùn)行一個(gè)具有root權(quán)限的文件,那么運(yùn)行進(jìn)程將取得root權(quán)限,即使你是一個(gè)普通
        用戶.[1]這對(duì)于需要存取系統(tǒng)硬件的執(zhí)行操作(比如pppd和cdrecord)非常有用.如果
        沒有suid標(biāo)志的話,那么普通用戶(沒有root權(quán)限)將無法運(yùn)行這種程序.
        見<>第58頁.
        -rwsr-xr-t 1 root 178236 Oct 2 2000 /usr/sbin/pppd
        對(duì)于設(shè)置了suid的文件,在它的權(quán)限標(biāo)志中有"s".
        -k 設(shè)置粘貼位,見<>第65頁.
        對(duì)于"sticky bit",save-text-mode標(biāo)志是一個(gè)文件權(quán)限的特殊類型.如果設(shè)置了這
        個(gè)標(biāo)志,那么這個(gè)文件將被保存在交換區(qū),為了達(dá)到快速存取的目的.如果設(shè)置在目錄
        中,它將限制寫權(quán)限.對(duì)于設(shè)置了sticky bit位的文件或目錄,權(quán)限標(biāo)志中有"t".
        drwxrwxrwt 7 root 1024 May 19 21:26 tmp/
        如果一個(gè)用戶并不時(shí)具有stick bit位的目錄的擁有者,但是具有寫權(quán)限,那么用戶只
        能在這個(gè)目錄下刪除自己所擁有的文件.這將防止用戶在一個(gè)公開的目錄中不慎覆蓋
        或者刪除別人的文件,比如/tmp(當(dāng)然root或者是目錄的所有者可以隨便刪除或重命名
        其中的文件).
        -O 你是文件的所有者.
        -G 文件的group-id和你的相同.
        -N 從文件最后被閱讀到現(xiàn)在,是否被修改.

        f1 -nt f2
        文件f1比f2新
        f1 -ot f2
        f1比f2老
        f1 -ef f2
        f1和f2都硬連接到同一個(gè)文件.

        ! 非--反轉(zhuǎn)上邊測(cè)試的結(jié)果(如果條件缺席,將返回true)

        Example 7-4 test死的鏈接文件
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # broken-link.sh
        3 # Written by Lee bigelow <ligelowbee@yahoo.com>
        4 # Used with permission.
        5
        6 #一個(gè)真正有用的shell腳本來找出死鏈接文件并且輸出它們的引用
        7 #以便于它們可以被輸入到xargs命令中進(jìn)行處理 :)
        8 #比如: broken-link.sh /somedir /someotherdir|xargs rm
        9 #
        10 #這里,不管怎么說,是一種更好的方法
        11 #
        12 #find "somedir" -type l -print0|\
        13 #xargs -r0 file|\
        14 #grep "broken symbolic"|
        15 #sed -e 's/^\|: *broken symbolic.*$/"/g'
        16 #
        17 #但這不是一個(gè)純粹的bash,最起碼現(xiàn)在不是.
        18 #小心:小心/proc文件系統(tǒng)和任何的循環(huán)鏈接文件.
        19 ##############################################################
        20
        21
        22 #如果沒對(duì)這個(gè)腳本傳遞參數(shù),那么就使用當(dāng)前目錄.
        23 #否則就使用傳遞進(jìn)來的參數(shù)作為目錄來搜索.
        24 #
        25 ####################
        26 [ $# -eq 0 ] && directorys=`pwd` || directorys=$@
        27
        28 #建立函數(shù)linkchk來檢查傳進(jìn)來的目錄或文件是否是鏈接和是否存在,
        29 #并且打印出它們的引用
        30 #如果傳進(jìn)來的目錄有子目錄,
        31 #那么把子目錄也發(fā)送到linkchk函數(shù)中處理,就是遞歸目錄.
        32 ##########
        33 linkchk () {
        34 for element in $1/*; do
        35 [ -h "$element" -a ! -e "$element" ] && echo \"$element\"
        36 [ -d "$element" ] && linkchk $element
        37 # Of course, '-h' tests for symbolic link, '-d' for directory.
        37 # 當(dāng)然'-h'是測(cè)試鏈接,'-d'是測(cè)試目錄.
        38 done
        39 }
        40
        41 #如果是個(gè)可用目錄,那就把每個(gè)從腳本傳遞進(jìn)來的參數(shù)都送到linkche函數(shù)中.
        42 #如果不是,那就打印出錯(cuò)誤消息和使用信息.
        43 #
        44 ################
        45 for directory in $directorys; do
        46 if [ -d $directory ]
        47 then linkchk $directory
        48 else
        49 echo "$directory is not a directory"
        50 echo "Usage: $0 dir1 dir2 ..."
        51 fi
        52 done
        53
        54 exit 0
        ################################End Script#########################################
        Example 28-1, Example 10-7, Example 10-3, Example 28-3, 和Example A-1 也會(huì)說明文件
        測(cè)試操作的使用過程.

        注意事項(xiàng):
        [1] 小心suid,可能引起安全漏洞,但是不會(huì)影響shell腳本.
        [2] 在當(dāng)代UNIX系統(tǒng)中,已經(jīng)不使用sticky bit了,只在目錄中使用.


        7.3 其他比較操作
        ----------------
        二元比較操作符,比較變量或者比較數(shù)字.注意數(shù)字與字符串的區(qū)別.

        整數(shù)比較

        -eq 等于,如:if [ "$a" -eq "$b" ]
        -ne 不等于,如:if [ "$a" -ne "$b" ]
        -gt 大于,如:if [ "$a" -gt "$b" ]
        -ge 大于等于,如:if [ "$a" -ge "$b" ]
        -lt 小于,如:if [ "$a" -lt "$b" ]
        -le 小于等于,如:if [ "$a" -le "$b" ]
        < 小于(需要雙括號(hào)),如:(("$a" < "$b"))
        <= 小于等于(需要雙括號(hào)),如:(("$a" <= "$b"))
        > 大于(需要雙括號(hào)),如:(("$a" > "$b"))
        >= 大于等于(需要雙括號(hào)),如:(("$a" >= "$b"))

        字符串比較
        = 等于,如:if [ "$a" = "$b" ]
        == 等于,如:if [ "$a" == "$b" ],與=等價(jià)
        注意:==的功能在[[]]和[]中的行為是不同的,如下:
        1 [[ $a == z* ]] # 如果$a以"z"開頭(模式匹配)那么將為true
        2 [[ $a == "z*" ]] # 如果$a等于z*(字符匹配),那么結(jié)果為true
        3
        4 [ $a == z* ] # File globbing 和word splitting將會(huì)發(fā)生
        5 [ "$a" == "z*" ] # 如果$a等于z*(字符匹配),那么結(jié)果為true
        一點(diǎn)解釋,關(guān)于File globbing是一種關(guān)于文件的速記法,比如"*.c"就是,再如~也是.
        但是file globbing并不是嚴(yán)格的正則表達(dá)式,雖然絕大多數(shù)情況下結(jié)構(gòu)比較像.
        != 不等于,如:if [ "$a" != "$b" ]
        這個(gè)操作符將在[[]]結(jié)構(gòu)中使用模式匹配.
        < 小于,在ASCII字母順序下.如:
        if [[ "$a" < "$b" ]]
        if [ "$a" \< "$b" ]
        注意:在[]結(jié)構(gòu)中"<"需要被轉(zhuǎn)義.
        > 大于,在ASCII字母順序下.如:
        if [[ "$a" > "$b" ]]
        if [ "$a" \> "$b" ]
        注意:在[]結(jié)構(gòu)中">"需要被轉(zhuǎn)義.
        具體參考Example 26-11來查看這個(gè)操作符應(yīng)用的例子.
        -z 字符串為"null".就是長度為0.
        -n 字符串不為"null"
        注意:
        使用-n在[]結(jié)構(gòu)中測(cè)試必須要用""把變量引起來.使用一個(gè)未被""的字符串來使用! -z
        或者就是未用""引用的字符串本身,放到[]結(jié)構(gòu)中(見Example 7-6)雖然一般情況下可
        以工作,但這是不安全的.習(xí)慣于使用""來測(cè)試字符串是一種好習(xí)慣.[1]

        Example 7-5 數(shù)字和字符串比較
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 a=4
        4 b=5
        5
        6 # 這里的變量a和b既可以當(dāng)作整型也可以當(dāng)作是字符串.
        7 # 這里在算術(shù)比較和字符串比較之間有些混淆,
        8 #+ 因?yàn)锽ash變量并不是強(qiáng)類型的.
        9
        10 # Bash允許對(duì)整型變量操作和比較
        11 #+ 當(dāng)然變量中只包含數(shù)字字符.
        12 # 但是還是要考慮清楚再做.
        13
        14 echo
        15
        16 if [ "$a" -ne "$b" ]
        17 then
        18 echo "$a is not equal to $b"
        19 echo "(arithmetic comparison)"
        20 fi
        21
        22 echo
        23
        24 if [ "$a" != "$b" ]
        25 then
        26 echo "$a is not equal to $b."
        27 echo "(string comparison)"
        28 # "4" != "5"
        29 # ASCII 52 != ASCII 53
        30 fi
        31
        32 # 在這個(gè)特定的例子中,"-ne"和"!="都可以.
        33
        34 echo
        35
        36 exit 0
        ################################End Script#########################################

        Example 7-6 測(cè)試字符串是否為null
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # str-test.sh: 測(cè)試null字符串和非引用字符串,
        3 #+ but not strings and sealing wax, not to mention cabbages and kings . . .
        4 #+ 上邊這句沒看懂
        5 # Using if [ ... ]
        6
        7
        8 # 如果一個(gè)字符串沒被初始化,那么它就沒有定義的值(像這種話,總感覺像屁話)
        9 # 這種狀態(tài)叫做"null"(與zero不同)
        10
        11 if [ -n $string1 ] # $string1 沒被聲明和初始化
        12 then
        13 echo "String \"string1\" is not null."
        14 else
        15 echo "String \"string1\" is null."
        16 fi
        17 # 錯(cuò)誤的結(jié)果.
        18 # 顯示$string1為非空,雖然他沒被初始化.
        19
        20
        21 echo
        22
        23
        24 # 讓我們?cè)僭囈幌?
        25
        26 if [ -n "$string1" ] # 這次$string1被引用了.
        27 then
        28 echo "String \"string1\" is not null."
        29 else
        30 echo "String \"string1\" is null."
        31 fi # ""的字符串在[]結(jié)構(gòu)中
        32
        33
        34 echo
        35
        36
        37 if [ $string1 ] # 這次$string1變成"裸體"的了
        38 then
        39 echo "String \"string1\" is not null."
        40 else
        41 echo "String \"string1\" is null."
        42 fi
        43 # 這工作得很好.
        44 # 這個(gè)[]test操作檢測(cè)string是否為null.
        45 # 然而,使用("$string1")是一種很好的習(xí)慣
        46 #
        47 # As Stephane Chazelas points out,
        48 # if [ $string1 ] 有1個(gè)參數(shù) "]"
        49 # if [ "$string1" ] 有2個(gè)參數(shù),空的"$string1"和"]"
        50
        51
        52
        53 echo
        54
        55
        56
        57 string1=initialized
        58
        59 if [ $string1 ] # 再來,$string1"裸體了"
        60 then
        61 echo "String \"string1\" is not null."
        62 else
        63 echo "String \"string1\" is null."
        64 fi
        65 # 再來,給出了正確的結(jié)果.
        66 # 不過怎么說("$string1")還是好很多,因?yàn)? . .
        67
        68
        69 string1="a = b"
        70
        71 if [ $string1 ] # 再來,$string1 再次裸體了.
        72 then
        73 echo "String \"string1\" is not null."
        74 else
        75 echo "String \"string1\" is null."
        76 fi
        77 # 非引用的"$string1"現(xiàn)在給出了一個(gè)錯(cuò)誤的結(jié)果!
        78
        79 exit 0
        80 # Thank you, also, Florian Wisser, for the "heads-up".
        ################################End Script#########################################

        Example 7-7 zmore
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # zmore
        3
        4 #使用'more'來查看gzip文件
        5
        6 NOARGS=65
        7 NOTFOUND=66
        8 NOTGZIP=67
        9
        10 if [ $# -eq 0 ] # 與 if [ -z "$1" ]同樣的效果
        11 # 應(yīng)該是說前邊的那句注釋有問題,$1是可以存在的,比如:zmore "" arg2 arg3
        12 then
        13 echo "Usage: `basename $0` filename" >&2
        14 # 錯(cuò)誤消息到stderr
        15 exit $NOARGS
        16 # 腳本返回65作為退出碼.
        17 fi
        18
        19 filename=$1
        20
        21 if [ ! -f "$filename" ] # 將$filename ""起來,來允許可能的空白
        22 then
        23 echo "File $filename not found!" >&2
        24 # 錯(cuò)誤消息到stderr
        25 exit $NOTFOUND
        26 fi
        27
        28 if [ ${filename##*.} != "gz" ]
        29 # 在變量替換中使用中括號(hào)
        30 then
        31 echo "File $1 is not a gzipped file!"
        32 exit $NOTGZIP
        33 fi
        34
        35 zcat $1 | more
        36
        37 # 使用過濾命令'more'
        38 # 如果你想的話也可使用'less'
        39
        40
        41 exit $? # 腳本將返回pipe的結(jié)果作為退出碼
        42 # 事實(shí)上,不用非的有"exit $?",但是不管怎么說,有了這句,能正規(guī)一些
        43 # 將最后一句命令的執(zhí)行狀態(tài)作為退出碼返回
        ################################End Script#########################################

        混合比較

        -a 邏輯與
        exp1 -a exp2 如果exp1和exp2都為true的話,這個(gè)表達(dá)式將返回true

        -o 邏輯或
        exp1 -o exp2 如果exp1和exp2中有一個(gè)為true的話,那么這個(gè)表達(dá)式就返回true

        這與Bash的比較操作符&&和||很相像.在[[]]中使用它.
        1 [[ condition1 && condition2 ]]
        -o和-a一般都是和test命令或者是[]一起工作.
        1 if [ "$exp1" -a "$exp2" ]

        請(qǐng)參考Example 8-3,Example 26-16和Example A-28來查看混合比較操作的行為.

        注意事項(xiàng):
        [1] S.C.(這家伙是個(gè)人名)指出,在使用混合比較的時(shí)候即使"$var"也可能會(huì)產(chǎn)生問題.
        如果$string為空的話,[ -n "$string" -o "$a" = "$b" ]可能在某些版本的Bash中
        會(huì)有問題.為了附加一個(gè)額外的字符到可能的空變量中的一種安全的辦法是,
        [ "x$string" != x -o "x$a" = "x$b" ](the "x's" cancel out)(沒看懂).
        cancel out是抵消的意思.


        7.4 嵌套的if/then條件test
        -------------------------
        可以使用if/then來進(jìn)行嵌套的條件test.最終的結(jié)果和上邊的使用&&混合比較操作是相同的.
        1 if [ condition1 ]
        2 then
        3 if [ condition2 ]
        4 then
        5 do-something # 這里只有在condition1和condition2都可用的時(shí)候才行.
        6 fi
        7 fi
        具體請(qǐng)查看Example 34-4.


        7.5 檢查你的test知識(shí)
        --------------------
        系統(tǒng)范圍的xinitrc文件可以用來啟動(dòng)X server.這個(gè)文件中包含了相當(dāng)多的if/then test,
        就像下邊的節(jié)選一樣:
        1 if [ -f $HOME/.Xclients ]; then
        2 exec $HOME/.Xclients
        3 elif [ -f /etc/X11/xinit/Xclients ]; then
        4 exec /etc/X11/xinit/Xclients
        5 else
        6 # 故障保險(xiǎn)設(shè)置,雖然我們永遠(yuǎn)都不會(huì)走到這來.
        7 # (我們?cè)赬clients中也提供了相同的機(jī)制)它不會(huì)受傷的.
        8 xclock -geometry 100x100-5+5 &
        9 xterm -geometry 80x50-50+150 &
        10 if [ -f /usr/bin/netscape -a -f /usr/share/doc/HTML/index.html ]; then
        11 netscape /usr/share/doc/HTML/index.html &
        12 fi
        13 fi

        對(duì)上邊的"test"結(jié)構(gòu)進(jìn)行解釋,然后檢查整個(gè)文件,/etc/X11/xinit/xinitrc,并分析if/then
        test結(jié)構(gòu).你可能需要查看一下后邊才能講解到的grep,sed和正則表達(dá)式的知識(shí).



        第8章 操作符和相關(guān)的主題
        ========================

        8.1 操作符
        ----------

        等號(hào)操作符

        變量賦值
        初始化或者修改變量的值
        =
        無論在算術(shù)運(yùn)算還是字符串運(yùn)算中,都是賦值語句.
        1 var=27
        2 category=minerals # No spaces allowed after the "=".

        注意:不要和"="test操作符混淆.
        1 # = as a test operator
        2
        3 if [ "$string1" = "$string2" ]
        4 # if [ "X$string1" = "X$string2" ] is safer,
        5 # to prevent an error message should one of the variables be empty.
        6 # (The prepended "X" characters cancel out.)
        7 then
        8 command
        9 fi

        算術(shù)操作符

        + 加法
        - 減法
        * 乘法
        / 除法
        ** 冪運(yùn)算
        1 # Bash, version 2.02, introduced the "**" exponentiation operator.
        2
        3 let "z=5**3"
        4 echo "z = $z" # z = 125
        % 取模
        bash$ expr 5 % 3
        2

        5/3=1余2
        模運(yùn)算經(jīng)常用在其它的事情中,比如產(chǎn)生特定的范圍的數(shù)字(Example 9-24,
        Example 9-27)和格式化程序的輸出(Example 26-15,Example A-6).它甚至可以用來
        產(chǎn)生質(zhì)數(shù),(Example A-16).事實(shí)上取模運(yùn)算在算術(shù)運(yùn)算中使用的頻率驚人的高.

        Example 8-1 最大公約數(shù)
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # gcd.sh: 最大公約數(shù)
        3 # 使用Euclid's 算法
        4
        5 # 最大公約數(shù),就是2個(gè)數(shù)能夠同時(shí)整除的最大的數(shù).
        6 #
        7
        8 # Euclid's算法采用連續(xù)除法.
        9 # 在每個(gè)循環(huán)中
        10 #+ 被除數(shù) <--- 除數(shù)
        11 #+ 除數(shù) <--- 余數(shù)
        12 #+ 直到余數(shù)= 0.
        13 #+ 在最后的循環(huán)中The gcd = 被除數(shù)
        14 #
        15 # 關(guān)于這個(gè)算法更精彩的討論
        16 # 見Jim Loy's site, http://www.jimloy.com/number/euclids.htm.
        17
        18
        19 # ------------------------------------------------------
        20 # 參數(shù)檢查
        21 ARGS=2
        22 E_BADARGS=65
        23
        24 if [ $# -ne "$ARGS" ]
        25 then
        26 echo "Usage: `basename $0` first-number second-number"
        27 exit $E_BADARGS
        28 fi
        29 # ------------------------------------------------------
        30
        31
        32 gcd ()
        33 {
        34
        35 dividend=$1 # 隨便給值
        36 divisor=$2 #+ 即使$2大,也沒關(guān)系.
        37 # Why not?
        38
        39 remainder=1 # 如果再循環(huán)中使用為初始化的變量.
        40 #+ 那將在第一次循環(huán)中產(chǎn)生一個(gè)錯(cuò)誤消息.
        41
        42
        43 until [ "$remainder" -eq 0 ]
        44 do
        45 let "remainder = $dividend % $divisor"
        46 dividend=$divisor # 現(xiàn)在使用2個(gè)最小的數(shù)重復(fù).
        47 divisor=$remainder
        48 done # Euclid's algorithm
        49
        50 } # Last $dividend is the gcd.
        50 } # 最后的$dividend就是gcd.
        51
        52
        53 gcd $1 $2
        54
        55 echo; echo "GCD of $1 and $2 = $dividend"; echo
        56
        57
        58 # 練習(xí):
        59 # --------
        60 # 檢查命令行參數(shù)來確定它們都是整數(shù),
        61 #+ and exit the script with an appropriate error message if not.
        61 #+ 否則就選擇合適的錯(cuò)誤消息退出.
        62
        63 exit 0
        ################################End Script#########################################

        += 加等于(通過常量增加變量)
        let "var += 5" #var將在本身值的基礎(chǔ)上增加5
        -= 減等于
        *= 乘等于
        let "var *= 4"
        /= 除等于
        %= 取模賦值,算術(shù)操作經(jīng)常使用expr或者let表達(dá)式.

        Example 8-2 使用算術(shù)操作符
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # Counting to 11 in 10 different ways.
        3
        4 n=1; echo -n "$n "
        5
        6 let "n = $n + 1" # let "n = n + 1" 這么寫也行
        7 echo -n "$n "
        8
        9
        10 : $((n = $n + 1))
        11 # ":" 是必須的,這是因?yàn)?如果沒有":"的話,Bash將
        12 #+ 嘗試把"$((n = $n + 1))"解釋成一個(gè)命令
        13 echo -n "$n "
        14
        15 (( n = n + 1 ))
        16 # 對(duì)于上邊的方法的一個(gè)更簡單的選則.
        17 # Thanks, David Lombard, for pointing this out.
        18 echo -n "$n "
        19
        20 n=$(($n + 1))
        21 echo -n "$n "
        22
        23 : $[ n = $n + 1 ]
        24 # ":" 是必須的,這是因?yàn)?如果沒有":"的話,Bash將
        25 #+ 嘗試把"$[ n = $n + 1 ]" 解釋成一個(gè)命令
        26 # 即使"n"被初始化成為一個(gè)字符串,這句也能工作.
        27 echo -n "$n "
        28
        29 n=$[ $n + 1 ]
        30 # 即使"n"被初始化成為一個(gè)字符串,這句也能工作.
        31 #* Avoid this type of construct, since it is obsolete and nonportable.
        31 #* 盡量避免這種類型的結(jié)果,因?yàn)檫@已經(jīng)被廢棄了,并且不具可移植性.
        32 # Thanks, Stephane Chazelas.
        33 echo -n "$n "
        34
        35 # 現(xiàn)在來個(gè)C風(fēng)格的增量操作.
        36 # Thanks, Frank Wang, for pointing this out.
        37
        38 let "n++" # let "++n" also works.
        39 echo -n "$n "
        40
        41 (( n++ )) # (( ++n ) also works.
        42 echo -n "$n "
        43
        44 : $(( n++ )) # : $(( ++n )) also works.
        45 echo -n "$n "
        46
        47 : $[ n++ ] # : $[ ++n ]] also works
        48 echo -n "$n "
        49
        50 echo
        51
        52 exit 0
        ################################End Script#########################################

        注意:在Bash中的整型變量事實(shí)上是32位的,范圍是 -2147483648 到2147483647.如果超過這個(gè)
        范圍進(jìn)行算術(shù)操作,將不會(huì)得到你期望的結(jié)果(就是溢出么).
        1 a=2147483646
        2 echo "a = $a" # a = 2147483646
        3 let "a+=1" # 加1 "a".
        4 echo "a = $a" # a = 2147483647
        5 let "a+=1" # 再加1 "a" ,將超過上限了.
        6 echo "a = $a" # a = -2147483648
        7 # 錯(cuò)誤 (溢出了)
        在Bash 2.05b版本中,Bash支持64位整型了.

        注意:Bash并不能理解浮點(diǎn)運(yùn)算.它把包含的小數(shù)點(diǎn)看作字符串.
        1 a=1.5
        2
        3 let "b = $a + 1.3" # 錯(cuò)誤.
        4 # t2.sh: let: b = 1.5 + 1.3: 表達(dá)式的語義錯(cuò)誤(錯(cuò)誤標(biāo)志為".5 + 1.3")
        5
        6 echo "b = $b" # b=1
        如果真想做浮點(diǎn)運(yùn)算的話,使用bc(見12.8節(jié)),bc可以進(jìn)行浮點(diǎn)運(yùn)算或調(diào)用數(shù)學(xué)庫函數(shù).

        位操作符.
        (暈,有點(diǎn)強(qiáng)大過分了吧,位級(jí)操作都支持.)
        位操作符在shell腳本中極少使用.它們最主要的用途看起來就是操作和test從sockets中
        讀出的變量."Bit flipping"與編譯語言的聯(lián)系很緊密,比如c/c++,在這種語言中它可以
        運(yùn)行得足夠快.(原文有處on the fly,我查了一下,好像是沒事干的意思,沒理解)

        << 左移1位(每次左移都將乘2)

        <<= 左移幾位,=號(hào)后邊將給出左移幾位
        let "var <<= 2"就是左移2位(就是乘4)

        >> 右移1位(每次右移都將除2)

        >>= 右移幾位

        & 按位與

        &= 按位與賦值

        | 按位或

        |= 按位或賦值

        ~ 按位非

        ! 按位否?(沒理解和上邊的~有什么區(qū)別?),感覺是應(yīng)該放到下邊的邏輯操作中

        ^ 按位異或XOR

        ^= 異或賦值


        邏輯操作:

        && 邏輯與
        1 if [ $condition1 ] && [ $condition2 ]
        2 # 與: if [ $condition1 -a $condition2 ] 相同
        3 # 如果condition1和condition2都為true,那結(jié)果就為true.
        4
        5 if [[ $condition1 && $condition2 ]] # 也可以.
        6 # 注意&&不允許出現(xiàn)在[ ... ]中.
        注意:&&也可以用在and list中(見25章),但是使用的時(shí)候需要依賴上下文.

        || 邏輯或
        1 if [ $condition1 ] || [ $condition2 ]
        2 # 與: if [ $condition1 -o $condition2 ] 相同
        3 # 如果condition1或condition2為true,那結(jié)果就為true.
        4
        5 if [[ $condition1 || $condition2 ]] # 也可以
        6 # 注意||不允許出現(xiàn)在[ ... ]中.
        注意:Bash將test每個(gè)連接到邏輯操作的狀態(tài)的退出狀態(tài)(見第6章).


        Example 8-3 使用&&和||進(jìn)行混合狀態(tài)的test
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 a=24
        4 b=47
        5
        6 if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]
        7 then
        8 echo "Test #1 succeeds."
        9 else
        10 echo "Test #1 fails."
        11 fi
        12
        13 # 錯(cuò)誤: if [ "$a" -eq 24 && "$b" -eq 47 ]
        14 #+ 嘗試執(zhí)行' [ "$a" -eq 24 '
        15 #+ 因?yàn)闆]找到']'所以失敗了.
        16 #
        17 # 注意: 如果 [[ $a -eq 24 && $b -eq 24 ]] 能夠工作.
        18 # 那這個(gè)[[]]的test結(jié)構(gòu)就比[]結(jié)構(gòu)更靈活了.
        19 #
        20 # (在17行的"&&"與第6行的"&&"意義不同)
        21 # Thanks, Stephane Chazelas, for pointing this out.
        22
        23
        24 if [ "$a" -eq 98 ] || [ "$b" -eq 47 ]
        25 then
        26 echo "Test #2 succeeds."
        27 else
        28 echo "Test #2 fails."
        29 fi
        30
        31
        32 # -a和-o選項(xiàng)提供了
        33 #+ 一種可選的混合test方法.
        34 # Thanks to Patrick Callahan for pointing this out.
        35
        36
        37 if [ "$a" -eq 24 -a "$b" -eq 47 ]
        38 then
        39 echo "Test #3 succeeds."
        40 else
        41 echo "Test #3 fails."
        42 fi
        43
        44
        45 if [ "$a" -eq 98 -o "$b" -eq 47 ]
        46 then
        47 echo "Test #4 succeeds."
        48 else
        49 echo "Test #4 fails."
        50 fi
        51
        52
        53 a=rhino
        54 b=crocodile
        55 if [ "$a" = rhino ] && [ "$b" = crocodile ]
        56 then
        57 echo "Test #5 succeeds."
        58 else
        59 echo "Test #5 fails."
        60 fi
        61
        62 exit 0
        ################################End Script#########################################
        &&和||操作也能在算術(shù)運(yùn)算的上下文中找到.
        bash$ echo $(( 1 && 2 )) $((3 && 0)) $((4 || 0)) $((0 || 0))
        1 0 1 0

        混雜操作:
        , 逗號(hào)操作符
        逗號(hào)操作符可以連接2個(gè)或多個(gè)算術(shù)運(yùn)算.所有的操作都會(huì)被執(zhí)行,但是只有最后一個(gè)
        操作作為結(jié)果.
        1 let "t1 = ((5 + 3, 7 - 1, 15 - 4))"
        2 echo "t1 = $t1" # t1 = 11
        3
        4 let "t2 = ((a = 9, 15 / 3))" # Set "a" and calculate "t2".
        5 echo "t2 = $t2 a = $a" # t2 = 5 a = 9
        ","主要用在for循環(huán)中,具體見Example 10-12.


        8.2 數(shù)字常量
        ------------
        shell腳本默認(rèn)都是將數(shù)字作為10進(jìn)制數(shù)處理,除非這個(gè)數(shù)字某種特殊的標(biāo)記法或前綴開頭.
        以0開頭就是8進(jìn)制.以0x開頭就是16進(jìn)制數(shù).使用BASE#NUMBER這種形式可以表示其它進(jìn)制
        表示法

        Example 8-4 數(shù)字常量的處理
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # numbers.sh: 數(shù)字常量的幾種不同的表示法
        3
        4 # 10進(jìn)制: 默認(rèn)
        5 let "dec = 32"
        6 echo "decimal number = $dec" # 32
        7 # 一切都很正常
        8
        9
        10 # 8進(jìn)制: 以'0'(零)開頭
        11 let "oct = 032"
        12 echo "octal number = $oct" # 26
        13 # 表達(dá)式的結(jié)果用10進(jìn)制表示.
        14 #
        15
        16 # 16進(jìn)制表示:數(shù)字以'0x'或者'0X'開頭
        17 let "hex = 0x32"
        18 echo "hexadecimal number = $hex" # 50
        19 # 表達(dá)式的結(jié)果用10進(jìn)制表示.
        20
        21 # 其它進(jìn)制: BASE#NUMBER
        22 # BASE between 2 and 64.
        22 # 2到64進(jìn)制都可以.
        23 # NUMBER必須在BASE的范圍內(nèi),具體見下邊.
        24
        25
        26 let "bin = 2#111100111001101"
        27 echo "binary number = $bin" # 31181
        28
        29 let "b32 = 32#77"
        30 echo "base-32 number = $b32" # 231
        31
        32 let "b64 = 64#@_"
        33 echo "base-64 number = $b64" # 4031
        34 # 這種64進(jìn)制的表示法中的每位數(shù)字都必須在64進(jìn)制表示法的限制字符內(nèi).
        35 # 10 個(gè)數(shù)字+ 26 個(gè)小寫字母+ 26 個(gè)大寫字母+ @ + _
        36
        37
        38 echo
        39
        40 echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))
        41 # 1295 170 44822 3375
        42
        43
        44 # 重要的注意事項(xiàng):
        45 # ---------------
        46 # 如果使用的每位數(shù)字超出了這個(gè)進(jìn)制表示法規(guī)定字符的范圍的話,
        47 #+ 將給出一個(gè)錯(cuò)誤消息.
        48
        49 let "bad_oct = 081"
        50 # (部分的) 錯(cuò)誤消息輸出:
        51 # bad_oct = 081: too great for base (error token is "081")
        52 # Octal numbers use only digits in the range 0 - 7.
        53
        54 exit 0 # Thanks, Rich Bartell and Stephane Chazelas, for clarification.
        ################################End Script#########################################



        第三部分 超越基本
        ++++++++++++++++++++


        第9章 變量重游
        ================
        如果變量使用恰當(dāng),將會(huì)增加腳本的能量和靈活性.但是前提是這需要仔細(xì)學(xué)習(xí)變量的細(xì)節(jié)知識(shí).


        9.1 內(nèi)部變量
        ------------
        Builtin variable
        這些內(nèi)建的變量,將影響bash腳本的行為.

        $BASH
        這個(gè)變量將指向Bash的二進(jìn)制執(zhí)行文件的位置.
        bash$ echo $BASH
        /bin/bash

        $BASH_ENV
        這個(gè)環(huán)境變量將指向一個(gè)Bash啟動(dòng)文件,這個(gè)啟動(dòng)文件將在調(diào)用一個(gè)腳本時(shí)被讀取.

        $BASH_SUBSHELL
        這個(gè)變量將提醒subshell的層次,這是一個(gè)在version3才被添加到Bash中的新特性.
        見Example 20-1.

        $BASH_VERSINFO[n]
        記錄Bash安裝信息的一個(gè)6元素的數(shù)組.與下邊的$BASH_VERSION很像,但這個(gè)更加詳細(xì).
        1 # Bash version info:
        2
        3 for n in 0 1 2 3 4 5
        4 do
        5 echo "BASH_VERSINFO[$n] = ${BASH_VERSINFO[$n]}"
        6 done
        7
        8 # BASH_VERSINFO[0] = 3 # 主版本號(hào)
        9 # BASH_VERSINFO[1] = 00 # 次版本號(hào)
        10 # BASH_VERSINFO[2] = 14 # Patch 次數(shù).
        11 # BASH_VERSINFO[3] = 1 # Build version.
        12 # BASH_VERSINFO[4] = release # Release status.
        13 # BASH_VERSINFO[5] = i386-redhat-linux-gnu # Architecture

        $BASH_VERSION
        安裝在系統(tǒng)上的Bash的版本號(hào).
        bash$ echo $BASH_VERSION
        3.00.14(1)-release
        tcsh% echo $BASH_VERSION
        BASH_VERSION: Undefined variable.
        使用這個(gè)變量對(duì)于判斷系統(tǒng)上到底運(yùn)行的是那個(gè)shll來說是一種非常好的辦法.$SHELL
        有時(shí)將不能給出正確的答案.

        $DIRSTACK
        在目錄棧中最上邊的值(將受到pushd和popd的影響).
        這個(gè)內(nèi)建的變量與dirs命令是保持一致的,但是dirs命令將顯示目錄棧的整個(gè)內(nèi)容.

        $EDITOR
        腳本調(diào)用的默認(rèn)編輯器,一般是vi或者是emacs.

        $EUID
        "effective"用戶ID號(hào).
        當(dāng)前用戶被假定的任何id號(hào).可能在su命令中使用.
        注意:$EUID并不一定與$UID相同.

        $FUNCNAME
        當(dāng)前函數(shù)的名字.
        1 xyz23 ()
        2 {
        3 echo "$FUNCNAME now executing." # xyz23 現(xiàn)在正在被執(zhí)行.
        4 }
        5
        6 xyz23
        7
        8 echo "FUNCNAME = $FUNCNAME" # FUNCNAME =
        9 # 出了函數(shù)就變?yōu)镹ull值了.

        $GLOBIGNORE
        一個(gè)文件名的模式匹配列表,如果在file globbing中匹配到的文件包含這個(gè)列表中的
        某個(gè)文件,那么這個(gè)文件將被從匹配到的文件中去掉.

        $GROUPS
        當(dāng)前用戶屬于的組.
        這是一個(gè)當(dāng)前用戶的組id列表(數(shù)組),就像在/etc/passwd中記錄的一樣.
        root# echo $GROUPS
        0

        root# echo ${GROUPS[1]}
        1

        root# echo ${GROUPS[5]}
        6

        $HOME
        用戶的home目錄,一般都是/home/username(見Example 9-14)

        $HOSTNAME
        hostname命令將在一個(gè)init腳本中,在啟動(dòng)的時(shí)候分配一個(gè)系統(tǒng)名字.
        gethostname()函數(shù)將用來設(shè)置這個(gè)$HOSTNAME內(nèi)部變量.(見Example 9-14)

        $HOSTTYPE
        主機(jī)類型
        就像$MACHTYPE,識(shí)別系統(tǒng)的硬件.
        bash$ echo $HOSTTYPE
        i686

        $IFS
        內(nèi)部域分隔符.
        這個(gè)變量用來決定Bash在解釋字符串時(shí)如何識(shí)別域,或者單詞邊界.
        $IFS默認(rèn)為空白(空格,tab,和新行),但可以修改,比如在分析逗號(hào)分隔的數(shù)據(jù)文件時(shí).
        注意:$*使用$IFS中的第一個(gè)字符,具體見Example 5-1.
        bash$ echo $IFS | cat -vte
        $

        bash$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
        w:x:y:o

        注意:$IFS并不像它處理其它字符一樣處理空白.

        Example 9-1 $IFS和空白
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # $IFS 處理空白的方法,與處理其它字符不同.
        3
        4 output_args_one_per_line()
        5 {
        6 for arg
        7 do echo "[$arg]"
        8 done
        9 }
        10
        11 echo; echo "IFS=\" \""
        12 echo "-------"
        13
        14 IFS=" "
        15 var=" a b c "
        16 output_args_one_per_line $var # output_args_one_per_line `echo " a b c "`
        17 #
        18 # [a]
        19 #
        20 # [c]
        21
        22
        23 echo; echo "IFS=:"
        24 echo "-----"
        25
        26 IFS=:
        27 var=":a::b:c:::" # 與上邊的一樣,但是用" "替換了":"
        28 output_args_one_per_line $var
        29 #
        30 # []
        31 # [a]
        32 # []
        33 #
        34 # [c]
        35 # []
        36 # []
        37 # []
        38
        39 # 同樣的事情也會(huì)發(fā)生在awk中的"FS"域分隔符.
        40
        41 # Thank you, Stephane Chazelas.
        42
        43 echo
        44
        45 exit 0
        ################################End Script#########################################
        Example 12-37也是使用$IFS的另一個(gè)啟發(fā)性的例子.

        $IGNOREEOF
        忽略EOF: 告訴shell在log out之前要忽略多少文件結(jié)束符(control-D).

        $LC_COLLATE
        常在.bashrc或/etc/profile中設(shè)置,這個(gè)變量用來在文件名擴(kuò)展和模式匹配校對(duì)順序.
        如果$LC_COLLATE被錯(cuò)誤的設(shè)置,那么將會(huì)在filename globbing中引起錯(cuò)誤的結(jié)果.

        注意:在2.05以后的Bash版本中,filename globbing將不在對(duì)[]中的字符區(qū)分大小寫.
        比如:ls [A-M]* 將即匹配File1.txt也會(huì)匹配file1.txt.為了恢復(fù)[]的習(xí)慣用法,
        設(shè)置$LC_COLLATE的值為c,使用export LC_COLLATE=c 在/etc/profile或者是
        ~/.bashrc中.

        $LC_CTYPE
        這個(gè)內(nèi)部變量用來控制globbing和模式匹配的字符串解釋.

        $LINENO
        這個(gè)變量記錄它所在的shell腳本中它所在行的行號(hào).這個(gè)變量一般用于調(diào)試目的.
        1 # *** BEGIN DEBUG BLOCK ***
        2 last_cmd_arg=$_ # Save it.
        3
        4 echo "At line number $LINENO, variable \"v1\" = $v1"
        5 echo "Last command argument processed = $last_cmd_arg"
        6 # *** END DEBUG BLOCK ***

        $MACHTYPE
        系統(tǒng)類型
        提示系統(tǒng)硬件
        bash$ echo $MACHTYPE
        i686

        $OLDPWD
        老的工作目錄("OLD-print-working-directory",你所在的之前的目錄)

        $OSTYPE
        操作系統(tǒng)類型.
        bash$ echo $OSTYPE
        linux

        $PATH
        指向Bash外部命令所在的位置,一般為/usr/bin,/usr/X11R6/bin,/usr/local/bin等.
        當(dāng)給出一個(gè)命令時(shí),Bash將自動(dòng)對(duì)$PATH中的目錄做一張hash表.$PATH中以":"分隔的
        目錄列表將被存儲(chǔ)在環(huán)境變量中.一般的,系統(tǒng)存儲(chǔ)的$PATH定義在/ect/processed或
        ~/.bashrc中(見Appendix G).

        bash$ echo $PATH
        /bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/sbin:/usr/sbin

        PATH=${PATH}:/opt/bin將把/opt/bin目錄附加到$PATH變量中.在腳本中,這是一個(gè)
        添加目錄到$PATH中的便捷方法.這樣在這個(gè)腳本退出的時(shí)候,$PATH將會(huì)恢復(fù)(因?yàn)檫@個(gè)
        shell是個(gè)子進(jìn)程,像這樣的一個(gè)腳本是不會(huì)將它的父進(jìn)程的環(huán)境變量修改的)

        注意:當(dāng)前的工作目錄"./"一般都在$PATH中被省去.

        $PIPESTATUS
        數(shù)組變量將保存最后一個(gè)運(yùn)行的前臺(tái)管道的退出碼.有趣的是,這個(gè)退出碼和最后一個(gè)命令
        運(yùn)行的退出碼并不一定相同.
        bash$ echo $PIPESTATUS
        0

        bash$ ls -al | bogus_command
        bash: bogus_command: command not found
        bash$ echo $PIPESTATUS
        141

        bash$ ls -al | bogus_command
        bash: bogus_command: command not found
        bash$ echo $?
        127

        $PIPESTATUS數(shù)組的每個(gè)成員都會(huì)保存一個(gè)管道命令的退出碼,$PIPESTATUS[0]保存第
        一個(gè)管道命令的退出碼,$PIPESTATUS[1]保存第2個(gè),以此類推.

        注意:$PIPESTATUS變量在一個(gè)login shell中可能會(huì)包含一個(gè)錯(cuò)誤的0值(3.0以下版本)
        tcsh% bash

        bash$ who | grep nobody | sort
        bash$ echo ${PIPESTATUS
      • }
        0
        包含在腳本中的上邊這行將會(huì)產(chǎn)生一個(gè)期望的輸出0 1 0.

        注意:在某些上下文$PIPESTATUS可能不會(huì)給出正確的結(jié)果.
        bash$ echo $BASH_VERSION
        3.00.14(1)-release

        bash$ $ ls | bogus_command | wc
        bash: bogus_command: command not found
        0 0 0

        bash$ echo ${PIPESTATUS[@]}
        141 127 0

        Chet Ramey把上邊輸出不成確原因歸咎于ls的行為.因?yàn)槿绻裭s的結(jié)果放到管道上,
        并且這個(gè)輸出沒被讀取,那么SIGPIPE將會(huì)kill掉它,并且退出碼變?yōu)?41,而不是我們期
        望的0.這種情況也會(huì)發(fā)生在tr命令中.

        注意:$PIPESTATUS是一個(gè)"volatile"變量.在任何命令插入之前,并且在pipe詢問之后,
        這個(gè)變量需要立即被捕捉.
        bash$ $ ls | bogus_command | wc
        bash: bogus_command: command not found
        0 0 0

        bash$ echo ${PIPESTATUS[@]}
        0 127 0

        bash$ echo ${PIPESTATUS[@]}
        0

        $PPID
        一個(gè)進(jìn)程的$PPID就是它的父進(jìn)程的進(jìn)程id(pid).[1]
        使用pidof命令對(duì)比一下.

        $PROMPT_COMMAND
        這個(gè)變量保存一個(gè)在主提示符($PS1)顯示之前需要執(zhí)行的命令.

        $PS1
        主提示符,具體見命令行上的顯示.

        $PS2
        第2提示符,當(dāng)你需要額外的輸入的時(shí)候?qū)?huì)顯示,默認(rèn)為">".

        $PS3
        第3提示符,在一個(gè)select循環(huán)中顯示(見Example 10-29).

        $PS4
        第4提示符,當(dāng)使用-x選項(xiàng)調(diào)用腳本時(shí),這個(gè)提示符將出現(xiàn)在每行的輸出前邊.
        默認(rèn)為"+".

        $PWD
        工作目錄(你當(dāng)前所在的目錄).
        與pwd內(nèi)建命令作用相同.
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 E_WRONG_DIRECTORY=73
        4
        5 clear # 清屏.
        6
        7 TargetDirectory=/home/bozo/projects/GreatAmericanNovel
        8
        9 cd $TargetDirectory
        10 echo "Deleting stale files in $TargetDirectory."
        11
        12 if [ "$PWD" != "$TargetDirectory" ]
        13 then # 防止偶然刪除錯(cuò)誤的目錄
        14 echo "Wrong directory!"
        15 echo "In $PWD, rather than $TargetDirectory!"
        16 echo "Bailing out!"
        17 exit $E_WRONG_DIRECTORY
        18 fi
        19
        20 rm -rf *
        21 rm .[A-Za-z0-9]* # Delete dotfiles.
        21 rm .[A-Za-z0-9]* # 刪除"."文件(隱含文件).
        22 # rm -f .[^.]* ..?* 為了刪除以多個(gè)"."開頭的文件.
        23 # (shopt -s dotglob; rm -f *) 也行.
        24 # Thanks, S.C. for pointing this out.
        25
        26 # 文件名能夠包含0-255范圍的所有字符,除了"/".
        27 # 刪除以各種詭異字符開頭的文件將作為一個(gè)練習(xí)留給大家.
        28
        29 # 這里預(yù)留給其他的必要操作.
        30
        31 echo
        32 echo "Done."
        33 echo "Old files deleted in $TargetDirectory."
        34 echo
        35
        36
        37 exit 0
        ################################End Script#########################################

        $REPLY
        read命令如果沒有給變量,那么輸入將保存在$REPLY中.在select菜單中也可用,但是只
        提供選擇的變量的項(xiàng)數(shù),而不是變量本身的值.
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # reply.sh
        3
        4 # REPLY是'read'命令結(jié)果保存的默認(rèn)變量.
        5
        6 echo
        7 echo -n "What is your favorite vegetable? "
        8 read
        9
        10 echo "Your favorite vegetable is $REPLY."
        11 # 當(dāng)且僅當(dāng)在沒有變量提供給"read"命令時(shí),
        12 #+ REPLY才保存最后一個(gè)"read"命令讀入的值.
        13
        14 echo
        15 echo -n "What is your favorite fruit? "
        16 read fruit
        17 echo "Your favorite fruit is $fruit."
        18 echo "but..."
        19 echo "Value of \$REPLY is still $REPLY."
        20 # $REPLY還是保存著上一個(gè)read命令的值,
        21 #+ 因?yàn)樽兞?fruit被傳入到了這個(gè)新的"read"命令中.
        22
        23 echo
        24
        25 exit 0
        ################################End Script#########################################

        $SECONDS
        這個(gè)腳本已經(jīng)運(yùn)行的時(shí)間(單位為秒).
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 TIME_LIMIT=10
        4 INTERVAL=1
        5
        6 echo
        7 echo "Hit Control-C to exit before $TIME_LIMIT seconds."
        8 echo
        9
        10 while [ "$SECONDS" -le "$TIME_LIMIT" ]
        11 do
        12 if [ "$SECONDS" -eq 1 ]
        13 then
        14 units=second
        15 else
        16 units=seconds
        17 fi
        18
        19 echo "This script has been running $SECONDS $units."
        20 # 在一臺(tái)比較慢的或者是負(fù)載很大的機(jī)器上,這個(gè)腳本可能會(huì)跳過幾次循環(huán)
        21 #+ 在一個(gè)while循環(huán)中.
        22 sleep $INTERVAL
        23 done
        24
        25 echo -e "\a" # Beep!
        26
        27 exit 0
        ################################End Script#########################################

        $SHELLOPTS
        這個(gè)變量里保存shell允許的選項(xiàng),這個(gè)變量是只讀的.
        bash$ echo $SHELLOPTS
        braceexpand:hashall:histexpand:monitor:history:interactive-comments:emacs

        $SHLVL
        Shell層次,就是shell層疊的層次,如果是命令行那$SHLVL就是1,如果命令行執(zhí)行的腳
        本中,$SHLVL就是2,以此類推.

        $TMOUT
        如果$TMOUT環(huán)境變量被設(shè)置為一個(gè)非零的時(shí)間值,那么在過了這個(gè)指定的時(shí)間之后,
        shell提示符將會(huì)超時(shí),這會(huì)引起一個(gè)logout.

        在2.05b版本的Bash中,已經(jīng)支持在一個(gè)帶有read命令的腳本中使用$TMOUT變量.
        1 # 需要使用Bash v2.05b或者以后的版本上
        2
        3 TMOUT=3 # Prompt times out at three seconds.
        3 TMOUT=3 # 設(shè)置超時(shí)的時(shí)間為3秒
        4
        5 echo "What is your favorite song?"
        6 echo "Quickly now, you only have $TMOUT seconds to answer!"
        7 read song
        8
        9 if [ -z "$song" ]
        10 then
        11 song="(no answer)"
        12 # 默認(rèn)響應(yīng).
        13 fi
        14
        15 echo "Your favorite song is $song."

        這里有一個(gè)更復(fù)雜的方法來在一個(gè)腳本中實(shí)現(xiàn)超時(shí)功能.一種辦法就是建立一個(gè)時(shí)間循
        環(huán),在超時(shí)的時(shí)候通知腳本.不過,這也需要一個(gè)信號(hào)處理機(jī)制,在超時(shí)的時(shí)候來產(chǎn)生中
        斷.
        (參見Example 29-5)

        Example 9-2 時(shí)間輸入
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # timed-input.sh
        3
        4 # TMOUT=3 在新版本的Bash上也能工作.
        5
        6
        7 TIMELIMIT=3 # 在這個(gè)例子上是3秒,也可以設(shè)其他的值.
        8
        9 PrintAnswer()
        10 {
        11 if [ "$answer" = TIMEOUT ]
        12 then
        13 echo $answer
        14 else # 別想混合著兩個(gè)例子.
        15 echo "Your favorite veggie is $answer"
        16 kill $! # kill將不再需要TimerOn函數(shù)運(yùn)行在后臺(tái).
        17 # $! 是運(yùn)行在后臺(tái)的最后一個(gè)工作的PID.
        18 fi
        19
        20 }
        21
        22
        23
        24 TimerOn()
        25 {
        26 sleep $TIMELIMIT && kill -s 14 $$ &
        27 # 等待3秒,然后發(fā)送一個(gè)信號(hào)給腳本.
        28 }
        29
        30 Int14Vector()
        31 {
        32 answer="TIMEOUT"
        33 PrintAnswer
        34 exit 14
        35 }
        36
        37 trap Int14Vector 14 # 為了我們的目的,時(shí)間中斷(14)被破壞了.
        38
        39 echo "What is your favorite vegetable "
        40 TimerOn
        41 read answer
        42 PrintAnswer
        43
        44
        45 # 很明顯的,這是一個(gè)拼湊的實(shí)現(xiàn).
        46 #+ 然而使用"-t"選項(xiàng)來"read"的話,將會(huì)簡化這個(gè)任務(wù).
        47 # 見"t-out.sh",在下邊.
        48
        49 # 如果你需要一個(gè)真正的幽雅的寫法...
        50 #+ 建議你使用c/c++來寫這個(gè)應(yīng)用,
        51 #+ 使用合適的庫來完成這個(gè)任務(wù),比如'alarm'和'setitimer'.
        52
        53 exit 0
        ################################End Script#########################################
        使用stty也是一種選擇.

        Example 9-3 再來一個(gè)時(shí)間輸入
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # timeout.sh
        3
        4 # Stephane Chazelas編寫,
        5 #+ 本書作者進(jìn)行了一些修改.
        6
        7 INTERVAL=5 # timeout間隔
        8
        9 timedout_read() {
        10 timeout=$1
        11 varname=$2
        12 old_tty_settings=`stty -g`
        13 stty -icanon min 0 time ${timeout}0
        14 eval read $varname # 或者就是 read $varname
        15 stty "$old_tty_settings"
        16 # 察看"stty"的man頁.
        17 }
        18
        19 echo; echo -n "What's your name? Quick! "
        20 timedout_read $INTERVAL your_name
        21
        22 # 這種方法可能不是每個(gè)終端類型都可以正常使用的.
        23 # 最大的timeout依賴于具體的終端.
        24 #+ (一般都是25.5秒).
        25
        26 echo
        27
        28 if [ ! -z "$your_name" ] # If name input before timeout...
        29 then
        30 echo "Your name is $your_name."
        31 else
        32 echo "Timed out."
        33 fi
        34
        35 echo
        36
        37 # 這個(gè)腳本的行為可能與"timed-input.sh"有點(diǎn)不同.
        38 # 在每次按鍵的時(shí)候,計(jì)數(shù)器都會(huì)重置.
        39
        40 exit 0
        ################################End Script#########################################
        或許,最簡單的辦法就是使用-t選項(xiàng)來read了.

        Example 9-4 Timed read
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # t-out.sh
        3 # "syngin seven"的一個(gè)很好的提議 (thanks).
        4
        5
        6 TIMELIMIT=4 # 4 seconds
        7
        8 read -t $TIMELIMIT variable <&1
        9 # ^^^
        10 # 在這個(gè)例子中,對(duì)于Bash 1.x和2.x就需要使用"<&1"
        11 # 但對(duì)于Bash 3.x就不需要.
        12
        13 echo
        14
        15 if [ -z "$variable" ] # Is null?
        16 then
        17 echo "Timed out, variable still unset."
        18 else
        19 echo "variable = $variable"
        20 fi
        21
        22 exit 0
        ################################End Script#########################################

        $UID
        用戶ID號(hào).
        當(dāng)前用戶的id號(hào),在/etc/passwd中記錄.
        這個(gè)值不會(huì)因?yàn)橛脩羰褂昧藄u命令而改變.$UID是只讀變量,不容易在命令行或者是腳
        本中被修改,并且和內(nèi)建的id命令很相像.
        Example 9-5 我是root?
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # am-i-root.sh: 我是不是root用戶?
        3
        4 ROOT_UID=0 # Root的$UID是0.
        5
        6 if [ "$UID" -eq "$ROOT_UID" ] # 是否是root用戶,請(qǐng)站出來.
        7 then
        8 echo "You are root."
        9 else
        10 echo "You are just an ordinary user (but mom loves you just the same)."
        11 fi
        12
        13 exit 0
        14
        15
        16 # ============================================================= #
        17 # 下邊的代碼將不被執(zhí)行,因?yàn)槟_本已經(jīng)退出了.
        18
        19 # 檢驗(yàn)是root用戶的一種可選方法:
        20
        21 ROOTUSER_NAME=root
        22
        23 username=`id -nu` # Or... username=`whoami`
        24 if [ "$username" = "$ROOTUSER_NAME" ]
        25 then
        26 echo "Rooty, toot, toot. You are root."
        27 else
        28 echo "You are just a regular fella."
        29 fi
        ################################End Script#########################################
        見例子Example 2-3
        注意:變量$ENV,$LOGNAME,$MAIL,$TERM,$USER,和$USERNAME并不是Bash的內(nèi)建變量.它
        們經(jīng)常被設(shè)置成環(huán)境變量,它們一般都放在Bash的安裝文件中.$SHELL,用戶登錄的
        shell的名字,可能是從/etc/passwd設(shè)置的,也可能是在一個(gè)"init"腳本中設(shè)置的,同樣
        的,它也不是Bash的內(nèi)建變量.
        tcsh% echo $LOGNAME
        bozo
        tcsh% echo $SHELL
        /bin/tcsh
        tcsh% echo $TERM
        rxvt

        bash$ echo $LOGNAME
        bozo
        bash$ echo $SHELL
        /bin/tcsh
        bash$ echo $TERM
        rxvt

        位置參數(shù)
        $0, $1, $2,等等...
        位置參數(shù),從命令行傳遞給腳本,或者是傳遞給函數(shù).或者賦職給一個(gè)變量.
        (具體見Example 4-5和Example 11-15)

        $#
        命令行或者是位置參數(shù)的個(gè)數(shù).(見Example 33-2)

        $*
        所有的位置參數(shù),被作為一個(gè)單詞.
        注意:"$*"必須被""引用.

        $@
        與$*同義,但是每個(gè)參數(shù)都是一個(gè)獨(dú)立的""引用字串,這就意味著參數(shù)被完整地傳遞,
        并沒有被解釋和擴(kuò)展.這也意味著,每個(gè)參數(shù)列表中的每個(gè)參數(shù)都被當(dāng)成一個(gè)獨(dú)立的
        單詞.
        注意:"$@"必須被引用.

        Example 9-6 arglist:通過$*和$@列出所有的參數(shù)
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # arglist.sh
        3 # 多使用幾個(gè)參數(shù)來調(diào)用這個(gè)腳本,比如"one tow three".
        4
        5 E_BADARGS=65
        6
        7 if [ ! -n "$1" ]
        8 then
        9 echo "Usage: `basename $0` argument1 argument2 etc."
        10 exit $E_BADARGS
        11 fi
        12
        13 echo
        14
        15 index=1 # 初始化數(shù)量.
        16
        17 echo "Listing args with \"\$*\":"
        18 for arg in "$*" # 如果"$*"不被""引用,那么將不能正常地工作
        19 do
        20 echo "Arg #$index = $arg"
        21 let "index+=1"
        22 done # $* sees all arguments as single word.
        22 done # $* 認(rèn)為所有的參數(shù)為一個(gè)單詞
        23 echo "Entire arg list seen as single word."
        24
        25 echo
        26
        27 index=1 # 重置數(shù)量.
        28 # 如果你忘了這句會(huì)發(fā)生什么?
        29
        30 echo "Listing args with \"\$@\":"
        31 for arg in "$@"
        32 do
        33 echo "Arg #$index = $arg"
        34 let "index+=1"
        35 done # $@ 認(rèn)為每個(gè)參數(shù)都一個(gè)單獨(dú)的單詞.
        36 echo "Arg list seen as separate words."
        37
        38 echo
        39
        40 index=1 # 重置數(shù)量.
        41
        42 echo "Listing args with \$* (unquoted):"
        43 for arg in $*
        44 do
        45 echo "Arg #$index = $arg"
        46 let "index+=1"
        47 done # 未""引用的$*把參數(shù)作為獨(dú)立的單詞.
        48 echo "Arg list seen as separate words."
        49
        50 exit 0
        ################################End Script#########################################

        在shift命令后邊,$@將保存命令行中剩余的參數(shù),而$1被丟掉了.
        1 #!/bin/bash
        2 # 使用 ./scriptname 1 2 3 4 5 來調(diào)用這個(gè)腳本
        3
        4 echo "$@" # 1 2 3 4 5
        5 shift
        6 echo "$@" # 2 3 4 5
        7 shift
        8 echo "$@" # 3 4 5
        9
        10 # 每個(gè)"shift"都丟棄$1.
        11 # "$@" 將包含剩下的參數(shù).
        $@也作為為工具使用,用來過濾傳給腳本的輸入.
        cat "$@"結(jié)構(gòu)接受從stdin傳來的輸入,也接受從參數(shù)中指定的文件傳來的輸入.
        具體見Example 12-21和Example 12-22.

        注意:$*和$@的參數(shù)有時(shí)會(huì)不一致,發(fā)生令人迷惑的行為,這依賴于$IFS的設(shè)置.

        Example 9-7 不一致的$*和$@行為
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 # "$*"和"$@"的古怪行為,
        4 #+ 依賴于它們是否被""引用.
        5 # 單詞拆分和換行的不一致處理.
        6
        7
        8 set -- "First one" "second" "third:one" "" "Fifth: :one"
        9 # 設(shè)置這個(gè)腳本參數(shù),$1,$2,等等.
        10
        11 echo
        12
        13 echo 'IFS unchanged, using "$*"'
        14 c=0
        15 for i in "$*" # 引用
        16 do echo "$((c+=1)): [$i]" # 這行在下邊的每個(gè)例子中都一樣.
        17 # Echo參數(shù).
        18 done
        19 echo ---
        20
        21 echo 'IFS unchanged, using $*'
        22 c=0
        23 for i in $* # 未引用
        24 do echo "$((c+=1)): [$i]"
        25 done
        26 echo ---
        27
        28 echo 'IFS unchanged, using "$@"'
        29 c=0
        30 for i in "$@"
        31 do echo "$((c+=1)): [$i]"
        32 done
        33 echo ---
        34
        35 echo 'IFS unchanged, using $@'
        36 c=0
        37 for i in $@
        38 do echo "$((c+=1)): [$i]"
        39 done
        40 echo ---
        41
        42 IFS=:
        43 echo 'IFS=":", using "$*"'
        44 c=0
        45 for i in "$*"
        46 do echo "$((c+=1)): [$i]"
        47 done
        48 echo ---
        49
        50 echo 'IFS=":", using $*'
        51 c=0
        52 for i in $*
        53 do echo "$((c+=1)): [$i]"
        54 done
        55 echo ---
        56
        57 var=$*
        58 echo 'IFS=":", using "$var" (var=$*)'
        59 c=0
        60 for i in "$var"
        61 do echo "$((c+=1)): [$i]"
        62 done
        63 echo ---
        64
        65 echo 'IFS=":", using $var (var=$*)'
        66 c=0
        67 for i in $var
        68 do echo "$((c+=1)): [$i]"
        69 done
        70 echo ---
        71
        72 var="$*"
        73 echo 'IFS=":", using $var (var="$*")'
        74 c=0
        75 for i in $var
        76 do echo "$((c+=1)): [$i]"
        77 done
        78 echo ---
        79
        80 echo 'IFS=":", using "$var" (var="$*")'
        81 c=0
        82 for i in "$var"
        83 do echo "$((c+=1)): [$i]"
        84 done
        85 echo ---
        86
        87 echo 'IFS=":", using "$@"'
        88 c=0
        89 for i in "$@"
        90 do echo "$((c+=1)): [$i]"
        91 done
        92 echo ---
        93
        94 echo 'IFS=":", using $@'
        95 c=0
        96 for i in $@
        97 do echo "$((c+=1)): [$i]"
        98 done
        99 echo ---
        100
        101 var=$@
        102 echo 'IFS=":", using $var (var=$@)'
        103 c=0
        104 for i in $var
        105 do echo "$((c+=1)): [$i]"
        106 done
        107 echo ---
        108
        109 echo 'IFS=":", using "$var" (var=$@)'
        110 c=0
        111 for i in "$var"
        112 do echo "$((c+=1)): [$i]"
        113 done
        114 echo ---
        115
        116 var="$@"
        117 echo 'IFS=":", using "$var" (var="$@")'
        118 c=0
        119 for i in "$var"
        120 do echo "$((c+=1)): [$i]"
        121 done
        122 echo ---
        123
        124 echo 'IFS=":", using $var (var="$@")'
        125 c=0
        126 for i in $var
        127 do echo "$((c+=1)): [$i]"
        128 done
        129
        130 echo
        131
        132 # 用ksh或者zsh -y來試試這個(gè)腳本.
        133
        134 exit 0
        135
        136 # This example script by Stephane Chazelas,
        137 # and slightly modified by the document author.
        ################################End Script#########################################
        注意:$@和$*中的參數(shù)只有在""中才會(huì)不同.

        Example 9-8 當(dāng)$IFS為空時(shí)的$*和$@
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 # 如果$IFS被設(shè)置為空時(shí),
        4 #+ 那么"$*" 和"$@" 將不會(huì)象期望那樣echo出位置參數(shù).
        5
        6 mecho () # Echo 位置參數(shù).
        7 {
        8 echo "$1,$2,$3";
        9 }
        10
        11
        12 IFS="" # 設(shè)置為空.
        13 set a b c # 位置參數(shù).
        14
        15 mecho "$*" # abc,,
        16 mecho $* # a,b,c
        17
        18 mecho $@ # a,b,c
        19 mecho "$@" # a,b,c
        20
        21 # 當(dāng)$IFS設(shè)置為空時(shí),$* 和$@ 的行為依賴于
        22 #+ 正在運(yùn)行的Bash或者sh的版本.
        23 # 所以在腳本中使用這種"feature"不是明智的行為.
        24
        25
        26 # Thanks, Stephane Chazelas.
        27
        28 exit 0
        ################################End Script#########################################

        其他的特殊參數(shù)

        $-
        傳遞給腳本的falg(使用set命令).參考Example 11-15.

        注意:這起初是ksh的特征,后來被引進(jìn)到Bash中,但不幸的是,在Bash中它看上去也不
        能可靠的工作.使用它的一個(gè)可能的方法就是讓這個(gè)腳本進(jìn)行自我測(cè)試(查看是否是交
        互的).

        $!
        在后臺(tái)運(yùn)行的最后的工作的PID(進(jìn)程ID).
        1 LOG=$0.log
        2
        3 COMMAND1="sleep 100"
        4
        5 echo "Logging PIDs background commands for script: $0" >> "$LOG"
        6 # 所以它們可以被監(jiān)控,并且在必要的時(shí)候kill掉.
        7 echo >> "$LOG"
        8
        9 # Logging 命令.
        10
        11 echo -n "PID of \"$COMMAND1\": " >> "$LOG"
        12 ${COMMAND1} &
        13 echo $! >> "$LOG"
        14 # PID of "sleep 100": 1506
        15
        16 # Thank you, Jacques Lederer, for suggesting this.


        1 possibly_hanging_job & { sleep ${TIMEOUT}; eval 'kill -9 $!' &> /dev/null; }
        2 # 強(qiáng)制結(jié)束一個(gè)品行不良的程序.
        3 # 很有用,比如在init腳本中.
        4
        5 # Thank you,Sylvain Fourmanoit,for this creative use of the "!" variable.

        $_
        保存之前執(zhí)行的命令的最后一個(gè)參數(shù).

        Example 9-9 下劃線變量
        ################################Start Script#######################################
        1 #!/bin/bash
        2
        3 echo $_ # /bin/bash
        4 # 只是調(diào)用/bin/bash來運(yùn)行這個(gè)腳本.
        5
        6 du >/dev/null # 將沒有命令的輸出
        7 echo $_ # du
        8
        9 ls -al >/dev/null # 沒有命令輸出
        10 echo $_ # -al (最后的參數(shù))
        11
        12 :
        13 echo $_ # :
        ################################End Script#########################################

        $?
        命令,函數(shù)或者腳本本身的退出狀態(tài)(見Example 23-7)

        $$
        腳本自身的進(jìn)程ID.這個(gè)變量經(jīng)常用來構(gòu)造一個(gè)"unique"的臨時(shí)文件名.
        (參考Example A-13,Example 29-6,Example 12-28和Example 11-25).
        這通常比調(diào)用mktemp來得簡單.

        注意事項(xiàng):
        [1] 當(dāng)前運(yùn)行的腳本的PID為$$.
        [2] "argument"和"parameter"這兩個(gè)單詞經(jīng)常不加區(qū)分的使用.在這整本書中,這兩個(gè)
        單詞的意思完全相同.(在翻譯的時(shí)候就未加區(qū)分,統(tǒng)統(tǒng)翻譯成參數(shù))


        9.2 操作字符串
        --------------
        Bash支持超多的字符串操作,操作的種類和數(shù)量令人驚異.但不幸的是,這些工具缺乏集中性.
        一些是參數(shù)替換的子集,但是另一些則屬于UNIX的expr命令.這就導(dǎo)致了命令語法的不一致和
        功能的重疊,當(dāng)然也會(huì)引起混亂.

        字符串長度

        ${#string}
        expr length $string
        expr "$string" : '.*'

        1 stringZ=abcABC123ABCabc
        2
        3 echo ${#stringZ} # 15
        4 echo `expr length $stringZ` # 15
        5 echo `expr "$stringZ" : '.*'` # 15

        Example 9-10 在一個(gè)文本文件的段間插入空行
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # paragraph-space.sh
        3
        4 # 在一個(gè)不空行的文本文件的段間插入空行.
        5 # Usage: $0 <FILENAME
        6
        7 MINLEN=45 # 可能需要修改這個(gè)值.
        8 # 假定行的長度小于$MINLEN指定的長度
        9 #+ $MINLEN中的值用來描述多少個(gè)字符結(jié)束一個(gè)段.
        10
        11 while read line # 對(duì)于需要多行輸入的文件基本都是這個(gè)樣子
        12 do
        13 echo "$line" # 輸出line.
        14
        15 len=${#line}
        16 if [ "$len" -lt "$MINLEN" ]
        17 then echo # 在短行后邊添加一個(gè)空行
        18 fi
        19 done
        20
        21 exit 0
        ################################End Script#########################################

        從字符串開始的位置匹配子串的長度

        expr match "$string" '$substring'
        $substring是一個(gè)正則表達(dá)式

        expr "$string" : '$substring'
        $substring是一個(gè)正則表達(dá)式

        1 stringZ=abcABC123ABCabc
        2 # |------|
        3
        4 echo `expr match "$stringZ" 'abc[A-Z]*.2'` # 8
        5 echo `expr "$stringZ" : 'abc[A-Z]*.2'` # 8

        索引

        expr index $string $substring
        匹配到子串的第一個(gè)字符的位置.

        1 stringZ=abcABC123ABCabc
        2 echo `expr index "$stringZ" C12` # 6
        3 # C position.
        4
        5 echo `expr index "$stringZ" 1c` # 3
        6 # 'c' (in #3 position) matches before '1'.

        在C語言中最近的等價(jià)函數(shù)為strchr().

        提取子串

        ${string:position}
        在string中從位置$position開始提取子串.
        如果$string為"*"或"@",那么將提取從位置$position開始的位置參數(shù),[1]

        ${string:position:length}
        在string中從位置$position開始提取$length長度的子串.

        ################################Start Script#######################################
        1 stringZ=abcABC123ABCabc
        2 # 0123456789.....
        3 # 0-based indexing.
        4
        5 echo ${stringZ:0} # abcABC123ABCabc
        6 echo ${stringZ:1} # bcABC123ABCabc
        7 echo ${stringZ:7} # 23ABCabc
        8
        9 echo ${stringZ:7:3} # 23A
        10 # 3個(gè)字符長度的子串.
        11
        12
        13
        14 # 有沒有可能從字符結(jié)尾開始,反向提取子串?
        15
        16 echo ${stringZ:-4} # abcABC123ABCabc
        17 # 以${parameter:-default}方式,默認(rèn)是提取完整地字符串.
        18 # 然而 . . .
        19
        20 echo ${stringZ:(-4)} # Cabc
        21 echo ${stringZ: -4} # Cabc
        22 # 現(xiàn)在,它可以工作了.
        23 # 使用圓括號(hào)或者添加一個(gè)空格來轉(zhuǎn)義這個(gè)位置參數(shù).
        24
        25 # Thank you, Dan Jacobson, for pointing this out.
        ################################End Script#########################################
        如果$string參數(shù)為"*"或"@",那將最大的提取從$position開始的$length個(gè)位置參數(shù).
        1 echo ${*:2} # Echo出第2個(gè)和后邊所有的位置參數(shù).
        2 echo ${@:2} # 與前邊相同.
        3
        4 echo ${*:2:3} # 從第2個(gè)開始,Echo出后邊3個(gè)位置參數(shù).


        expr substr $string $position $length
        在string中從位置$position開始提取$length長度的子串.
        1 stringZ=abcABC123ABCabc
        2 # 123456789......
        3 # 1-based indexing.
        4
        5 echo `expr substr $stringZ 1 2` # ab
        6 echo `expr substr $stringZ 4 3` # ABC

        expr match "$string" '\($substring\)'
        從$string的開始位置提取$substring,$substring是一個(gè)正則表達(dá)式.

        expr "$string" : '\($substring\)'
        從$string的開始位置提取$substring,$substring是一個(gè)正則表達(dá)式.
        1 stringZ=abcABC123ABCabc
        2 # =======
        3
        4 echo `expr match "$stringZ" '\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1
        5 echo `expr "$stringZ" : '\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1
        6 echo `expr "$stringZ" : '\(.......\)'` # abcABC1
        7 # All of the above forms give an identical result.

        子串削除

        ${string#substring}
        從$string的左邊截掉第一個(gè)匹配的$substring
        ${string##substring}
        從$string的左邊截掉最后一個(gè)個(gè)匹配的$substring

        1 stringZ=abcABC123ABCabc
        2 # |----|
        3 # |----------|
        4
        5 echo ${stringZ#a*C} # 123ABCabc
        6 # 截掉'a'和'C'之間最近的匹配.
        7
        8 echo ${stringZ##a*C} # abc
        9 # 截掉'a'和'C'之間最遠(yuǎn)的匹配.


        ${string%substring}
        從$string的右邊截掉第一個(gè)匹配的$substring
        ${string%%substring}
        從$string的右邊截掉最后一個(gè)匹配的$substring

        1 stringZ=abcABC123ABCabc
        2 # ||
        3 # |------------|
        4
        5 echo ${stringZ%b*c} # abcABC123ABCa
        6 # 從$stringZ的后邊開始截掉'b'和'c'之間的最近的匹配
        7
        8 echo ${stringZ%%b*c} # a
        9 # 從$stringZ的后邊開始截掉'b'和'c'之間的最遠(yuǎn)的匹配

        Example 9-11 利用修改文件名,來轉(zhuǎn)換圖片格式
        ################################Start Script#######################################
        1 #!/bin/bash
        2 # cvt.sh:
        3 # 把一個(gè)目錄下的所有MacPaint格式的圖片文件都轉(zhuǎn)換為"pbm"格式的圖片文件.
        4
        5 # 使用來自"netpbm"包的"macptopbm"程序,
        6 #+ 這個(gè)程序主要是由Brian Henderson(bryanh@giraffe-data.com)來維護(hù)的.
        7 # Netpbm是大多數(shù)Linux發(fā)行版的標(biāo)準(zhǔn)部分.
        8
        9 OPERATION=macptopbm
        10 SUFFIX=pbm # 新的文件名后綴
        11
        12 if [ -n "$1" ]
        13 then
        14 directory=$1 # 如果目錄名作為第1個(gè)參數(shù)給出...
        15 else
        16 directory=

總結(jié)

以上是生活随笔為你收集整理的高级Bash脚本编程指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

欧美 丝袜 自拍 制服 另类 | 蜜桃视频插满18在线观看 | 天天躁夜夜躁狠狠是什么心态 | 99久久精品午夜一区二区 | 欧美成人家庭影院 | 亚洲欧美综合区丁香五月小说 | 亚洲精品国偷拍自产在线观看蜜桃 | 欧美真人作爱免费视频 | 大色综合色综合网站 | 男女爱爱好爽视频免费看 | 高潮毛片无遮挡高清免费 | 日韩欧美中文字幕公布 | 97精品国产97久久久久久免费 | 亚洲日韩乱码中文无码蜜桃臀网站 | 影音先锋中文字幕无码 | 色婷婷综合激情综在线播放 | 国产熟妇高潮叫床视频播放 | 人人爽人人澡人人高潮 | 成人精品天堂一区二区三区 | 国产偷抇久久精品a片69 | 99久久久无码国产精品免费 | 欧美性色19p | 黄网在线观看免费网站 | 久久视频在线观看精品 | 在线成人www免费观看视频 | 4hu四虎永久在线观看 | 妺妺窝人体色www在线小说 | 久久久中文字幕日本无吗 | 女人被男人躁得好爽免费视频 | 玩弄少妇高潮ⅹxxxyw | 老太婆性杂交欧美肥老太 | 亚洲国产精品久久人人爱 | 国产成人精品三级麻豆 | 女人色极品影院 | 国产亚洲精品久久久久久 | 亚洲色欲色欲天天天www | 强伦人妻一区二区三区视频18 | 精品国产精品久久一区免费式 | 久久亚洲精品成人无码 | 国产片av国语在线观看 | 久久久国产一区二区三区 | 青青青爽视频在线观看 | 久久久久亚洲精品男人的天堂 | 福利一区二区三区视频在线观看 | 无码人妻精品一区二区三区下载 | 国产真实乱对白精彩久久 | 国产乱人偷精品人妻a片 | 色一情一乱一伦一视频免费看 | 十八禁真人啪啪免费网站 | 久久精品视频在线看15 | 女高中生第一次破苞av | 色欲人妻aaaaaaa无码 | 无码人妻少妇伦在线电影 | 亚洲熟妇色xxxxx欧美老妇 | 国产激情一区二区三区 | 久久久久亚洲精品中文字幕 | 一本久久a久久精品vr综合 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 国产精品99爱免费视频 | 98国产精品综合一区二区三区 | 强奷人妻日本中文字幕 | 国产精品高潮呻吟av久久4虎 | 激情亚洲一区国产精品 | 亚洲综合久久一区二区 | 色婷婷综合中文久久一本 | 台湾无码一区二区 | 亚洲中文字幕在线观看 | 一本无码人妻在中文字幕免费 | 蜜臀av无码人妻精品 | 精品欧美一区二区三区久久久 | 天海翼激烈高潮到腰振不止 | 欧美自拍另类欧美综合图片区 | 一本久久伊人热热精品中文字幕 | 一本久久a久久精品vr综合 | 国产精品内射视频免费 | 国产成人无码午夜视频在线观看 | 精品欧美一区二区三区久久久 | 激情国产av做激情国产爱 | 伊在人天堂亚洲香蕉精品区 | 国产av无码专区亚洲a∨毛片 | 最近中文2019字幕第二页 | 精品久久8x国产免费观看 | 日本大香伊一区二区三区 | 久久综合色之久久综合 | 亚洲毛片av日韩av无码 | 国产suv精品一区二区五 | 好爽又高潮了毛片免费下载 | 日本一区二区三区免费高清 | 色偷偷人人澡人人爽人人模 | 一区二区三区乱码在线 | 欧洲 | 蜜桃无码一区二区三区 | 国产三级久久久精品麻豆三级 | 丰满诱人的人妻3 | 少妇性l交大片欧洲热妇乱xxx | 一二三四社区在线中文视频 | 国产午夜无码视频在线观看 | а√资源新版在线天堂 | 国产香蕉尹人视频在线 | 久久精品无码一区二区三区 | 精品久久久中文字幕人妻 | 国产精品无码久久av | 精品国产乱码久久久久乱码 | 精品国产精品久久一区免费式 | 青青草原综合久久大伊人精品 | 久久亚洲日韩精品一区二区三区 | 国产成人精品一区二区在线小狼 | 丰满少妇高潮惨叫视频 | 中文字幕亚洲情99在线 | 日日摸日日碰夜夜爽av | 亚洲精品国产a久久久久久 | 日日噜噜噜噜夜夜爽亚洲精品 | 未满成年国产在线观看 | 日日碰狠狠丁香久燥 | 无码吃奶揉捏奶头高潮视频 | 亚洲日韩中文字幕在线播放 | 熟妇激情内射com | 亚洲精品一区二区三区在线观看 | 性色欲网站人妻丰满中文久久不卡 | 欧美人与物videos另类 | 色综合天天综合狠狠爱 | 图片小说视频一区二区 | 精品aⅴ一区二区三区 | 天海翼激烈高潮到腰振不止 | 兔费看少妇性l交大片免费 | 天堂亚洲免费视频 | 亚洲啪av永久无码精品放毛片 | 成在人线av无码免费 | 波多野结衣 黑人 | 久久无码专区国产精品s | 国产精品国产自线拍免费软件 | 国产成人无码av片在线观看不卡 | 色偷偷人人澡人人爽人人模 | 成人毛片一区二区 | 377p欧洲日本亚洲大胆 | 97无码免费人妻超级碰碰夜夜 | 成人免费视频一区二区 | 久久人人爽人人爽人人片ⅴ | 99精品无人区乱码1区2区3区 | 亚洲日韩av片在线观看 | 免费男性肉肉影院 | 亚洲熟女一区二区三区 | 少妇性l交大片欧洲热妇乱xxx | 国产综合久久久久鬼色 | 欧美喷潮久久久xxxxx | 国产莉萝无码av在线播放 | 亚洲中文无码av永久不收费 | 日日碰狠狠躁久久躁蜜桃 | 精品成在人线av无码免费看 | 红桃av一区二区三区在线无码av | 久久久久久a亚洲欧洲av冫 | 国产精品久久久av久久久 | 无码av最新清无码专区吞精 | 亚洲精品中文字幕久久久久 | 在线观看欧美一区二区三区 | 日本精品少妇一区二区三区 | 一本久久a久久精品vr综合 | 国语精品一区二区三区 | 亚洲精品欧美二区三区中文字幕 | 亚洲人成无码网www | 欧美国产日产一区二区 | 国精产品一区二区三区 | 亚洲爆乳大丰满无码专区 | 久久国产劲爆∧v内射 | 狂野欧美性猛xxxx乱大交 | 300部国产真实乱 | 最新国产麻豆aⅴ精品无码 | 在线欧美精品一区二区三区 | 性欧美疯狂xxxxbbbb | 国产av剧情md精品麻豆 | 国产精品人人爽人人做我的可爱 | 2020久久香蕉国产线看观看 | 黑人粗大猛烈进出高潮视频 | 国产麻豆精品一区二区三区v视界 | 国产精品99久久精品爆乳 | 少女韩国电视剧在线观看完整 | 99久久久国产精品无码免费 | 国产综合在线观看 | 日韩精品无码一区二区中文字幕 | 奇米影视7777久久精品人人爽 | 99久久精品午夜一区二区 | 夜夜影院未满十八勿进 | 国产热a欧美热a在线视频 | 日本精品高清一区二区 | 久久综合激激的五月天 | 动漫av网站免费观看 | 成人欧美一区二区三区黑人 | 亚洲の无码国产の无码影院 | 国产精品美女久久久网av | 亚洲一区二区三区 | 人人妻人人澡人人爽人人精品浪潮 | 中文字幕日产无线码一区 | 天堂久久天堂av色综合 | 精品国产青草久久久久福利 | 男女性色大片免费网站 | 天堂亚洲2017在线观看 | 扒开双腿吃奶呻吟做受视频 | 自拍偷自拍亚洲精品被多人伦好爽 | 人妻熟女一区 | 成人影院yy111111在线观看 | 狠狠色丁香久久婷婷综合五月 | 粗大的内捧猛烈进出视频 | 欧美阿v高清资源不卡在线播放 | 久久久久久亚洲精品a片成人 | 妺妺窝人体色www在线小说 | 久久亚洲中文字幕无码 | 黑人大群体交免费视频 | 少妇厨房愉情理9仑片视频 | 国产69精品久久久久app下载 | 亚洲熟妇自偷自拍另类 | 国产一区二区三区日韩精品 | 狠狠色丁香久久婷婷综合五月 | 无码av中文字幕免费放 | 澳门永久av免费网站 | 波多野结衣乳巨码无在线观看 | 荫蒂被男人添的好舒服爽免费视频 | 青青青爽视频在线观看 | www国产精品内射老师 | 中文无码成人免费视频在线观看 | 精品 日韩 国产 欧美 视频 | 国产成人精品视频ⅴa片软件竹菊 | 日本大乳高潮视频在线观看 | 久久久久久九九精品久 | 亚欧洲精品在线视频免费观看 | 国产精品久久福利网站 | 久久久久久九九精品久 | 国产精品久久国产精品99 | 精品无人区无码乱码毛片国产 | 日本精品人妻无码免费大全 | 又粗又大又硬又长又爽 | 国产人成高清在线视频99最全资源 | 无码吃奶揉捏奶头高潮视频 | 人人妻人人澡人人爽欧美一区 | 国产亚av手机在线观看 | 久久精品成人欧美大片 | 国产一区二区三区四区五区加勒比 | 熟妇激情内射com | 国产熟妇另类久久久久 | 四虎永久在线精品免费网址 | 无码av中文字幕免费放 | 欧美激情内射喷水高潮 | 欧美精品免费观看二区 | 亚洲男人av天堂午夜在 | 狠狠色欧美亚洲狠狠色www | 国产熟女一区二区三区四区五区 | 成人无码影片精品久久久 | 日本www一道久久久免费榴莲 | 亚洲精品无码国产 | 无码吃奶揉捏奶头高潮视频 | 成人免费视频在线观看 | 人人妻人人藻人人爽欧美一区 | 波多野结衣av一区二区全免费观看 | 亚洲第一网站男人都懂 | 强开小婷嫩苞又嫩又紧视频 | 在教室伦流澡到高潮hnp视频 | 99久久婷婷国产综合精品青草免费 | 精品久久综合1区2区3区激情 | 荫蒂添的好舒服视频囗交 | 国产亚洲精品精品国产亚洲综合 | 思思久久99热只有频精品66 | 中文字幕乱妇无码av在线 | 日本又色又爽又黄的a片18禁 | 成熟妇人a片免费看网站 | 2020久久香蕉国产线看观看 | 午夜熟女插插xx免费视频 | 亚洲小说图区综合在线 | 亚洲综合无码一区二区三区 | 亚洲欧美精品aaaaaa片 | 国产成人无码一二三区视频 | 亚洲成a人片在线观看日本 | 国产凸凹视频一区二区 | 亚洲区小说区激情区图片区 | 午夜福利一区二区三区在线观看 | 欧美性猛交内射兽交老熟妇 | 欧美精品在线观看 | 中文字幕人妻无码一区二区三区 | 国产综合在线观看 | 无码午夜成人1000部免费视频 | 亚洲日本va中文字幕 | 激情人妻另类人妻伦 | 中文字幕日产无线码一区 | 蜜臀aⅴ国产精品久久久国产老师 | 亚洲精品www久久久 | 久久伊人色av天堂九九小黄鸭 | 天堂在线观看www | 无码国产激情在线观看 | 内射爽无广熟女亚洲 | 3d动漫精品啪啪一区二区中 | 给我免费的视频在线观看 | 久久久久久国产精品无码下载 | 成人无码精品1区2区3区免费看 | 欧美亚洲国产一区二区三区 | 欧美 日韩 人妻 高清 中文 | 性欧美牲交xxxxx视频 | 国产莉萝无码av在线播放 | 精品国精品国产自在久国产87 | 欧美人与物videos另类 | 久久国产精品_国产精品 | 国产香蕉尹人视频在线 | 人妻天天爽夜夜爽一区二区 | 亚洲综合无码一区二区三区 | 无码任你躁久久久久久久 | 久久成人a毛片免费观看网站 | 高潮喷水的毛片 | 天天爽夜夜爽夜夜爽 | 天下第一社区视频www日本 | 欧美色就是色 | 熟妇人妻激情偷爽文 | 少妇人妻偷人精品无码视频 | 色狠狠av一区二区三区 | 婷婷丁香五月天综合东京热 | 亚洲中文字幕va福利 | 国产精品欧美成人 | 黄网在线观看免费网站 | 国产精品久久久久无码av色戒 | 久久久久99精品成人片 | 5858s亚洲色大成网站www | 婷婷五月综合缴情在线视频 | 国产精品高潮呻吟av久久4虎 | 精品偷拍一区二区三区在线看 | 丰满人妻精品国产99aⅴ | 成人片黄网站色大片免费观看 | 东京热男人av天堂 | 夜精品a片一区二区三区无码白浆 | a片免费视频在线观看 | 又大又硬又爽免费视频 | 3d动漫精品啪啪一区二区中 | 国产精品亚洲а∨无码播放麻豆 | 欧美成人免费全部网站 | 欧美三级a做爰在线观看 | 国产sm调教视频在线观看 | 无码成人精品区在线观看 | 99精品久久毛片a片 | 久久久久成人片免费观看蜜芽 | 成熟人妻av无码专区 | 欧美怡红院免费全部视频 | 国产xxx69麻豆国语对白 | 国产精品自产拍在线观看 | 永久免费精品精品永久-夜色 | 成人精品一区二区三区中文字幕 | 国产麻豆精品一区二区三区v视界 | 粉嫩少妇内射浓精videos | 扒开双腿吃奶呻吟做受视频 | 四虎国产精品免费久久 | 国产97人人超碰caoprom | 无码一区二区三区在线观看 | 色 综合 欧美 亚洲 国产 | 美女极度色诱视频国产 | 国产绳艺sm调教室论坛 | 又黄又爽又色的视频 | 两性色午夜免费视频 | 老子影院午夜精品无码 | 国产两女互慰高潮视频在线观看 | 任你躁国产自任一区二区三区 | 51国偷自产一区二区三区 | 欧美人与禽zoz0性伦交 | 国产麻豆精品一区二区三区v视界 | 国产精品久久久久久久9999 | 人妻互换免费中文字幕 | 亚洲中文字幕无码中文字在线 | 九九久久精品国产免费看小说 | 久久人人97超碰a片精品 | 东京一本一道一二三区 | 国产综合在线观看 | 荫蒂被男人添的好舒服爽免费视频 | 天堂а√在线地址中文在线 | 色欲av亚洲一区无码少妇 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 免费国产黄网站在线观看 | 樱花草在线社区www | 丝袜美腿亚洲一区二区 | 国产午夜精品一区二区三区嫩草 | 亚洲七七久久桃花影院 | 亚洲 高清 成人 动漫 | 奇米影视7777久久精品人人爽 | 亚洲精品成人福利网站 | 狠狠色色综合网站 | 亚洲日韩乱码中文无码蜜桃臀网站 | 久久人妻内射无码一区三区 | 欧美黑人巨大xxxxx | 少妇无码av无码专区在线观看 | 在线欧美精品一区二区三区 | 狠狠综合久久久久综合网 | 55夜色66夜色国产精品视频 | 亚洲国产一区二区三区在线观看 | 美女黄网站人色视频免费国产 | 77777熟女视频在线观看 а天堂中文在线官网 | 午夜精品一区二区三区的区别 | 国产办公室秘书无码精品99 | 好屌草这里只有精品 | 欧美日韩人成综合在线播放 | 婷婷丁香六月激情综合啪 | 女人被爽到呻吟gif动态图视看 | 久久精品中文字幕一区 | 中文无码精品a∨在线观看不卡 | 国产精品沙发午睡系列 | 永久免费精品精品永久-夜色 | 欧美三级不卡在线观看 | 亚洲综合色区中文字幕 | 国产莉萝无码av在线播放 | 强开小婷嫩苞又嫩又紧视频 | 国产午夜亚洲精品不卡 | 欧美阿v高清资源不卡在线播放 | 国产精品亚洲а∨无码播放麻豆 | 久久久久人妻一区精品色欧美 | 扒开双腿吃奶呻吟做受视频 | 亚洲欧美国产精品专区久久 | 99久久无码一区人妻 | 色欲久久久天天天综合网精品 | а√资源新版在线天堂 | 久久亚洲中文字幕无码 | 亚洲精品中文字幕久久久久 | 男女性色大片免费网站 | 性欧美videos高清精品 | 午夜熟女插插xx免费视频 | 亚洲国产精品一区二区第一页 | 天天躁日日躁狠狠躁免费麻豆 | 夜夜躁日日躁狠狠久久av | 亚洲国产高清在线观看视频 | 无码人妻出轨黑人中文字幕 | 亚洲精品综合一区二区三区在线 | 午夜免费福利小电影 | 伊人久久大香线蕉午夜 | 午夜精品一区二区三区在线观看 | 免费人成在线视频无码 | 高潮毛片无遮挡高清免费视频 | 国产香蕉尹人综合在线观看 | 精品无码成人片一区二区98 | 熟女俱乐部五十路六十路av | 国产香蕉尹人视频在线 | 日韩人妻无码一区二区三区久久99 | 成人毛片一区二区 | 国产一区二区三区影院 | 国产乱人伦av在线无码 | 欧洲欧美人成视频在线 | 在线精品国产一区二区三区 | 久久99精品久久久久久动态图 | 少妇人妻偷人精品无码视频 | 国产婷婷色一区二区三区在线 | 国产精品毛多多水多 | 亚洲中文字幕无码一久久区 | 精品无码成人片一区二区98 | 天天拍夜夜添久久精品大 | 久久精品成人欧美大片 | 国产乱码精品一品二品 | www国产精品内射老师 | 熟妇人妻无乱码中文字幕 | 大乳丰满人妻中文字幕日本 | 成人av无码一区二区三区 | 300部国产真实乱 | 无码人妻av免费一区二区三区 | 在线 国产 欧美 亚洲 天堂 | 色综合久久久无码网中文 | 性欧美牲交xxxxx视频 | 55夜色66夜色国产精品视频 | 国产午夜手机精彩视频 | 黑人巨大精品欧美一区二区 | 荫蒂添的好舒服视频囗交 | 国产成人精品视频ⅴa片软件竹菊 | 日本大乳高潮视频在线观看 | 国产精品第一区揄拍无码 | а√资源新版在线天堂 | 免费无码一区二区三区蜜桃大 | 亚洲第一网站男人都懂 | 国产又爽又猛又粗的视频a片 | av小次郎收藏 | 动漫av网站免费观看 | 夫妻免费无码v看片 | 久久久久久久女国产乱让韩 | 久久人人爽人人爽人人片ⅴ | 国内精品一区二区三区不卡 | 日韩精品久久久肉伦网站 | 无码人妻精品一区二区三区不卡 | 中文字幕人成乱码熟女app | 精品一区二区不卡无码av | 国产亚洲人成在线播放 | 77777熟女视频在线观看 а天堂中文在线官网 | 欧美激情一区二区三区成人 | 欧美 日韩 人妻 高清 中文 | 欧洲精品码一区二区三区免费看 | 人人妻人人澡人人爽欧美一区 | 99麻豆久久久国产精品免费 | 精品国产成人一区二区三区 | 性开放的女人aaa片 | 任你躁国产自任一区二区三区 | 99精品国产综合久久久久五月天 | 日本爽爽爽爽爽爽在线观看免 | 在线观看国产一区二区三区 | 久久精品国产大片免费观看 | 国产两女互慰高潮视频在线观看 | 国内少妇偷人精品视频 | 强开小婷嫩苞又嫩又紧视频 | 狠狠综合久久久久综合网 | 国产午夜精品一区二区三区嫩草 | 色妞www精品免费视频 | 综合激情五月综合激情五月激情1 | 未满小14洗澡无码视频网站 | 国产亚洲美女精品久久久2020 | 少妇性俱乐部纵欲狂欢电影 | 图片区 小说区 区 亚洲五月 | 亚洲精品国产品国语在线观看 | 国产精品亚洲一区二区三区喷水 | 男女作爱免费网站 | 国产一区二区不卡老阿姨 | 中文字幕无码av波多野吉衣 | 99久久婷婷国产综合精品青草免费 | 亚洲热妇无码av在线播放 | 欧美刺激性大交 | 欧美猛少妇色xxxxx | 国产精品爱久久久久久久 | 国产深夜福利视频在线 | 黑人巨大精品欧美黑寡妇 | 夜夜躁日日躁狠狠久久av | 无码免费一区二区三区 | 日本熟妇乱子伦xxxx | 高清无码午夜福利视频 | 日韩av无码中文无码电影 | 久久综合九色综合97网 | 国产色xx群视频射精 | 精品久久久久久人妻无码中文字幕 | 国产真人无遮挡作爱免费视频 | 国产婷婷色一区二区三区在线 | 无码一区二区三区在线 | 熟女少妇人妻中文字幕 | 色五月五月丁香亚洲综合网 | 国产在线一区二区三区四区五区 | 99riav国产精品视频 | 大屁股大乳丰满人妻 | 久久精品中文字幕大胸 | 亚洲欧美国产精品专区久久 | 日本精品少妇一区二区三区 | 三级4级全黄60分钟 | 久久午夜无码鲁丝片午夜精品 | 18禁黄网站男男禁片免费观看 | 理论片87福利理论电影 | 鲁鲁鲁爽爽爽在线视频观看 | 乱人伦人妻中文字幕无码 | 乌克兰少妇xxxx做受 | 精品国产av色一区二区深夜久久 | 国产精品久久久久无码av色戒 | 日韩成人一区二区三区在线观看 | 四虎影视成人永久免费观看视频 | 帮老师解开蕾丝奶罩吸乳网站 | 久久精品国产日本波多野结衣 | 国产麻豆精品精东影业av网站 | 最近中文2019字幕第二页 | 日韩精品久久久肉伦网站 | 国产精品第一国产精品 | 亚洲欧洲日本无在线码 | 妺妺窝人体色www婷婷 | 色噜噜亚洲男人的天堂 | 国产精品内射视频免费 | 黑人巨大精品欧美黑寡妇 | 日韩精品无码免费一区二区三区 | 国产又爽又黄又刺激的视频 | 无码一区二区三区在线观看 | 麻豆国产丝袜白领秘书在线观看 | 午夜福利不卡在线视频 | 波多野结衣av在线观看 | 撕开奶罩揉吮奶头视频 | 久久精品人人做人人综合试看 | 国产精品va在线观看无码 | 在线播放免费人成毛片乱码 | 欧美成人家庭影院 | 久久久久久a亚洲欧洲av冫 | 欧美日韩视频无码一区二区三 | 蜜桃臀无码内射一区二区三区 | 国产成人精品无码播放 | 大色综合色综合网站 | 丰满诱人的人妻3 | 免费无码的av片在线观看 | 久久人妻内射无码一区三区 | 性生交大片免费看l | 精品国产精品久久一区免费式 | 男人和女人高潮免费网站 | 国产人成高清在线视频99最全资源 | 久久国产精品精品国产色婷婷 | 高潮毛片无遮挡高清免费视频 | 国产午夜福利亚洲第一 | 2020久久超碰国产精品最新 | 国产av无码专区亚洲a∨毛片 | 国产免费观看黄av片 | 国产真实乱对白精彩久久 | 国内精品九九久久久精品 | av香港经典三级级 在线 | 樱花草在线播放免费中文 | 日本肉体xxxx裸交 | 久久久久se色偷偷亚洲精品av | 天堂亚洲2017在线观看 | 亚洲国产欧美日韩精品一区二区三区 | 日韩精品乱码av一区二区 | 亚洲精品www久久久 | 天堂一区人妻无码 | 蜜臀aⅴ国产精品久久久国产老师 | 扒开双腿疯狂进出爽爽爽视频 | 国产精品久久久久久亚洲影视内衣 | 成年美女黄网站色大免费全看 | 综合人妻久久一区二区精品 | 日韩精品无码免费一区二区三区 | 亚洲欧美综合区丁香五月小说 | 欧美阿v高清资源不卡在线播放 | 久久精品国产精品国产精品污 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国内精品久久久久久中文字幕 | 国产激情一区二区三区 | 国产精品久久久久久久9999 | 日本一卡2卡3卡四卡精品网站 | 色综合久久中文娱乐网 | 亚洲va中文字幕无码久久不卡 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 久精品国产欧美亚洲色aⅴ大片 | 熟妇女人妻丰满少妇中文字幕 | 亚洲成av人影院在线观看 | 色欲人妻aaaaaaa无码 | 日日橹狠狠爱欧美视频 | 成年美女黄网站色大免费视频 | 一区二区传媒有限公司 | 国产亚洲人成a在线v网站 | 午夜精品一区二区三区在线观看 | 丰腴饱满的极品熟妇 | 国内精品久久久久久中文字幕 | 骚片av蜜桃精品一区 | 国产无遮挡又黄又爽又色 | 国模大胆一区二区三区 | 中文字幕人妻无码一夲道 | 一本久道久久综合狠狠爱 | 老熟女乱子伦 | 一本大道久久东京热无码av | 国产成人无码av一区二区 | 国产午夜福利100集发布 | 日本一卡2卡3卡四卡精品网站 | 国产深夜福利视频在线 | 国产无遮挡吃胸膜奶免费看 | 国产suv精品一区二区五 | 大胆欧美熟妇xx | 精品国产一区av天美传媒 | 欧美成人家庭影院 | 永久免费精品精品永久-夜色 | 欧美 日韩 亚洲 在线 | 中文字幕人妻无码一夲道 | 丰满妇女强制高潮18xxxx | 激情爆乳一区二区三区 | 亚洲色欲久久久综合网东京热 | 精品熟女少妇av免费观看 | 国产午夜视频在线观看 | 色综合久久久无码中文字幕 | 国产免费观看黄av片 | 对白脏话肉麻粗话av | 东京热无码av男人的天堂 | 内射爽无广熟女亚洲 | 中文字幕无码热在线视频 | 午夜时刻免费入口 | 国产9 9在线 | 中文 | 日韩少妇白浆无码系列 | 国产极品美女高潮无套在线观看 | 欧美猛少妇色xxxxx | 波多野结衣一区二区三区av免费 | 国产精品毛片一区二区 | 性欧美videos高清精品 | 久久精品成人欧美大片 | 亚洲成熟女人毛毛耸耸多 | 动漫av一区二区在线观看 | 国产97色在线 | 免 | 亚洲欧美日韩国产精品一区二区 | 日日躁夜夜躁狠狠躁 | 国产乱码精品一品二品 | 亚洲码国产精品高潮在线 | 亚洲色在线无码国产精品不卡 | 亚无码乱人伦一区二区 | 亚洲国产av美女网站 | 久久国产精品二国产精品 | 无码人妻出轨黑人中文字幕 | 中文字幕中文有码在线 | 国内少妇偷人精品视频免费 | 久热国产vs视频在线观看 | 亚洲成av人片在线观看无码不卡 | 亚洲精品国产品国语在线观看 | 东北女人啪啪对白 | 欧美 日韩 人妻 高清 中文 | 好男人www社区 | 亚洲成a人片在线观看日本 | 极品嫩模高潮叫床 | 国产精品99爱免费视频 | 国产在线一区二区三区四区五区 | 婷婷丁香六月激情综合啪 | 98国产精品综合一区二区三区 | 中文字幕亚洲情99在线 | 久久精品国产一区二区三区肥胖 | 精品亚洲成av人在线观看 | 日本精品人妻无码77777 天堂一区人妻无码 | 男女爱爱好爽视频免费看 | 久久99久久99精品中文字幕 | 中文字幕av无码一区二区三区电影 | 成人影院yy111111在线观看 | 天天拍夜夜添久久精品大 | 久久无码中文字幕免费影院蜜桃 | 水蜜桃av无码 | 亚洲乱码国产乱码精品精 | 中文字幕日韩精品一区二区三区 | 国产精品丝袜黑色高跟鞋 | 日本免费一区二区三区最新 | 国产麻豆精品一区二区三区v视界 | 国産精品久久久久久久 | 亚洲欧洲日本综合aⅴ在线 | 色婷婷av一区二区三区之红樱桃 | 亚洲精品综合一区二区三区在线 | 人妻aⅴ无码一区二区三区 | 窝窝午夜理论片影院 | 久久久久免费精品国产 | 东京热一精品无码av | 免费无码肉片在线观看 | 国产激情无码一区二区app | 久久99精品国产.久久久久 | 久久精品人人做人人综合试看 | 亚洲中文字幕乱码av波多ji | 国产精品第一区揄拍无码 | 欧美日韩人成综合在线播放 | 国产xxx69麻豆国语对白 | 任你躁国产自任一区二区三区 | 久久综合九色综合欧美狠狠 | 好爽又高潮了毛片免费下载 | 高清不卡一区二区三区 | 亚洲人成网站色7799 | 一本大道伊人av久久综合 | 亚洲一区二区三区 | 一本久久伊人热热精品中文字幕 | 国产va免费精品观看 | 精品国产乱码久久久久乱码 | 亚洲综合色区中文字幕 | 99re在线播放 | 无码中文字幕色专区 | 日本精品人妻无码免费大全 | 国内精品久久久久久中文字幕 | a在线观看免费网站大全 | 一区二区三区乱码在线 | 欧洲 | 人人妻人人澡人人爽欧美精品 | 久久精品丝袜高跟鞋 | 色诱久久久久综合网ywww | 国产成人精品视频ⅴa片软件竹菊 | 女人被爽到呻吟gif动态图视看 | 日日摸日日碰夜夜爽av | 亚洲色大成网站www | 国产超级va在线观看视频 | 欧美成人免费全部网站 | 成人性做爰aaa片免费看不忠 | 久久国产自偷自偷免费一区调 | 老头边吃奶边弄进去呻吟 | 在线欧美精品一区二区三区 | 日本饥渴人妻欲求不满 | 性欧美videos高清精品 | 色欲综合久久中文字幕网 | 日韩欧美中文字幕公布 | 在线亚洲高清揄拍自拍一品区 | 亚洲一区二区三区在线观看网站 | 蜜臀av无码人妻精品 | 亚洲乱码国产乱码精品精 | 亚洲自偷自偷在线制服 | 国产精品毛多多水多 | 在线亚洲高清揄拍自拍一品区 | 国产美女极度色诱视频www | 婷婷五月综合缴情在线视频 | 高中生自慰www网站 | 麻豆国产人妻欲求不满 | 老子影院午夜伦不卡 | 国产在线aaa片一区二区99 | 性做久久久久久久免费看 | 亚洲国产成人av在线观看 | 日本高清一区免费中文视频 | 欧美激情一区二区三区成人 | 51国偷自产一区二区三区 | 国产又爽又黄又刺激的视频 | 亚洲精品一区二区三区婷婷月 | 久久亚洲中文字幕无码 | 内射老妇bbwx0c0ck | 亚洲精品久久久久久久久久久 | 大地资源网第二页免费观看 | 免费国产黄网站在线观看 | 全球成人中文在线 | 无套内谢的新婚少妇国语播放 | 捆绑白丝粉色jk震动捧喷白浆 | 荫蒂添的好舒服视频囗交 | 国产精品18久久久久久麻辣 | 伊人久久大香线焦av综合影院 | 成人综合网亚洲伊人 | 国产精品人人爽人人做我的可爱 | 久久久国产精品无码免费专区 | aⅴ亚洲 日韩 色 图网站 播放 | 国产日产欧产精品精品app | 亚洲欧美日韩综合久久久 | 色偷偷人人澡人人爽人人模 | 国产麻豆精品精东影业av网站 | 女人被男人躁得好爽免费视频 | 人人妻人人澡人人爽欧美精品 | 18黄暴禁片在线观看 | 蜜臀av无码人妻精品 | 少妇被粗大的猛进出69影院 | 狠狠色欧美亚洲狠狠色www | 色综合久久88色综合天天 | 天天爽夜夜爽夜夜爽 | 丰满人妻一区二区三区免费视频 | 欧美性生交xxxxx久久久 | 国产精品视频免费播放 | 中文字幕日产无线码一区 | 欧美人与物videos另类 | 精品水蜜桃久久久久久久 | 国产熟妇另类久久久久 | 性欧美疯狂xxxxbbbb | 岛国片人妻三上悠亚 | 欧美一区二区三区 | 日韩精品一区二区av在线 | 樱花草在线社区www | 国产猛烈高潮尖叫视频免费 | 无码人妻黑人中文字幕 | 双乳奶水饱满少妇呻吟 | 装睡被陌生人摸出水好爽 | 午夜无码人妻av大片色欲 | 无码人妻丰满熟妇区五十路百度 | 99久久久国产精品无码免费 | 婷婷丁香六月激情综合啪 | 夜夜影院未满十八勿进 | 国产片av国语在线观看 | 无码纯肉视频在线观看 | 人人妻人人澡人人爽人人精品 | 成人免费视频一区二区 | 激情内射日本一区二区三区 | 久久99精品国产.久久久久 | 亚洲精品国偷拍自产在线观看蜜桃 | 色婷婷香蕉在线一区二区 | 蜜桃臀无码内射一区二区三区 | 日韩人妻无码一区二区三区久久99 | 精品人妻人人做人人爽 | 亚洲午夜福利在线观看 | 18无码粉嫩小泬无套在线观看 | 国产手机在线αⅴ片无码观看 | 夫妻免费无码v看片 | 久久无码中文字幕免费影院蜜桃 | 欧美成人高清在线播放 | 伊人久久大香线蕉av一区二区 | 免费无码av一区二区 | 亚洲爆乳无码专区 | 天堂а√在线地址中文在线 | 精品人妻人人做人人爽夜夜爽 | 欧美日本日韩 | 国产亚洲精品久久久ai换 | 亚洲中文字幕av在天堂 | 无码免费一区二区三区 | 国产在线一区二区三区四区五区 | 久久精品国产大片免费观看 | 免费无码肉片在线观看 | 无码一区二区三区在线观看 | 久久久中文久久久无码 | 性史性农村dvd毛片 | 国产情侣作爱视频免费观看 | 永久黄网站色视频免费直播 | 亚洲色无码一区二区三区 | 人人妻在人人 | 欧美日韩精品 | 色欲综合久久中文字幕网 | 青草青草久热国产精品 | 强开小婷嫩苞又嫩又紧视频 | 国产亚洲精品精品国产亚洲综合 | 纯爱无遮挡h肉动漫在线播放 | 精品国产一区二区三区av 性色 | 精品无码一区二区三区的天堂 | 夫妻免费无码v看片 | 国产精品人人爽人人做我的可爱 | 日韩欧美成人免费观看 | 精品国产av色一区二区深夜久久 | 久久无码中文字幕免费影院蜜桃 | 久久这里只有精品视频9 | 99精品无人区乱码1区2区3区 | 377p欧洲日本亚洲大胆 | 免费无码一区二区三区蜜桃大 | 亚洲aⅴ无码成人网站国产app | 夜夜高潮次次欢爽av女 | 精品日本一区二区三区在线观看 | 国产成人精品久久亚洲高清不卡 | 蜜臀aⅴ国产精品久久久国产老师 | 欧美大屁股xxxxhd黑色 | 亚洲精品中文字幕 | 成人精品视频一区二区三区尤物 | 亚洲色无码一区二区三区 | 亚洲精品一区二区三区在线观看 | 亚洲熟妇色xxxxx欧美老妇y | 18黄暴禁片在线观看 | 色情久久久av熟女人妻网站 | 亚洲乱码日产精品bd | 一本大道久久东京热无码av | 国产成人无码区免费内射一片色欲 | 欧美熟妇另类久久久久久多毛 | 狂野欧美性猛xxxx乱大交 | 扒开双腿吃奶呻吟做受视频 | 成人无码精品1区2区3区免费看 | 欧美肥老太牲交大战 | 伊人色综合久久天天小片 | 亚洲色成人中文字幕网站 | 中文字幕无码av激情不卡 | 麻豆国产人妻欲求不满谁演的 | 国产成人午夜福利在线播放 | 麻豆蜜桃av蜜臀av色欲av | 国产情侣作爱视频免费观看 | 九九在线中文字幕无码 | 真人与拘做受免费视频 | 97人妻精品一区二区三区 | 精品欧美一区二区三区久久久 | 又大又硬又黄的免费视频 | 亚洲综合精品香蕉久久网 | 国产色xx群视频射精 | 日本护士毛茸茸高潮 | 对白脏话肉麻粗话av | 天天拍夜夜添久久精品大 | 国精产品一品二品国精品69xx | 久久人人爽人人人人片 | 国产婷婷色一区二区三区在线 | 欧美激情内射喷水高潮 | 国产精品无码永久免费888 | 精品无码一区二区三区爱欲 | 欧美三级不卡在线观看 | 人妻中文无码久热丝袜 | 天天摸天天碰天天添 | 久久无码中文字幕免费影院蜜桃 | 99国产精品白浆在线观看免费 | 久久亚洲国产成人精品性色 | 少妇无套内谢久久久久 | 一本色道久久综合亚洲精品不卡 | 丁香啪啪综合成人亚洲 | 亚洲综合无码一区二区三区 | 国产精品久久久久7777 | 亚洲色欲色欲天天天www | 中文字幕无线码免费人妻 | 欧美性色19p | 成人免费视频在线观看 | 在线欧美精品一区二区三区 | 亚洲色大成网站www国产 | 久久综合色之久久综合 | 国产成人一区二区三区在线观看 | www国产亚洲精品久久网站 | 亚洲成a人片在线观看无码 | 欧美freesex黑人又粗又大 | 天天摸天天透天天添 | 中文字幕乱码人妻无码久久 | 国产成人综合在线女婷五月99播放 | 久久人人爽人人爽人人片av高清 | 亚洲国产精品一区二区第一页 | 成人无码精品1区2区3区免费看 | 成人综合网亚洲伊人 | 国产成人精品一区二区在线小狼 | av无码不卡在线观看免费 | 午夜精品一区二区三区的区别 | 国产精品久免费的黄网站 | 粗大的内捧猛烈进出视频 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 1000部夫妻午夜免费 | www国产亚洲精品久久久日本 | 精品久久久久香蕉网 | 高潮毛片无遮挡高清免费 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 精品熟女少妇av免费观看 | 日本爽爽爽爽爽爽在线观看免 | 在线 国产 欧美 亚洲 天堂 | 少妇厨房愉情理9仑片视频 | 18无码粉嫩小泬无套在线观看 | 高潮毛片无遮挡高清免费视频 | 亚洲综合无码一区二区三区 | 在线播放免费人成毛片乱码 | 国产成人精品必看 | 美女黄网站人色视频免费国产 | 中文字幕无码免费久久99 | 亚洲精品成a人在线观看 | 丝袜 中出 制服 人妻 美腿 | 熟女体下毛毛黑森林 | 成人三级无码视频在线观看 | 欧洲vodafone精品性 | 久久综合网欧美色妞网 | 亚洲aⅴ无码成人网站国产app | 国产精品无码mv在线观看 | 国产亚av手机在线观看 | 野狼第一精品社区 | 国产精品久久久久久无码 | 未满成年国产在线观看 | 人妻插b视频一区二区三区 | 中文字幕av无码一区二区三区电影 | 日韩人妻无码中文字幕视频 | 午夜精品一区二区三区的区别 | 欧美一区二区三区视频在线观看 | 久久久中文字幕日本无吗 | 99国产精品白浆在线观看免费 | 色综合久久中文娱乐网 | 欧美喷潮久久久xxxxx | 在线播放亚洲第一字幕 | 一本久久伊人热热精品中文字幕 | 麻豆国产97在线 | 欧洲 | 性开放的女人aaa片 | 1000部夫妻午夜免费 | 欧美大屁股xxxxhd黑色 | 国内少妇偷人精品视频免费 | 一个人看的www免费视频在线观看 | 97久久精品无码一区二区 | 亚洲综合色区中文字幕 | 成人影院yy111111在线观看 | 色欲久久久天天天综合网精品 | 日韩欧美中文字幕在线三区 | 精品一区二区不卡无码av | 一区二区三区乱码在线 | 欧洲 | 老司机亚洲精品影院无码 | 在教室伦流澡到高潮hnp视频 | 国产香蕉97碰碰久久人人 | 丰满岳乱妇在线观看中字无码 | 99精品视频在线观看免费 | 欧美老人巨大xxxx做受 | 一本色道婷婷久久欧美 | 人人妻人人澡人人爽欧美一区 | 亚洲日韩精品欧美一区二区 | 亚洲小说图区综合在线 | 国产精品无码永久免费888 | 亚洲精品美女久久久久久久 | 色婷婷香蕉在线一区二区 | 国产成人亚洲综合无码 | 成人综合网亚洲伊人 | 最近免费中文字幕中文高清百度 | 图片小说视频一区二区 | 玩弄中年熟妇正在播放 | 国产熟妇高潮叫床视频播放 | 午夜丰满少妇性开放视频 | 欧美怡红院免费全部视频 | 中文字幕人妻无码一区二区三区 | 无码av岛国片在线播放 | 国产一区二区不卡老阿姨 | 国产人妻久久精品二区三区老狼 | 亚洲人交乣女bbw | 欧美日韩一区二区综合 | 亚洲乱码日产精品bd | 国产综合久久久久鬼色 | 亚洲国产av精品一区二区蜜芽 | 国产亚洲精品精品国产亚洲综合 | 熟妇女人妻丰满少妇中文字幕 | 亚洲色在线无码国产精品不卡 | 国内精品久久毛片一区二区 | 日产精品99久久久久久 | 色婷婷久久一区二区三区麻豆 | 1000部夫妻午夜免费 | 久久综合狠狠综合久久综合88 | 欧美亚洲日韩国产人成在线播放 | 久久天天躁狠狠躁夜夜免费观看 | 国内综合精品午夜久久资源 | 国产精品亚洲lv粉色 | 中文字幕无线码免费人妻 | 日本www一道久久久免费榴莲 | 少妇高潮一区二区三区99 | 精品国精品国产自在久国产87 | 欧洲熟妇色 欧美 | 99精品无人区乱码1区2区3区 | 亚洲国产一区二区三区在线观看 | 午夜时刻免费入口 | 一本色道婷婷久久欧美 | 在线观看国产一区二区三区 | 2019nv天堂香蕉在线观看 | 久久综合给合久久狠狠狠97色 | 国产精品久久久久久久9999 | 欧美日韩视频无码一区二区三 | 精品少妇爆乳无码av无码专区 | 在线亚洲高清揄拍自拍一品区 | 乌克兰少妇xxxx做受 | 澳门永久av免费网站 | 亚洲国产av精品一区二区蜜芽 | 麻豆国产丝袜白领秘书在线观看 | 亚洲色偷偷男人的天堂 | 久久zyz资源站无码中文动漫 | aⅴ亚洲 日韩 色 图网站 播放 | 久久国语露脸国产精品电影 | 人妻与老人中文字幕 | 久久综合九色综合97网 | 色综合久久久久综合一本到桃花网 | 国内精品久久久久久中文字幕 | 国内综合精品午夜久久资源 | 国产精品久久久久久久9999 | 少妇的肉体aa片免费 | 无码福利日韩神码福利片 | 丁香花在线影院观看在线播放 | 久久五月精品中文字幕 | а√天堂www在线天堂小说 | 欧美亚洲日韩国产人成在线播放 | 成人精品视频一区二区三区尤物 | 亚洲经典千人经典日产 | 无码人妻精品一区二区三区下载 | 黑人巨大精品欧美一区二区 | 欧美肥老太牲交大战 | 亚洲日本va中文字幕 | 国产精品内射视频免费 | 青草青草久热国产精品 | 欧美xxxx黑人又粗又长 | 精品久久久久久亚洲精品 | 色爱情人网站 | 日本护士xxxxhd少妇 | 高中生自慰www网站 | 影音先锋中文字幕无码 | 无码人妻av免费一区二区三区 | 久久综合给合久久狠狠狠97色 | 无码av中文字幕免费放 | 亚洲va中文字幕无码久久不卡 | 内射巨臀欧美在线视频 | 欧洲熟妇色 欧美 | 久久综合给久久狠狠97色 | 精品久久久久香蕉网 | 日本一区二区三区免费播放 | www国产亚洲精品久久网站 | 中文无码成人免费视频在线观看 | 久久www免费人成人片 | 精品无码一区二区三区的天堂 | 影音先锋中文字幕无码 | 又色又爽又黄的美女裸体网站 | a在线观看免费网站大全 | 国产成人无码午夜视频在线观看 | 国产一区二区不卡老阿姨 | 国内揄拍国内精品少妇国语 | 漂亮人妻洗澡被公强 日日躁 | 国产精品沙发午睡系列 | 国产人成高清在线视频99最全资源 | 亚洲综合伊人久久大杳蕉 | 无码国产乱人伦偷精品视频 | 黑人巨大精品欧美一区二区 | 国产亚洲美女精品久久久2020 | 国产亚洲人成a在线v网站 | 成人欧美一区二区三区黑人 | 扒开双腿疯狂进出爽爽爽视频 | 欧美刺激性大交 | 丰满人妻精品国产99aⅴ | 国产日产欧产精品精品app | 无码纯肉视频在线观看 | 在线精品亚洲一区二区 | 日韩精品一区二区av在线 | 久久亚洲精品成人无码 | 99久久久无码国产aaa精品 | 国产亚洲精品久久久久久国模美 | 欧美日韩在线亚洲综合国产人 | 精品人妻av区 | 亚洲伊人久久精品影院 | 在线天堂新版最新版在线8 | 大地资源中文第3页 | 性欧美videos高清精品 | 国产精品va在线播放 | 国产午夜亚洲精品不卡 | 乌克兰少妇性做爰 | 兔费看少妇性l交大片免费 | 未满小14洗澡无码视频网站 | 伊人久久大香线蕉午夜 | 亚洲小说春色综合另类 | 日本又色又爽又黄的a片18禁 | 国产亚洲欧美在线专区 | 亚洲日本在线电影 | 国产片av国语在线观看 | 日本一区二区三区免费播放 | 亚洲精品久久久久中文第一幕 | 学生妹亚洲一区二区 | 人人妻人人澡人人爽欧美一区 | 国内揄拍国内精品少妇国语 | 亚洲一区av无码专区在线观看 | 亚洲精品久久久久avwww潮水 | 久久久精品456亚洲影院 | 国产特级毛片aaaaaa高潮流水 | 国产人妖乱国产精品人妖 | 一区二区传媒有限公司 | 草草网站影院白丝内射 | 国语自产偷拍精品视频偷 | 亚洲国产精品无码久久久久高潮 | 色综合视频一区二区三区 | 狂野欧美性猛交免费视频 | 麻豆成人精品国产免费 | 无码人妻丰满熟妇区毛片18 | 亚洲精品国产a久久久久久 | 亚洲自偷自拍另类第1页 | 激情五月综合色婷婷一区二区 | 麻豆成人精品国产免费 | 亚洲色欲久久久综合网东京热 | 黑人巨大精品欧美一区二区 | 双乳奶水饱满少妇呻吟 | 一个人免费观看的www视频 | 久久久久国色av免费观看性色 | 色综合久久网 | 人人妻人人澡人人爽精品欧美 | 国内精品一区二区三区不卡 | 精品国产一区二区三区四区 | 国产美女精品一区二区三区 | 丰满人妻精品国产99aⅴ | 亚洲精品午夜国产va久久成人 | 成熟妇人a片免费看网站 | 欧美老熟妇乱xxxxx | 玩弄少妇高潮ⅹxxxyw | 免费观看的无遮挡av | 久久久久久av无码免费看大片 | 成 人 免费观看网站 | 小sao货水好多真紧h无码视频 | 日欧一片内射va在线影院 | 大肉大捧一进一出视频出来呀 | 麻豆国产人妻欲求不满 | 久久zyz资源站无码中文动漫 | 少妇被粗大的猛进出69影院 | 国产精品毛片一区二区 | 亚洲综合精品香蕉久久网 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 色婷婷欧美在线播放内射 | 精品一区二区三区波多野结衣 | 天堂亚洲2017在线观看 | 国产成人精品一区二区在线小狼 | 国产精品无码久久av | 国产精品国产三级国产专播 | 精品国产aⅴ无码一区二区 | 国产av无码专区亚洲awww | 国产国产精品人在线视 | 狂野欧美激情性xxxx | 午夜熟女插插xx免费视频 | 娇妻被黑人粗大高潮白浆 | 最新国产麻豆aⅴ精品无码 | 欧美怡红院免费全部视频 | 久久综合九色综合欧美狠狠 | 亚洲国产精品一区二区美利坚 | 在线精品国产一区二区三区 | 亚洲精品国偷拍自产在线观看蜜桃 | 日本熟妇人妻xxxxx人hd | 国产明星裸体无码xxxx视频 | 澳门永久av免费网站 | 中文字幕av伊人av无码av | 青青青手机频在线观看 | 熟妇人妻中文av无码 | 欧美激情一区二区三区成人 | 色欲久久久天天天综合网精品 | 国产亚洲美女精品久久久2020 | 曰韩少妇内射免费播放 | 国产电影无码午夜在线播放 | 亚洲色大成网站www国产 | 蜜桃视频韩日免费播放 | 色情久久久av熟女人妻网站 | 黑人巨大精品欧美一区二区 | 国产亚洲tv在线观看 | 国产超级va在线观看视频 | 国产一区二区三区影院 | 国产成人精品无码播放 | 女人被男人躁得好爽免费视频 | 少妇邻居内射在线 | 中文字幕乱码人妻二区三区 | 中文字幕人妻无码一夲道 | 伊人久久大香线蕉av一区二区 | 131美女爱做视频 | 国产精品嫩草久久久久 | 亚洲人亚洲人成电影网站色 | 欧美刺激性大交 | 亚洲日本在线电影 | 性啪啪chinese东北女人 | 亚洲爆乳大丰满无码专区 | 高中生自慰www网站 | 国产av剧情md精品麻豆 | 国产精品二区一区二区aⅴ污介绍 | 亚洲成av人影院在线观看 | 三级4级全黄60分钟 | 亚洲成av人影院在线观看 | 久久久久se色偷偷亚洲精品av | 三上悠亚人妻中文字幕在线 | 国产精品亚洲а∨无码播放麻豆 | 97精品人妻一区二区三区香蕉 | 亚洲精品www久久久 | 欧美 亚洲 国产 另类 | 国产成人精品无码播放 | 人人爽人人澡人人人妻 | 色欲综合久久中文字幕网 | 久久久精品人妻久久影视 | 18黄暴禁片在线观看 | 久久精品视频在线看15 | 欧美高清在线精品一区 | 精品欧美一区二区三区久久久 | 亚洲国产精品成人久久蜜臀 | 成熟女人特级毛片www免费 | 永久免费观看美女裸体的网站 | 国内少妇偷人精品视频 | 在线a亚洲视频播放在线观看 | 色一情一乱一伦一区二区三欧美 | 黑人巨大精品欧美一区二区 | 久久久久久九九精品久 | 亚洲日韩av一区二区三区中文 | 国产精品久久久久久亚洲影视内衣 | 日本爽爽爽爽爽爽在线观看免 | 久久国产精品_国产精品 | 天堂久久天堂av色综合 | 人妻人人添人妻人人爱 | 亚洲国产精品一区二区第一页 | 国产精品久久国产精品99 | 欧美人与善在线com | 人妻夜夜爽天天爽三区 | 日韩无套无码精品 | 日日摸天天摸爽爽狠狠97 | 午夜熟女插插xx免费视频 | 国产成人精品三级麻豆 | 国产又爽又黄又刺激的视频 | 亚洲中文字幕无码中字 | 久久无码中文字幕免费影院蜜桃 | 欧美日韩综合一区二区三区 | 亚洲精品国产精品乱码不卡 | 图片区 小说区 区 亚洲五月 | 成人一在线视频日韩国产 | 青青久在线视频免费观看 | 亚洲综合久久一区二区 | 国产精品香蕉在线观看 | 成人欧美一区二区三区黑人免费 | 亚洲精品一区二区三区四区五区 | 国产做国产爱免费视频 | 亚洲欧洲日本综合aⅴ在线 | 婷婷五月综合缴情在线视频 | 久久精品视频在线看15 | 亚洲一区av无码专区在线观看 | 国产精品.xx视频.xxtv | 激情内射亚州一区二区三区爱妻 | 国产午夜福利亚洲第一 | 一个人看的视频www在线 | 狂野欧美性猛交免费视频 | 日日躁夜夜躁狠狠躁 | 日日噜噜噜噜夜夜爽亚洲精品 | 亚洲中文字幕久久无码 | 日本一本二本三区免费 | 无码毛片视频一区二区本码 | 成人无码精品1区2区3区免费看 | 天堂亚洲免费视频 | 青青草原综合久久大伊人精品 | 成熟女人特级毛片www免费 | 成熟人妻av无码专区 | 东京热一精品无码av | 亚洲乱码日产精品bd | 无遮挡国产高潮视频免费观看 | 377p欧洲日本亚洲大胆 | 性生交大片免费看l | 午夜无码区在线观看 | 亚洲小说春色综合另类 | 黄网在线观看免费网站 | 小sao货水好多真紧h无码视频 | 亚洲国产精品无码一区二区三区 | 国产成人精品一区二区在线小狼 | 人妻无码久久精品人妻 | 亚洲国产成人av在线观看 | 在线观看免费人成视频 | 无码人妻精品一区二区三区下载 | 人妻插b视频一区二区三区 | 久久www免费人成人片 | 99久久亚洲精品无码毛片 | 97资源共享在线视频 | 性开放的女人aaa片 | 夜夜高潮次次欢爽av女 | 欧美怡红院免费全部视频 | 国产九九九九九九九a片 | 欧美真人作爱免费视频 | 国产免费久久精品国产传媒 | 国产激情艳情在线看视频 | 天堂亚洲免费视频 | 九九久久精品国产免费看小说 | 久久无码人妻影院 | 夜夜夜高潮夜夜爽夜夜爰爰 | 日本精品少妇一区二区三区 | 亚洲日韩中文字幕在线播放 | 国产在线无码精品电影网 | 亚洲欧美色中文字幕在线 | 国产另类ts人妖一区二区 | 99久久99久久免费精品蜜桃 | 久久久久久久久蜜桃 | 久久久婷婷五月亚洲97号色 | 成熟妇人a片免费看网站 | 久久精品中文字幕大胸 | 精品人人妻人人澡人人爽人人 | 丝袜 中出 制服 人妻 美腿 | 曰韩无码二三区中文字幕 | 国精产品一品二品国精品69xx | 国精品人妻无码一区二区三区蜜柚 | 精品国产av色一区二区深夜久久 | 中文字幕av伊人av无码av | 永久免费观看国产裸体美女 | 激情人妻另类人妻伦 | 国产精品18久久久久久麻辣 | 大屁股大乳丰满人妻 | 女高中生第一次破苞av | 丰满少妇弄高潮了www | 九一九色国产 | 小鲜肉自慰网站xnxx | 国产激情一区二区三区 | 国产精品自产拍在线观看 | 日韩少妇内射免费播放 | 久久精品丝袜高跟鞋 | 成人无码影片精品久久久 | 精品国产一区二区三区av 性色 | 久久这里只有精品视频9 | 国产在线一区二区三区四区五区 | 国产特级毛片aaaaaaa高清 | www国产亚洲精品久久网站 | 欧美兽交xxxx×视频 | 免费观看激色视频网站 | 狠狠噜狠狠狠狠丁香五月 | 久久久精品人妻久久影视 | 国内精品人妻无码久久久影院蜜桃 | 亚洲国产一区二区三区在线观看 | 欧美怡红院免费全部视频 | 国产高清av在线播放 | 成人av无码一区二区三区 | 国产成人亚洲综合无码 | 亚洲欧美日韩国产精品一区二区 | 最近免费中文字幕中文高清百度 | 18精品久久久无码午夜福利 | 国产精品久久国产三级国 | 性色欲情网站iwww九文堂 | 国产真人无遮挡作爱免费视频 | 老熟妇乱子伦牲交视频 | 久久精品女人的天堂av | 曰韩少妇内射免费播放 | 人妻体内射精一区二区三四 | 2020久久香蕉国产线看观看 | 欧洲熟妇色 欧美 | 国产美女极度色诱视频www | 东京无码熟妇人妻av在线网址 | 国产人妻久久精品二区三区老狼 | 噜噜噜亚洲色成人网站 | 国产97在线 | 亚洲 | 国产成人精品视频ⅴa片软件竹菊 | 国产精品高潮呻吟av久久4虎 | 久久久久99精品成人片 | 未满小14洗澡无码视频网站 | 日产精品高潮呻吟av久久 | 99久久精品国产一区二区蜜芽 | 亚洲色欲色欲欲www在线 | 精品无码av一区二区三区 | 国产精品久久久av久久久 | 亚洲国产精品久久久久久 | 久久五月精品中文字幕 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产特级毛片aaaaaa高潮流水 | 日韩欧美中文字幕公布 | 无码精品人妻一区二区三区av | 欧美喷潮久久久xxxxx | 一本色道久久综合狠狠躁 | 亚洲精品久久久久久久久久久 | 成人欧美一区二区三区黑人 | 好爽又高潮了毛片免费下载 | 又紧又大又爽精品一区二区 | 欧美老妇交乱视频在线观看 | 色妞www精品免费视频 | 亚洲精品美女久久久久久久 | 亚洲精品中文字幕久久久久 | 久9re热视频这里只有精品 | 无码成人精品区在线观看 | 色婷婷香蕉在线一区二区 | 无码乱肉视频免费大全合集 | 国产精品18久久久久久麻辣 | 国产手机在线αⅴ片无码观看 | 色综合久久中文娱乐网 | 欧美人与物videos另类 | 97色伦图片97综合影院 | 扒开双腿吃奶呻吟做受视频 | 色婷婷久久一区二区三区麻豆 | 国产精品爱久久久久久久 | 中文字幕日韩精品一区二区三区 | 丰满少妇弄高潮了www | 欧美日本精品一区二区三区 | 67194成是人免费无码 | 久久综合色之久久综合 | 天天躁日日躁狠狠躁免费麻豆 | 国产精品久久久 | 日韩欧美成人免费观看 | 国产欧美亚洲精品a | 国产人妻精品一区二区三区不卡 | 日韩少妇白浆无码系列 | 日韩精品成人一区二区三区 | 久久久久se色偷偷亚洲精品av | 国产高清av在线播放 | 中文字幕人妻丝袜二区 | 亚洲国产成人av在线观看 | 日韩亚洲欧美中文高清在线 | 亚洲成a人片在线观看无码 | 久久久久久亚洲精品a片成人 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 在教室伦流澡到高潮hnp视频 | 欧美自拍另类欧美综合图片区 | 亚洲精品国产第一综合99久久 | 中文字幕日产无线码一区 | 国产乱人无码伦av在线a | 欧美日本精品一区二区三区 | 中文字幕人妻丝袜二区 | 无套内射视频囯产 | 99精品无人区乱码1区2区3区 | 又色又爽又黄的美女裸体网站 | 九九久久精品国产免费看小说 | 亚洲综合无码久久精品综合 | 国产成人无码a区在线观看视频app | 麻豆成人精品国产免费 | 小泽玛莉亚一区二区视频在线 | 国产情侣作爱视频免费观看 | 国产真实伦对白全集 | 九九在线中文字幕无码 | 亚洲国产欧美国产综合一区 | 国产农村乱对白刺激视频 | 久久久精品人妻久久影视 | 97色伦图片97综合影院 | 亚洲人成人无码网www国产 | 狠狠色噜噜狠狠狠7777奇米 | 色五月丁香五月综合五月 | 给我免费的视频在线观看 | 成年美女黄网站色大免费全看 | 久久久久人妻一区精品色欧美 | 欧美性猛交xxxx富婆 | 强奷人妻日本中文字幕 | 思思久久99热只有频精品66 | 中文字幕av伊人av无码av | 无码av中文字幕免费放 | 精品人妻人人做人人爽 | 国产无遮挡又黄又爽又色 | 无码帝国www无码专区色综合 | 熟妇人妻无乱码中文字幕 | 亚洲区欧美区综合区自拍区 | 丰满人妻翻云覆雨呻吟视频 | 俺去俺来也在线www色官网 | 免费无码的av片在线观看 | 成人免费视频视频在线观看 免费 | 亚洲熟悉妇女xxx妇女av | 蜜桃视频韩日免费播放 | 欧美人妻一区二区三区 | 综合激情五月综合激情五月激情1 | 人人妻人人藻人人爽欧美一区 | 粗大的内捧猛烈进出视频 | 日日碰狠狠躁久久躁蜜桃 | 国产午夜视频在线观看 | 99久久久国产精品无码免费 | 日日摸夜夜摸狠狠摸婷婷 | 小鲜肉自慰网站xnxx | 男人和女人高潮免费网站 | 国产亚洲精品精品国产亚洲综合 | 国产亚洲视频中文字幕97精品 | 亚洲成在人网站无码天堂 | 午夜性刺激在线视频免费 | 久久综合激激的五月天 | 天天爽夜夜爽夜夜爽 | 色婷婷综合激情综在线播放 | 国产精品无码一区二区三区不卡 | 日日干夜夜干 | 东京热男人av天堂 | 日本免费一区二区三区最新 | 丰满少妇人妻久久久久久 | 免费播放一区二区三区 | 人妻天天爽夜夜爽一区二区 | 偷窥村妇洗澡毛毛多 | 中文字幕人妻无码一夲道 | 成在人线av无码免费 | 欧美丰满老熟妇xxxxx性 | 欧美猛少妇色xxxxx | 扒开双腿疯狂进出爽爽爽视频 | 无码人妻精品一区二区三区下载 | 欧美性生交xxxxx久久久 | 国产婷婷色一区二区三区在线 | 中国女人内谢69xxxx | 无码精品国产va在线观看dvd | 国产精品第一区揄拍无码 | 国产小呦泬泬99精品 | 波多野结衣av一区二区全免费观看 | 精品久久久久香蕉网 | 欧美熟妇另类久久久久久多毛 | 久久精品国产精品国产精品污 | 天天躁日日躁狠狠躁免费麻豆 | 377p欧洲日本亚洲大胆 | 麻豆精品国产精华精华液好用吗 | 女人被男人躁得好爽免费视频 | 2019nv天堂香蕉在线观看 | 麻豆国产丝袜白领秘书在线观看 | 少妇高潮一区二区三区99 | 国产成人综合色在线观看网站 | 国产色在线 | 国产 | 日韩欧美中文字幕公布 | 成人免费无码大片a毛片 | 欧美 日韩 人妻 高清 中文 | 欧美真人作爱免费视频 | 久久人人97超碰a片精品 | 国产亚洲精品久久久闺蜜 | 2020久久超碰国产精品最新 | a在线亚洲男人的天堂 | 国产做国产爱免费视频 | 欧洲欧美人成视频在线 | 欧美日韩一区二区三区自拍 | 黄网在线观看免费网站 | 国产无套内射久久久国产 | 亚洲娇小与黑人巨大交 | 秋霞特色aa大片 | 亚洲日韩一区二区三区 | 夜夜高潮次次欢爽av女 | 97se亚洲精品一区 | 男人的天堂av网站 | 国产亚洲人成a在线v网站 | 国产精品人人妻人人爽 | 日本熟妇大屁股人妻 | 成人性做爰aaa片免费看不忠 | 国产乱人伦av在线无码 | 玩弄少妇高潮ⅹxxxyw | 亲嘴扒胸摸屁股激烈网站 | 亚洲中文字幕在线无码一区二区 | 精品久久久无码人妻字幂 | 亚洲の无码国产の无码步美 | 99久久久国产精品无码免费 | 色综合久久88色综合天天 | 成熟妇人a片免费看网站 | 无码毛片视频一区二区本码 | 亚洲日本va午夜在线电影 | 日韩无码专区 | 天堂亚洲2017在线观看 | 两性色午夜免费视频 | 久久zyz资源站无码中文动漫 | 久久亚洲精品中文字幕无男同 | 丰满护士巨好爽好大乳 | 国内少妇偷人精品视频 | 精品熟女少妇av免费观看 | 大屁股大乳丰满人妻 | 黄网在线观看免费网站 | 撕开奶罩揉吮奶头视频 | 装睡被陌生人摸出水好爽 | 牛和人交xxxx欧美 | 欧美国产亚洲日韩在线二区 | 精品国产乱码久久久久乱码 | 久在线观看福利视频 | 男女性色大片免费网站 | 老子影院午夜伦不卡 | 精品人妻人人做人人爽夜夜爽 | 国产小呦泬泬99精品 | 国产乱子伦视频在线播放 | 美女黄网站人色视频免费国产 | 久久久www成人免费毛片 | 人妻无码久久精品人妻 | 内射欧美老妇wbb | 好爽又高潮了毛片免费下载 | 久久无码专区国产精品s | 99久久99久久免费精品蜜桃 | 蜜桃无码一区二区三区 | 国产精品无码久久av | 国产明星裸体无码xxxx视频 | 欧美激情内射喷水高潮 | 四虎永久在线精品免费网址 | 亚洲国产综合无码一区 | 国产一区二区三区日韩精品 | 欧美激情一区二区三区成人 | 亚洲国产精品无码久久久久高潮 | 精品国产精品久久一区免费式 | 日本xxxx色视频在线观看免费 | 在线а√天堂中文官网 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产精品丝袜黑色高跟鞋 | 国产口爆吞精在线视频 | 国产精品高潮呻吟av久久4虎 | 天天躁夜夜躁狠狠是什么心态 | 精品无码av一区二区三区 | 久久精品成人欧美大片 | 无遮挡啪啪摇乳动态图 | 无码人妻少妇伦在线电影 | 久久精品女人天堂av免费观看 | 内射后入在线观看一区 | 无码一区二区三区在线 | 小鲜肉自慰网站xnxx | 免费人成在线视频无码 | 131美女爱做视频 | 中文字幕av日韩精品一区二区 | 清纯唯美经典一区二区 | 国产手机在线αⅴ片无码观看 | 久久国产精品偷任你爽任你 | 亚洲国产日韩a在线播放 | www国产精品内射老师 | 狠狠色色综合网站 | 国产特级毛片aaaaaa高潮流水 | 午夜肉伦伦影院 | 日本一区二区三区免费播放 | 亚洲欧洲日本综合aⅴ在线 | 人人澡人人妻人人爽人人蜜桃 | 一区二区三区乱码在线 | 欧洲 | 久久99久久99精品中文字幕 | 国产精品毛片一区二区 | 中文字幕无码av激情不卡 | 国内精品人妻无码久久久影院 | 樱花草在线社区www | 国产成人一区二区三区在线观看 | 两性色午夜视频免费播放 | 亚洲精品成人av在线 | 99国产精品白浆在线观看免费 |