日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

shell 生活0806012145

發布時間:2025/3/8 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 shell 生活0806012145 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引用:     ?
  學習 Shell Scripts
?
如果您真的很想要走信息這條路,并且想要好好的管理好屬于您的主機,那么,別說鳥哥不告訴您, Shell Scripts 真的是必須要學習的一項課題呢!基本上, shell script 有點像是早期的批次檔, 亦即是將一些指令匯整起來一次執行,但是 Shell script 擁有更強大的功能,那就是, 他可以進行類似程序 (program) 的撰寫,并且,不需要經過編譯 (compiler) 就能夠執行, 真的很方便。加上,我們可透過 shell script 來簡化我們日常的工作管理, 而且,整個 Linux 環境中,一些服務 (services) 的啟動都是透過 shell script 的, 如果您對于 script 不了解,嘿嘿!發生問題時,可真是會求助無門喔! 所以,好好的學一學他吧!??


1. 什么是 Shell Script
  1.1 干嘛學習 shell scripts?
  1.2 第一支 script 的撰寫與執行
  1.3 撰寫 shell script 的良好習慣建立
2. 簡單的 shell script 練習:
3. 善用判斷式:
  3.1 利用 test 指令的測試功能
  3.2 利用判斷符號 [ ]
  3.3 Shell script 的預設變數($0, $1...)
4. 條件判斷式:
  4.1 利用 if .... then
  4.2 利用 case ..... esac 判斷
  4.3 利用 function 功能
5. 循環 (loop)
  5.1 while....do....done, until....do....done
  5.2 for...do...done
6. shell script 的追蹤與 debug
7. 本章習題練習


--------------------------------------------------------------------------------
什么是 Shell scripts ?

這個有趣的問題趕緊來回答看看,什么是 shell script 呢? shell 我們在 認識 bash 當中已經提過了,那是一個文字接口底下讓我們與系統溝通的一個工具接口,那么 script 是啥? 字面上的意義, script 是『腳本、劇本』的意思。整句話是說, shell script 是針對 shell 所寫的『劇本!』 什么東西啊?呵呵!其實, shell script 是利用 shell 的功能所寫的一個『程序 (program)』,這個程序是使用純文字文件,將一些 shell 的語法與指令寫在里面, 搭配正規表示法、管線命令與數據流重導向等功能,以達到我們所想要的處理目的。

所以,簡單的說, shell script 就像是早期 DOS 年代的批次檔 (.bat) ,最簡單的功能就是將許多指令匯整寫在一起, 讓使用者很輕易的就能夠 one touch (執行一個檔案 "shell script" ,就能夠一次執行多個指令), 而, shell script 更提供數組、循環、條件與邏輯判斷等重要功能,讓使用者也可以直接以 shell 來撰寫程序,而不必使用類似 C 程序語言等傳統程序撰寫的語法呢!

那,這么說您可以了解了嗎?是的! shell script 可以簡單的被看成是批次檔, 也可以被說成是一個程序語言,且這個程序語言由于都是利用 shell 與相關工具指令, 所以不需要編譯即可執行,且擁有不錯的除錯 (debug) 工具,所以,他可以幫助系統管理員快速的管理好主機。


--------------------------------------------------------------------------------
干嘛學習 shell scripts?

這是個好問題,我又干嘛一定要學 shell script ?我又不是信息人,沒有寫程序的概念, 那我干嘛還要學 shell script 呢?不要學可不可以啊?呵呵~如果 Linux 對您而言, 您只是想要『會用』而已,那么,不需要學 shell script 也還無所謂,這部分先給他跳過去, 等到有空的時候,再來好好的瞧一瞧。但是,如果您是真的想要玩清楚 Linux 的來龍去脈, 那么 shell script 就不可不知,為什么呢?因為:


自動化管理的重要依據:?
不用鳥哥說您也知道,管理一部主機真不是件簡單的事情,每天要進行的任務就有: 查詢登錄檔、追蹤流量、監控使用者使用主機狀態、主機各項硬設備狀態、 主機軟件更新查詢、更不要說得應付其它使用者的突然要求了。而這些工作, 您想要自行手動處理,還是寫個簡單的程序來幫您每日自動處理分析,若有問題才通知您呢? 當然是讓系統自動工作比較好,對吧!呵呵~這就得要良好的 shell script 來幫忙的啦!


追蹤與管理系統的重要工作:?
雖然我們還沒有提到服務啟動的方法,不過,這里可以先提一下,我們 Linux 系統的服務 ( services ) 啟動的接口,在 /etc/init.d/ 這個目錄下,所有的檔案都是 scripts ; 另外,包括開機 (booting) 過程也都是利用 shell script 來幫忙搜尋系統的相關設定數據, 然后再代入各個服務的設定參數啊!舉例來說,如果我們想要重新啟動系統登錄文件, 可以使用:『/etc/init.d/syslogd restart』,那個 syslogd 檔案就是 script 啦! 另外,我曾經在某一代的 FC 上面發現,啟動 MySQL 這個數據庫服務時,確實是可以啟動的, 但是屏幕上卻老是出現『failure』,后來才發現,原來是啟動 MySQL 那個 script 會主動的以『空的密碼』去嘗試登入 MySQL ,但我修改過 MySQL 的密碼啰~當然就登入失敗~ 后來改了改 script ,就略去這個問題啦!如此說來, script 確實是需要學習的啊!


簡單入侵偵測功能:?
當我們的系統有異狀時,大多會將這些異狀記錄在系統記錄器,也就是我們常提到的『系統登錄文件』, 那么我們可以在固定的幾分鐘內主動的去分析系統登錄文件,若察覺有問題,就立刻通報管理員, 或者是立刻加強防火墻的設定規則,如此一來,您的主機可就能夠達到『自我保護』的聰明學習功能啦~ 舉例來說,我們可以通過 shell script 去分析『當該封包嘗試幾次還是聯機失敗之后,就予以抵擋住該 IP』之類的舉動,例如鳥哥寫過一個關于抵擋砍站軟件的 shell script , 就是用這個想法去達成的呢!


連續指令單一化:?
其實,對于新手而言, script 最簡單的功能就是:『匯整一些在 command line 下達的連續指令,將他寫入 scripts 當中,而由直接執行 scripts 來啟動一連串的 command line 指令輸出入!』例如: 防火墻連續規則 ( iptables ),開機加載程序的項目 ( 就是在 /etc/rc.d/rc.local 里頭的數據 ) ,等等都是相似的功能啦! 其實,說穿了,如果不考慮 program 的部分,那么 scripts 也可以想成,僅是幫我們把一大串的指令匯整在一個檔案里面, 而直接執行該檔案就可以執行那一串又臭又長的指令段!就是這么簡單啦!


簡易的數據處理:?
由前一章 正規表示法 的 awk 程序說明中, 您可以發現, awk 可以用來處理簡單的數據數據呢!例如薪資單的處理啊等等的。 shell script 的功能更強大,例如鳥哥曾經用 shell script 直接處理數據數據的比對啊, 文字數據的處理啊等等的,撰寫方便,速度又快(因為在 Linux 效能較佳), 真的是很不錯用的啦!


跨平臺支持與學習歷程較短:?
幾乎所有的 Unix Like 上面都可以跑 shell script ,連 MS Windows 系列也有相關的仿真器可以用, 此外, shell script 的語法是相當親和的,看都看的懂得文字,而不是機器碼, 很容易學習~這些都是您可以加以考慮的學習點啊!


上面這些都是您考慮學習 shell script 的特點~此外, shell script 還可以簡單的以 vi 來直接編寫,實在是很方便的好東西!所以,還是建議您學習一下啦。

不過,雖然 shell script 號稱是程序 (program) ,但實際上, shell script 處理數據的速度上是不太夠的。因為 shell script 用的是外部的指令與 bash shell 的一些預設工具,所以,他常常會去呼叫外部的函式庫,因此,運算速度上面當然比不上傳統的程序語言。 所以啰, shell script 用在系統管理上面是很好的一項工具,但是用在處理大量數值運算上, 就不夠好了~而且還很麻煩,因為:Shell scripts 的速度較慢, 且使用的 CPU 資源較多,造成主機資源的分配不良。還好, 我們確實很少看到利用 shell script 在進行大量數據運算的,所以,不必擔心的啦!

?

--------------------------------------------------------------------------------
第一支 script 的撰寫與執行

如同前面講到的, shell script 其實就是純文字文件 (ASCII) ,我們可以編輯這個檔案, 然后讓這個檔案來幫我們一次執行多個指令,或者是利用一些運算與邏輯判斷來幫我們達成某些功能。 所以啦,要編輯這個檔案的內容時,當然就需要具備有 bash shell 指令下達的相關認識。 我們說過,要下達指令需要注意的事項在 bash 章節內已經提過, 在 shell script 的撰寫同樣需要用到這些注意事項的:
如同前面 bash command 提到的,指令與參數間的多個空白會被忽略掉;?
而空白行也將被忽略掉!,并且 [tab] 也是不會被理會的!?
如果讀取到一個 Enter 符號 ( CR )),就嘗試開始執行該行命令;?
至于如果一行的內容太多,則可以使用 /[Enter] 來延伸至下一行;?
此外,使用最多的 # 可做為批注!任何加在 # 后面的字,將全部被視為批注文字而被忽略!?
如此一來,我們在 script 內所撰寫的程序,就會被一行一行的執行。好了,那么這個程序假設文件名是 shell.sh 好了,如何執行這個檔案?很簡單,可以有底下幾個方法:
將 shell.sh 加上可讀與執行 (rx) 的權限,然后就能夠以 ./shell.sh 來執行了;?
直接以 sh shell.sh 的方式來直接執行即可。
反正重點就是要讓那個 shell.sh 內的指令可以被執行的意思啦!咦!那我為何需要使用 ./shell.sh 來下達指令? 還記得我們在 bash 里面一直強調的,指令是否能夠被執行與 PATH 這個環境變量有關, 所以,要執行『目前這個目錄下的某個檔案』就需要加上 ./ 這個目錄啦!另外,其實您也可以將 shell.sh 放在您家目錄下的 ~/bin 這個目錄中,然后利用 PATH="$PATH":~/bin 的設定, 嘿嘿,就能夠直接執行您的 script 啰~ ^_^

那,為何 sh shell.sh 也可以執行呢?這是因為 /bin/sh 其實就是 /bin/bash , 使用 sh shell.sh 亦即告訴系統,我想要直接以 bash 的功能來執行 shell.sh 這個檔案內的相關指令的意思。 而我們也可以利用 sh 的參數,如 -n 及 -x 來檢查與追蹤 shell.sh 的語法是否正確呢! ^_^


--------------------------------------------------------------------------------

撰寫第一支 script?
不論是那個門派,要學武功要從掃地做起,那么要學程序呢?呵呵,肯定是由『秀出 Hello World!』 這個字眼開始的!OK!那么鳥哥就先寫一支 script 給大家瞧一瞧:
[root@linux ~]# mkdir scripts; cd scripts
[root@linux scripts]# vi sh01.sh
#!/bin/bash
# Program:
#?????? This program is used to show "Hello World !" in screen.
# History:
# 2005/08/23 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Hello World ! /a /n"
exit 0

?
在我們這個章節當中,請將所有的撰寫的 script 放置到您家目錄的 ~/scripts 這個目錄內, 比較好管理啦!上面的寫法當中,我主要將整個程序的撰寫分成數段,大致是這樣:
第一行 #!/bin/bash 在宣告這個 script 使用的 shell 名稱:
因為我們使用的是 bash ,所以,必須要以『 #!/bin/bash 』來宣告這個檔案內的語法使用 bash 的語法!那么當這個程序被執行時,他就能夠加載 bash 的相關環境設定檔, 并且執行 bash 來使我們底下的指令能夠執行!這很重要的!(在很多狀況中,如果沒有設定好這一行, 那么該程序很可能會無法執行,因為系統可能無法判斷該程序需要使用什么 shell 來執行啊!)


程序內容的宣告:
整個 script 當中,除了第一行的 #! 是用來宣告 shell 的之外,其它的 # 都是『批注』用途! 所以上面的程序當中,第二行以下就是用來說明整個程序的狀態。一般來說, 建議您一定要養成說明該 script 的:1. 內容與功能; 2. 版本信息; 3. 作者與聯絡方式; 4. 建檔日期;5. 歷史紀錄 等等。這將有助于未來程序的改寫與 debug 呢!


主要環境變量的宣告:
建議務必要將一些重要的環境變量設定好,鳥哥個人認為, PATH 是當中最重要的! 如此一來,則可讓我們這支程序在進行時,可以直接下達指令, 而不必寫絕對路徑呢!比較好啦!


主要程序部分
就將主要的程序寫好即可!在這個例子當中,就是 echo 那一行啦!


執行成果告知
是否記得我們在 bash 里面要討論一個指令的執行成功與否,可以使用 $? 這個變量來觀察~ 那么我們也可以利用 exit 這個指令來讓程序中斷,并且回傳一個數值給系統。 在我們這個例子當中,我使用 exit 0 ,這代表離開 script ,并且回傳一個 0 給系統, 所以我執行完這個 script 后,若接著下達 echo $? 則可得到 0 的值喔! 更聰明的讀者應該也知道了,呵呵!利用這個 exit n 的功能,我們還可以自訂錯誤訊息, 讓這支程序變得更加的 smart 呢!?
接下來執行看看結果是怎樣吧?
[root@linux scripts]# sh sh01.sh
Hello World !


?
您會看到屏幕是這樣,而且應該還會聽到『咚』的一聲,為什么呢?還記得前一章提到的 printf 吧?用 echo 接著那些特殊的按鍵也可以發生同樣的事情~ 不過, echo 必須要加上 -e 的參數才行! 呵呵!在您寫完這個小 script 之后,您就可以大聲的說:『我也會寫程序了』!哈哈! 很簡單有趣吧~ ^_^

另外,你也可以利用:『chmod a+x sh01.sh; ./sh01.sh』來執行這個 script 的呢!


--------------------------------------------------------------------------------
撰寫 shell script 的良好習慣建立

一個良好習慣的養成是很重要的~大家在剛開始撰寫程序的時候,最容易忽略這部分, 認為程序寫出來就好了,其它的不重要。其實,如果程序的說明能夠更清楚, 那么對您自己是有很大的幫助的。

舉例來說,鳥哥自己為了自己的需求,曾經撰寫了不少的 script 來幫我進行主機 IP 的偵測啊、 登錄檔分析與管理啊、自動上傳下載重要設定檔啊等等的,不過,早期就是因為太懶了, 管理的主機又太多了,常常同一個程序在不同的主機上面進行更改,到最后,到底哪一支才是最新的都記不起來, 而且,重點是,我到底是改了哪里??為什么做那樣的修改?都忘的一乾二凈~真要命~

所以,后來鳥哥在寫程序的時候,通常會比較仔細的將程序的設計過程給他記錄下來, 而且還會記錄一些歷史紀錄,如此一來,好多了~ 至少很容易知道我修改了哪些數據,以及程序修改的理念與邏輯概念等等, 在維護上面是輕松很多很多的喔!

另外,在一些環境的設定上面,畢竟每個人的環境都不相同,為了取得較佳的執行環境, 我都會自行先定義好一些一定會被用到的環境變量,例如 PATH 這個玩意兒! 這樣比較好啦~所以說,建議您一定要養成良好的 script 撰寫習慣, 在每個 script 的文件頭處記錄好:
script 的功能;?
script 的版本信息;?
script 的作者與聯絡方式;?
script 的版權宣告方式;?
script 的 History (歷史紀錄);?
script 內較特殊的指令,使用絕對路徑的方式來下達;?
script 運作時需要的環境變量預先宣告與設定。

--------------------------------------------------------------------------------
簡單的 shell script 練習

在第一支 shell script 撰寫完畢之后,相信您應該具有基本的撰寫功力了。 接下來,在開始更深入的程序概念之前,我們先來玩一些比較有趣的簡單的小范例好了。 底下的范例中,達成結果的方式相當的多,建議您先自行撰寫看看,寫完之后再與鳥哥寫的內容比對, 這樣才能更加深概念喔!好!不啰唆,我們就一個一個來玩吧!


--------------------------------------------------------------------------------

變量內容由使用者決定?
很多時候我們需要使用者輸入一些內容,好讓程序可以順利運作。 簡單的來說,大家應該都有安裝過軟件的經驗,安裝的時候,他不是會問您『要安裝到那個目錄去?』嗎? 那個讓使用者輸入的數據的動作,就是讓使用者輸入變量內容啦。

你應該還記得在 bash 的時候,我們有學到一個 read 指令吧?忘記的話,請自行回頭去閱讀一番。 現在,請你以 read 指令的用途,撰寫一個 script ,他可以讓使用者輸入:1 first name 與 2. last name, 最后并且在屏幕上顯示:『Your full name is: 』的內容:
[root@linux scripts]# vi sh02.sh
#!/bin/bash
# Program:
#? Let user keyin their first and last name, and show their full name.
# History:
# 2005/08/23 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input your first name: " firstname
read -p "Please input your last name:? " lastname
echo -e "/nYour full name is: $firstname $lastname"

?
將上面這個 sh02.sh 執行一下,你就能夠發現使用者自己輸入的變量可以被取用的哩! 很不錯吧!加油!

?

--------------------------------------------------------------------------------

利用 date 進行檔案的建立?
想象一個狀況,如果我每天要進行備份,而備份的數據又不想被覆蓋掉,也就是說, 我想要將每天備份的數據放在不同的檔案中。哇!這真困擾啊?難道要我每天去修改 script ? 不需要啊!因為每天的『日期』并不相同,所以我可以將檔名取成類似: backup.20050802 , 不就可以每天一個不同檔名了嗎?呵呵!確實如此。好了,接下來出個例子: 我想要建立三個空的檔案,檔名最開頭由使用者輸入決定,假設使用者輸入 filename 好了, 那今天的日期是 2005/08/23 ,我想要以前天、昨天、今天的日期來建立這個檔案,亦即 filename_20050821, filename_20050822, filename_20050823 ,該如何是好?
[root@linux scripts]# vi sh03.sh
#!/bin/bash
# Program:
#? User can keyin filename to touch 3 new files.
# History:
# 2005/08/23 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1. 讓使用者輸入文件名稱,并取得 fileuser 這個變量;
echo -e "I will use 'touch' command to create 3 files."
read -p "Please input the filename what you want: " fileuser

# 2. 為了避免使用者隨意按 Enter ,利用變量功能分析文件名是否有設定?
filename=${fileuser:-"filename"}

# 3. 開始利用 date 指令來取得所需要的檔名了;
date1=`date --date='2 days ago' +%Y%m%d`
date2=`date --date='1 days ago' +%Y%m%d`
date3=`date +%Y%m%d`
file1="$filename""$date1"
file2="$filename""$date2"
file3="$filename""$date3"

# 4. 將檔名建立吧!
touch $file1
touch $file2
touch $file3

?
我透過一些簡單的動作,這些動作都可以在 bash 那一章里面找到, 包括小指令 (`) 的取得訊息、變量的設定功能、變量的累加以及利用 touch 指令輔助! 如果您開始執行這個 sh03.sh 之后,你可以進行兩次輸入,一次直接按 [Enter] 來查閱檔名是啥? 一次可以輸入一些字符,這樣來判斷你的檔案喔!關于 date 的指令應用,請 man date 吧! ^_^

?

--------------------------------------------------------------------------------

數值運算的方法?
各位看官應該還記得,我們可以使用 declare 來定義變量的類型吧?! 這樣才能夠進行加減運算啊!可惜的是, bash shell 里頭預設僅支持到整數的數據。 OK!那我們來玩玩看,如果我們要使用者輸入兩個變量,然后將兩個變量的內容相乘, 最后輸出相乘的結果,那可以怎么做?
[root@linux scripts]# vi sh04.sh
#!/bin/bash
# Program:
#? User can input 2 integer to cross by!
# History:
# 2005/08/23 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "You SHOULD input 2 number, I will cross they! /n"
read -p "first number:? " firstnu
read -p "second number: " secnu
total=$(($firstnu*$secnu))
echo -e "/nThe number $firstnu x $secnu is ==> $total"

?
在數字的運算上,我們可以使用『 declare -i total=$firstnu*$secnu 』 也可以使用上面的方式來進行!基本上,鳥哥比較建議使用這樣的方式來進行運算:?
var=$((運算內容))
不但容易記憶,而且也比較方便的多~未來您可以使用這種方式來計算的呀!至于數值運算上的處理, 則有:+, -, *, /, %等等。 那個 % 是取余數啦~舉例來說, 13 對 3 取余數,結果是 13=4*3+1,所以余數是 1 啊!就是:
[root@linux scripts]# nu=$((13%3)); echo $nu
1

?
這樣了解了吧?!多多學習與應用喔! ^_^


--------------------------------------------------------------------------------
善用判斷式

在 bash 章節中,我們提到過 $? 這個變量所代表的意義, 此外,也透過 && 及 || 來作為前一個指令是否能夠成功進行的一個參考。 那么,如果我想要知道 /dmtsai 這個目錄是否存在時,難道一定要使用 ls 來執行, 然后再以 $? 來判斷執行成果嗎?呵呵!當然不需要! 我們可以透過『 test 』這個指令來偵測呢!


--------------------------------------------------------------------------------
利用 test 指令的測試功能

當我要檢測系統上面某些檔案或者是相關的屬性時,利用 test 這個指令來工作, 真是好用得不得了,舉例來說,我要檢查 /dmtsai 是否存在時,使用:
[root@linux ~]# test -e /dmtsai

?
執行結果并不會顯示任何訊息,但最后我們可以透過 $? 或 && 及 || 來展現整個結果呢! 例如我們在將上面的例子改寫成這樣:
[root@linux ~]# test -e /dmtsai && echo "exist" || echo "Not exist"

?
最終的結果可以告知我們是『exist』還是『Not exist』呢!那我知道 -e 是測試一個『東西』在不在, 如果還想要測試一下該檔名是啥玩意兒時,還有哪些標志可以來判斷的呢?呵呵!有底下這些東西喔!

測試的標志 代表意義?
1. 關于某個檔名的『類型』偵測(存在與否),如 test -e filename?
-e 該『檔名』是否存在?(常用)?
-f 該『檔名』是否為檔案(file)?(常用)?
-d 該『文件名』是否為目錄(directory)?(常用)?
-b 該『檔名』是否為一個 block device 裝置??
-c 該『檔名』是否為一個 character device 裝置??
-S 該『檔名』是否為一個 Socket 檔案??
-p 該『檔名』是否為一個 FIFO (pipe) 檔案??
-L 該『檔名』是否為一個連結檔??
2. 關于檔案的權限偵測,如 test -r filename?
-r 偵測該檔名是否具有『可讀』的屬性??
-w 偵測該檔名是否具有『可寫』的屬性??
-x 偵測該檔名是否具有『可執行』的屬性??
-u 偵測該文件名是否具有『SUID』的屬性??
-g 偵測該文件名是否具有『SGID』的屬性??
-k 偵測該文件名是否具有『Sticky bit』的屬性??
-s 偵測該檔名是否為『非空白檔案』??
3. 兩個檔案之間的比較,如: test file1 -nt file2?
-nt (newer than)判斷 file1 是否比 file2 新?
-ot (older than)判斷 file1 是否比 file2 舊?
-ef 判斷 file2 與 file2 是否為同一檔案,可用在判斷 hard link 的判定上。 主要意義在判定,兩個檔案是否均指向同一個 inode 哩!?
4. 關于兩個整數之間的判定,例如 test n1 -eq n2?
-eq 兩數值相等 (equal)?
-ne 兩數值不等 (not equal)?
-gt n1 大于 n2 (greater than)?
-lt n1 小于 n2 (less than)?
-ge n1 大于等于 n2 (greater than or equal)?
-le n1 小于等于 n2 (less than or equal)?
5. 判定字符串的數據?
test -z string 判定字符串是否為 0 ?若 string 為空字符串,則為 true?
test -n string 判定字符串是否非為 0 ?若 string 為空字符串,則為 false。
注: -n 亦可省略?
test str1 = str2 判定 str1 是否等于 str2 ,若相等,則回傳 true?
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,則回傳 false?
6. 多重條件判定,例如: test -r filename -a -x filename?
-a (and)兩狀況同時成立!例如 test -r file -a -x file,則 file 同時具有 r 與 x 權限時,才回傳 true。?
-o (or)兩狀況任何一個成立!例如 test -r file -o -x file,則 file 具有 r 或 x 權限時,就可回傳 true。?
! 反相狀態,如 test ! -x file ,當 file 不具有 x 時,回傳 true?

OK!現在我們就利用 test 來幫我們寫幾個簡單的例子。首先,判斷一下, 讓使用者輸入一個檔名,我們判斷:
這個檔案是否存在,若不存在則給予一個『Filename does not exist』的訊息,并中斷程序;?
若這個檔案存在,則判斷他是個檔案或目錄,結果輸出『Filename is regular file』或 『Filename is directory』?
判斷一下,執行者的身份對這個檔案或目錄所擁有的權限,并輸出權限數據!
你可以先自行創作看看,然后再跟底下的結果討論討論。注意利用 test 與 && 還有 || 等標志!
[root@linux scripts]# vi sh05.sh
#!/bin/bash
# Program:
#? Let user input a filename, the program will search the filename
# 1.) exist? 2.) file/directory? 3.) file permissions?
# History:
# 2005/08/25 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1. 讓使用者輸入檔名,并且判斷使用者是否真的有輸入字符串?
echo -e "The program will show you that filename is exist which input by you./n/n"
read -p "Input a filename : " filename
test -z $filename && echo "You MUST input a filename." && exit 0
# 2. 判斷檔案是否存在?
test ! -e $filename && echo "The filename $filename DO NOT exist" && exit 0
# 3. 開始判斷檔案類型與屬性
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
# 4. 開始輸出信息!
echo "The filename: $filename is a $filetype"
echo "And the permission are : $perm"

?
很有趣的例子吧!您可以自行再以其它的案例來撰寫一下可用的功能呢!

?

--------------------------------------------------------------------------------
利用判斷符號 [ ]

除了我們很喜歡使用的 test 之外,其實,我們還可以利用判斷符號『 [ ] 』來進行數據的判斷呢! 舉例來說,如果我想要知道 $HOME 這個變量是否為空的,可以這樣做:
[root@linux ~]# [ -z "$HOME" ]

?
但使用 [] 要特別注意的是,在上述的每個組件中間都需要有空格鍵來分隔,假設我空格鍵使用『□』來表示, 那么,在這些地方你都需要有空格鍵:
[? "$HOME"? ==? "$MAIL"? ]
[□"$HOME"□==□"$MAIL"□]
?↑?????? ↑? ↑?????? ↑

?
上面的例子在說明,兩個字符串 $HOME 與 $MAIL 是否相同的意思,相當于 test $HOME = $MAIL 的意思啦! 而如果沒有空白分隔,例如 [$HOME==$MAIL] 時,我們的 bash 就會顯示錯誤訊息了!這可要很注意啊! 所以說,您最好要注意:
在中括號 [] 內的每個組件都需要有空格鍵來分隔;?
在中括號內的變量,最好都以雙引號來設定;?
在中括號內的常數,最好都以單或雙引號來設定。
舉例來說,假如我設定了 name="VBird Tsai" ,然后這樣判定:
[root@linux ~]# name="VBird Tsai"
[root@linux ~]# [ $name == "VBird" ]
bash: [: too many arguments

?
為什么呢?因為 $name 如果沒有使用雙引號刮起來,那么上面的判定式會變成:?
[ VBird Tsai == "VBird" ]?
而不是我們要的:?
[ "VBird Tsai" == "VBird" ]?
這可是差很多的喔!另外,中括號的使用方法與標志與 test 幾乎一模一樣啊~ 只是中括號比較常用在條件判斷式 if ..... then ..... fi 的情況中就是了。 好,那我們也繼續來做一個小案例好了:
當執行一個程序的時候,這個程序會讓使用者選擇 Y 或 N ,?
如果使用者輸入 Y 或 y 時,就顯示『 OK, continue 』?
如果使用者輸入 n 或 N 時,就顯示『 Oh, interrupt !』?
如果不是 Y/y/N/n 之內的其它字符,就顯示『I don't know what is your choise』
利用中括號、 && 與 || 來繼續吧!
[root@linux scripts]# vi sh06.sh
#!/bin/bash
# Program:
#? This program will show the user's choice
# History:
# 2005/08/25 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input (Y/N): " yn
[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" && exit 0
[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" && exit 0
echo "I don't know what is your choise" && exit 0

?
很有趣吧!利用這個字符串判別的方法,我們就可以很輕松的將使用者想要進行的工作分門別類呢! 接下來,我們再來談一些其它有的沒有的東西吧!

Tips:
為什么判斷式里面下達等于要用 == 而不是一個 = 就好了呢?我們在前一章正規表示法里面的 awk 提到, 只有一個 = 用來給予一個變量設定其內容,邏輯判斷時,則會給予兩個等于, 亦即『比較』而非『設定』的意思~這里要好好的分辨一下喔! ^_^???


--------------------------------------------------------------------------------
Shell script 的預設變數($0, $1...)

其實,當我們執行一個 shell script 時,在這個 shell script 里面就已將幫我們做好一些可用的變量了。 舉例來說,在不久的將來,您就會發現,當我們要啟動一個系統服務時,可能會下達類似這樣的指令:
[root@linux ~]# /etc/init.d/crond restart

?
那是啥玩意兒?呵呵!就是『向 /etc/init.d/crond 這個 script 下達 restart 的指令』, 咦!我們不是都使用 read 來讀取使用者輸入的變量內容嗎?為啥我可以直接在 script 后面接上這個參數? 這是因為 shell script 幫我們設定好一些指定的變量了!變量的對應是這樣的:

/path/to/scriptname? opt1? opt2? opt3? opt4? ...
?????? $0???????????? $1??? $2??? $3??? $4?? ...

?
這樣夠清楚了吧?!執行的文件名為 $0 這個變量,第一個接的參數就是 $1 啊~ 所以,只要我們在 script 里面善用 $1 的話,就可以很簡單的立即下達某些指令功能了! 好了,來做個例子吧~假設我要執行一個 script ,執行后,該 script 會自動列出自己的檔名, 還有后面接的前三個參數,該如何是好?
[root@linux scripts]# vi sh07.sh
#!/bin/bash
# Program:
#? The program will show it's name and first 3 parameters.
# History:
# 2005/08/25 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "The script naem is ==> $0"
[ -n "$1" ] && echo "The 1st paramter is ==> $1" || exit 0
[ -n "$2" ] && echo "The 2nd paramter is ==> $2" || exit 0
[ -n "$3" ] && echo "The 3th paramter is ==> $3" || exit 0

?
這支程序里面鳥哥加上了一些控制式,亦即利用 && 及 || 來加以判斷 $1 ~ $3 是否存在? 若存在才顯示,若不存在就中斷~執行結果如下:
[root@linux scripts]# sh sh07.sh theone haha quot
The script naem is ==> sh07.sh
The 1st paramter is ==> theone
The 2nd paramter is ==> haha
The 3th paramter is ==> quot

?
上面這七的例子都很簡單吧?幾乎都是利用 bash 的相關功能而已~ 不難啦~底下我們就要使用條件判斷式來進行一些分別功能的設定了,好好瞧一瞧先~?

--------------------------------------------------------------------------------
條件判斷式:

只要講到『程序』的話,那么條件判斷式,亦即是『 if then 』這種判別式肯定一定要學習的! 因為很多時候,我們都必須要依據某些數據來判斷程序該如何進行。舉例來說,我們在上頭不是有練習當使用者輸入 Y/N 時,必須要執行不同的訊息輸出嗎?簡單的方式可以利用 && 與 || ,但如果我還想要執行一堆指令呢? 那真的得要 if then 來幫忙啰~底下我們就來聊一聊!


--------------------------------------------------------------------------------
利用 if .... then

這個 if .... then 是最常見的條件判斷式了~簡單的說,就是當符合某個條件判斷的時候, 就予以進行某項工作就是了。我們可以簡單的這樣看:
if [ 條件判斷式 ]; then
當條件判斷式成立時,可以進行的指令工作內容;
fi

?
至于條件判斷式的判斷方法,與前一小節的介紹相同啊!較特別的是,如果我有多個條件要判別時, 除了 sh06.sh 那個案例,也就是將多個條件寫入一個中括號內的情況之外, 我還可以有多個中括號來隔開喔!而括號與括號之間,則以 && 或 || 來隔開,他們的意義是:?
&& 代表 AND ;?
|| 代表 or ;
所以,在使用中括號的判斷式中, && 及 || 就與指令下達的狀態不同了。舉例來說, sh06.sh 那個例子我可以改寫成這樣:
[root@linux scripts]# vi sh06-2.sh
#!/bin/bash
# Program:
#? This program will show the user's choice
# History:
# 2005/08/25 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input (Y/N): " yn

if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK, continue"
exit 0
fi
if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh, interrupt!"
exit 0
fi
echo "I don't know what is your choise" && exit 0

?
不過,由這個例子看起來,似乎也沒有什么了不起吧? sh06.sh 還比較簡單呢~ 但是,如果我們考慮底下的狀態,您就會知道 if then 的好處了:
if [ 條件判斷式 ]; then
當條件判斷式成立時,可以進行的指令工作內容;
else
當條件判斷式不成立時,可以進行的指令工作內容;
fi

?
如果考慮更復雜的情況,則可以使用這個語法:
if [ 條件判斷式一 ]; then
當條件判斷式一成立時,可以進行的指令工作內容;
elif [ 條件判斷式二 ]; then
當條件判斷式二成立時,可以進行的指令工作內容;
else
當條件判斷式一與二均不成立時,可以進行的指令工作內容;
fi

?
那我就可以將 sh06-2.sh 改寫成這樣:
[root@linux scripts]# vi sh06-3.sh
#!/bin/bash
# Program:
#? This program will show the user's choice
# History:
# 2005/08/25 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input (Y/N): " yn

if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK, continue"
elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh, interrupt!"
else
echo "I don't know what is your choise"
fi

?
是否程序變得很簡單,而且依序判斷,可以避免掉重復判斷的狀況,這樣真的很容易設計程序的啦! ^_^ 好了,那么如果我要偵測你所輸入的參數是否為 hello 呢 , 也就是說,如果我想要知道,你在程序后面所接的第一個參數 (就是 $1 啊!) 是否為 hello ,
如果是的話,就顯示 "Hello, how are you ?";?
如果沒有加任何參數,就提示使用者必須要使用的參數下達法;?
而如果加入的參數不是 hello ,就提醒使用者僅能使用 hello 為參數。
整個程序的撰寫可以是這樣的:
[root@linux scripts]# vi sh08.sh
#!/bin/bash
# Program:
#? Show "Hello" from $1....
# History:
# 2005/08/28 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

if [ "$1" == "hello" ]; then
echo "Hello, how are you ?"
elif [ "$1" == "" ]; then
echo "You MUST input parameters, ex> $0 someword"
else
echo "The only parameter is 'hello'"
fi

?
然后您可以執行這支程序,分別在 $1 的位置輸入 hello, 沒有輸入與隨意輸入, 就可以看到不同的輸出啰~是否還覺得挺簡單的啊! ^_^。事實上, 學到這里,也真的很厲害了~好了,底下我們繼續來玩一些比較大一點的啰~ 我們在前一章已經學會了 grep 這個好用的玩意兒,那么多學一個叫做 netstat 的指令, 這個指令可以查詢到目前主機有開啟的網絡服務端口口 (service ports), 相關的功能我們會在服務器架設篇繼續介紹,這里您只要知道,我可以利用『 netstat -tuln 』來取得目前主機有啟動的服務, 而且取得的信息有點像這樣:
[root@linux ~]# netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address?? Foreign Address??? State
tcp??????? 0????? 0 0.0.0.0:199???? 0.0.0.0:*????????? LISTEN
tcp??????? 0????? 0 :::80?????????? :::*?????????????? LISTEN
tcp??????? 0????? 0 :::22?????????? :::*?????????????? LISTEN
tcp??????? 0????? 0 :::25?????????? :::*?????????????? LISTEN

?
上面的重點是特殊字體的那個部分,那些特殊字體的部分代表的就是 port 啰~ 那么每個 port 代表的意義為何呢?幾個常見的 port 與相關網絡服務的關系是:?
80: WWW?
22: ssh?
21: ftp?
25: mail
那我如何透過 netstat 去偵測我的主機是否有開啟這四個主要的網絡服務端口口呢? 我可以簡單的這樣去寫這個程序喔:
[root@linux scripts]# vi sh09.sh
#!/bin/bash
# Program:
#? Using netstat and grep to detect WWW,SSH,FTP and Mail services.
# History:
# 2005/08/28 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1. 先作一些告知的動作而已~
echo "Now, the services of your Linux system will be detect!"
echo -e "The www, ftp, ssh, and mail will be detect! /n"

# 2. 開始進行一些測試的工作,并且也輸出一些信息啰!
testing=`netstat -tuln | grep ":80 "`
if [ "$testing" != "" ]; then
echo "WWW is running in your system."
fi
testing=`netstat -tuln | grep ":22 "`
if [ "$testing" != "" ]; then
echo "SSH is running in your system."
fi
testing=`netstat -tuln | grep ":21 "`
if [ "$testing" != "" ]; then
echo "FTP is running in your system."
fi
testing=`netstat -tuln | grep ":25 "`
if [ "$testing" != "" ]; then
echo "Mail is running in your system."
fi

?
這樣又能夠一個一個的檢查啰~是否很有趣啊! ^_^。接下來,我們再來玩更難一點的。 我們知道可以利用 date 來顯示日期與時間,也可以利用 $((計算式)) 來計算數值運算。 另外, date 也可以用來顯示自 19710101 以來的『總秒數』 (請自行查閱 man date 及 info date) 。那么,您是否可以撰寫一支小程序,用來『計算退伍日期還剩幾天?』也就是說:
先讓使用者輸入他們的退伍日期;?
再由現在日期比對退伍日期;?
由兩個日期的比較來顯示『還需要幾天』才能夠退伍的字樣。
似乎挺難的樣子?其實也不會啦,利用『 date --date="YYYYMMDD" +%s 』就能夠達到我們所想要的啰~如果您已經寫完了程序,對照底下的寫法試看看:
[root@linux scripts]# vi sh10.sh
#!/bin/bash
# Program:
#? Tring to calculate your demobilization date at how many days?
# later...
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1. 告知使用者這支程序的用途,并且告知應該如何輸入日期格式?
echo "This program will try to calculate :"
echo "How many days about your demobilization date..."
read -p "Please input your demobilization date (YYYYMMDD ex>20050401): " date2

# 2. 測試一下,這個輸入的內容是否正確?利用正規表示法啰~
date_d=`echo $date2 |grep '[0-9]/{8/}'`
if [ "$date_d" == "" ]; then
echo "You input the wrong format of date...."
exit 1
fi

# 3. 開始計算日期啰~
declare -i date_dem=`date --date="$date2" +%s`
declare -i date_now=`date +%s`
declare -i date_total_s=$(($date_dem-$date_now))
declare -i date_d=$(($date_total_s/60/60/24))
if [ "$date_total_s" -lt "0" ]; then
echo "You had been demobilization before: " $((-1*$date_d)) " ago"
else
declare -i date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60))
echo "You will be demobilized after $date_d days and $date_h hours."
fi

?
瞧一瞧,這支程序可以幫您計算退伍日期呢~如果是已經退伍的朋友, 還可以知道已經退伍多久了~哈哈!很可愛吧~利用 date 算出自 1971/01/01 以來的總秒數, 再與目前的總秒數來比對,然后以一天的總秒數 (60*60*24) 為基數去計算總日數, 就能夠得知兩者的差異了~瞧~全部的動作都沒有超出我們所學的范圍吧~ ^_^ 還能夠避免使用者輸入錯誤的數字,所以多了一個正規表示法的判斷式呢~ 這個例子比較難,有興趣想要一探究竟的朋友,可以作一下課后練習題 關于計算生日的那一題喔!~加油!

?

--------------------------------------------------------------------------------
利用 case ..... esac 判斷

上個小節提到的『 if .... then .... fi 』對于變量的判斷中, 是以比對的方式來分辨的,如果符合狀態就進行某些行為,并且透過較多層次 ( 就是 elif ... ) 的方式來進行多個變量的程序代碼撰寫,譬如 sh08.sh 那個小程序,就是用這樣的方式來的啰。 好,那么萬一我有多個既定的變量內容,例如 sh08.sh 當中,我所需要的變量就是 "hello" 及空字符串兩個, 那么我只要針對這兩個變量來設定狀況就好了對吧?!那么可以使用什么方式來設計呢? 呵呵~就用 case ... in .... esac 吧~,他的語法如下:
case $變量名稱 in
? "第一個變量內容")
程序段
;;
? "第二個變量內容")
程序段
;;
? *)
不包含第一個變量內容與第二個變量內容的其它程序執行段
exit 1
;;
esac

?
要注意的是,這個語法是以 case 為開頭,而以 esac 為結尾,啥?為何是 esac 呢?想一想,既然 if 的結尾是 fi ,那么 case 的結尾當然就是將 case 倒著寫,自然就是 esac 啰~ ^_^,很好記吧~ 另外,每一個變量內容的程序段最后都需要兩個分號 (;;) 來代表該程序段落的結束,這挺重要的喔! 至于為何需要有 * 這個變量內容在最后呢?這是因為,如果使用者不是輸入變量內容一或二時, 我們可以告知使用者相關的信息啊!舉例來說,我們如果將 sh08.sh 改寫的話, 他應該會變成這樣喔!
[root@linux scripts]# vi sh08-2.sh
#!/bin/bash
# Program:
#? Show "Hello" from $1.... by using case .... esac
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

case $1 in
? "hello")
echo "Hello, how are you ?"
;;
? "")
echo "You MUST input parameters, ex> $0 someword"
;;
? *)
echo "Usage $0 {hello}"
;;
esac

?
在上面這個 sh08-2.sh 的案例當中,如果你輸入『 sh sh08-2.sh test 』來執行, 那么屏幕上就會出現『Usage sh08-2.sh {hello}』的字樣,告知執行者僅能夠使用 hello 喔~ 這樣的方式對于需要某些固定字符串來執行的變量內容就顯的更加的方便呢? 這種方式您真的要熟悉喔!這是因為系統的很多服務的啟動 scripts 都是使用這種寫法的, 舉例來說,我們 Linux 的服務啟動放置目錄是在 /etc/init.d/ 當中,我已經知道里頭有個 syslog 的服務,我想要重新啟動這個服務,可以這樣做:?
/etc/init.d/syslog restart
重點是那個 restart 啦~如果您進入 /etc/init.d/syslog 就會看到他使用的是 case 語法, 并且會規定某些既定的變量內容,你可以直接下達 /etc/init.d/syslog , 該 script 就會告知你有哪些后續接的變量可以使用啰~方便吧! ^_^

一般來說,使用『 case $變量 in 』這個語法中,當中的那個 $變量 大致有兩種取得的方式:
直接下達式:例如上面提到的,利用『 script.sh variable 』 的方式來直接給予 $1 這個變量的內容,這也是在 /etc/init.d 目錄下大多數程序的設計方式。?
交互式:透過 read 這個指令來讓使用者輸入變量的內容。
這么說或許您的感受性還不高,好,我們直接寫個程序來玩玩:讓使用者能夠輸入 one, two, three , 并且將使用者的變量顯示到屏幕上,如果不是 one, two, three 時,就告知使用者僅有這三種選擇。
[root@linux scripts]# vi sh11.sh
#!/bin/bash
# Program:
#? Let user input one, two, three and show in screen.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "This program will print your selection !"
# read -p "Input your choice: " choice
# case $choice in
case $1 in
? "one")
echo "Your choice is ONE"
;;
? "two")
echo "Your choice is TWO"
;;
? "three")
echo "Your choice is THREE"
;;
? *)
echo "Usage {one|two|three}"
;;
esac

?
此時,您可以使用『 sh sh11.sh two 』的方式來下達指令,就可以收到相對應的響應了。 上面使用的是直接下達的方式,而如果使用的是交互式時,那么將上面第 10, 11 行的 "#" 拿掉, 并將 12 行加上批注 (#),就可以讓使用者輸入參數啰~這樣是否很有趣啊?!

?

--------------------------------------------------------------------------------
利用 function 功能

什么是『函數 (function)』功能啊?簡單的說,其實, 函數可以在 shell script 當中做出一個類似自訂執行指令的東西,最大的功能是, 可以簡化我們很多的程序代碼~舉例來說,上面的 sh11.sh 當中,每個輸入結果 one, two, three 其實輸出的內容都一樣啊~那么我就可以使用 function 來簡化了! function 的語法是這樣的:
function fname() {
程序段
}

?
那個 fname 就是我們的自訂的執行指令名稱~而程序段就是我們要他執行的內容了。 要注意的是,在 shell script 當中, function 的設定一定要在程序的最前面, 這樣才能夠在執行時被找到可用的程序段喔!好~我們將 sh11.sh 改寫一下:
[root@linux scripts]# vi sh11-2.sh
#!/bin/bash
# Program:
#? Let user input one, two, three and show in screen.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

function printit(){
echo -n "Your choice is "
}

echo "This program will print your selection !"
case $1 in
? "one")
printit; echo $1 | tr 'a-z' 'A-Z'
;;
? "two")
printit; echo $1 | tr 'a-z' 'A-Z'
;;
? "three")
printit; echo $1 | tr 'a-z' 'A-Z'
;;
? *)
echo "Usage {one|two|three}"
;;
esac

?
以上面的例子來說,我做了一個函數名稱為 printif ,所以,當我在后續的程序段里面, 只要執行 printit 的話,就表示我的 shell script 要去執行『 function printit .... 』 里面的那幾個程序段落啰! 當然啰,上面這個例子舉得太簡單了,所以您不會覺得 function 有什么好厲害的, 不過,如果某些程序代碼一再地在 script 當中重復時,這個 function 可就重要的多啰~ 不但可以簡化程序代碼,而且可以做成類似『模塊』的玩意兒,真的很棒啦!

另外, function 也是擁有內建變量的~他的內建變量與 shell script 很類似, 函數名稱代表示 $0 ,而后續接的變量也是以 $1, $2... 來取代的~ 這里很容易搞錯喔~因為『 function fname() { 程序段 } 』內的 $0, $1... 等等與 shell script 的 $0 是不同的。以上面 sh11-2.sh 來說,假如我下達:『 sh sh11-2.sh one 』 這表示在 shell script 內的 $1 為 "one" 這個字符串。但是在 printit() 內的 $1 則與這個 one 無關。 我們將上面的例子再次的改寫一下,讓您更清楚!
[root@linux scripts]# vi sh11-3.sh
#!/bin/bash
# Program:
#? Let user input one, two, three and show in screen.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

function printit(){
echo "Your choice is $1"
}

echo "This program will print your selection !"
case $1 in
? "one")
printit 1
;;
? "two")
printit 2
;;
? "three")
printit 3
;;
? *)
echo "Usage {one|two|three}"
;;
esac

?
在上面的例子當中,如果您輸入『 sh sh11-3.sh one 』就會出現『 Your choice is 1 』的字樣~ 為什么是 1 呢?因為在程序段落當中,我們是寫了『 printit 1 』那個 1 就會成為 function 當中的 $1 喔~ 這樣是否理解呢? function 本身其實比較困難一點,如果您還想要進行其它的撰寫的話。 不過,我們僅是想要更加了解 shell script 而已,所以,這里看看即可~了解原理就好啰~ ^_^?

--------------------------------------------------------------------------------
循環 (loop)

除了 if...then...fi 這種條件判斷式之外,循環可能是程序當中最重要的一環了~ 循環可以不斷的執行某個程序段落,直到使用者設定的條件達成為止。 所以,重點是那個『條件的達成』是什么。底下我們就來談一談:


--------------------------------------------------------------------------------
while do done, until do done

一般來說,循環最常見的就是底下這兩種狀態了:
while [ condition ]
do
程序段落
done

?
這種方式中, while 是『當....時』,所以,這種方式說的是『當 condition 條件成立時,就進行循環,直到 condition 的條件不成立才停止』的意思。
until [ condition ]
do
程序段落
done

?
這種方式恰恰與 while 相反,它說的是『當 condition 條件成立時,就終止循環, 否則就持續進行循環的程序段。』是否剛好相反啊~我們以 while 來做個簡單的練習好了。 假設我要讓使用者輸入 yes 或者是 YES 才結束程序的執行,否則就一直進行告知使用者輸入字符串。
[root@linux scripts]# vi sh12.sh
#!/bin/bash
# Program:
#? Use loop to try find your input.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

while [ "$yn" != "yes" ] && [ "$yn" != "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done

?
上面這個例題的說明是『當 $yn 這個變量不是 "yes" 且 $yn 也不是 "YES" 時,才進行循環內的程序。』 而如果 $yn 是 "yes" 或 "YES" 時,就會離開循環啰~那如果使用 until 呢?呵呵有趣啰~ 他的條件會變成這樣:
[root@linux scripts]# vi sh12-2.sh
#!/bin/bash
# Program:
#? Use loop to try find your input.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

until [ "$yn" == "yes" ] || [ "$yn" == "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done

?
仔細比對一下這兩個東西有啥不同喔! ^_^再來,如果我想要計算 1+2+3+....+100 這個數據呢? 利用循環啊~他是這樣的:
[root@linux scripts]# vi sh13.sh
#!/bin/bash
# Program:
#? Try to use loop to calculate the result "1+2+3...+100"
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

s=0
i=0
while [ "$i" != "100" ]
do
i=$(($i+1))
s=$(($s+$i))
done
echo "The result of '1+2+3+...+100' is ==> $s"

?
嘿嘿!當您執行了『 sh sh13.sh 』之后,就可以得到 5050 這個數據才對啊!這樣瞭呼~ 那么讓您自行做一下,如果想要讓使用者自行輸入一個數字,讓程序由 1+2+... 直到您輸入的數字為止, 該如何撰寫呢?應該很簡單吧?!答案可以參考一下習題練習里面的一題喔!

?

--------------------------------------------------------------------------------
for...do....done

相對于 while, until 的循環方式是必須要『符合某個條件』的狀態, for 這種語法,則是『 已經知道要進行幾次循環』的狀態!他的語法是:
for (( 初始值; 限制值; 執行步階 ))
do
程序段
done

?
這種語法適合于數值方式的運算當中,在 for 后面的括號內的三串內容意義為:
初始值:某個變量在循環當中的起始值,直接以類似 i=1 設定好;?
限制值:當變量的值在這個限制值的范圍內,就繼續進行循環。例如 i<=100;?
執行步階:每作一次循環時,變量的變化量。例如 i=i+1。
值得注意的是,在『執行步階』的設定上,如果每次增加 1 ,則可以使用類似『i++』的方式,亦即是 i 每次循環都會增加一的意思。好,我們以這種方式來進行 1 累加到 100 的循環吧!
[root@linux scripts]# vi sh14.sh
#!/bin/bash
# Program:
#? Try do calculate 1+2+....+100
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

s=0
for (( i=1; i<=100; i=i+1 ))
do
s=$(($s+$i))
done
echo "The result of '1+2+3+...+100' is ==> $s"

?
一樣也是很簡單吧!利用這個 for 則可以直接限制循環要進行幾次呢!這么好用的東西難道只能在數值方面動作? 當然不是啦~我們還可以利用底下的方式來進行非數字方面的循環運作喔!
for $var in con1 con2 con3 ...
do
程序段
done

?
以上面的例子來說,這個 $var 的變量內容在循環工作時:
第一次循環時, $var 的內容為 con1 ;?
第二次循環時, $var 的內容為 con2 ;?
第三次循環時, $var 的內容為 con3 ;?
....
我們可以做個簡單的練習。假設我有三種動物,分別是 dog, cat, elephant 三種, 我想每一行都輸出這樣:『There are dogs...』之類的字樣,則可以:
[root@linux scripts]# vi sh15.sh
#!/bin/bash
# Program:
#? Using for .... loop to print 3 animal?
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

for animal in dog cat elephant
do
echo "There are ""$animal""s.... "
done

?
很簡單是吧! ^_^。好了,那么如果我想要讓使用者輸入某個目錄, 然后我找出某目錄內的文件名的權限呢?又該如何是好?呵呵!可以這樣做啦~
[root@linux scripts]# vi sh16.sh
#!/bin/bash
# Program:
#? let user input a directory and find the whole file's permission.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1. 先看看這個目錄是否存在啊?
read -p "Please input a directory: " dir
if [ "$dir" == "" ] || [ ! -d "$dir" ]; then
echo "The $dir is NOT exist in your system."
exit 1
fi

# 2. 開始測試檔案啰~
filelist=`ls $dir`
for filename in $filelist
do
perm=""
test -r "$dir/$filename" && perm="$perm readable"
test -w "$dir/$filename" && perm="$perm writable"
test -x "$dir/$filename" && perm="$perm executable"
echo "The file $dir/$filename's permission is $perm "
done

?
呵呵!很有趣的例子吧~利用這種方式,您可以很輕易的來處理一些檔案的特性呢~ 我們循環就介紹到這里了~其它更多的應用,就得視您的需求來玩啰~。?

--------------------------------------------------------------------------------
shell script 的追蹤與 debug

scripts 在執行之前,最怕的就是出現問題了!那么我們如何 debug 呢?有沒有辦法不需要透過直接執行該 scripts 就可以來判斷是否有問題呢!?呵呵! 當然是有的!我們就直接以 bash 的相關參數來進行判斷吧!
[root@linux ~]# sh [-nvx] scripts.sh
參數:
-n? :不要執行 script,僅查詢語法的問題;
-v? :再執行 sccript 前,先將 scripts 的內容輸出到屏幕上;
-x? :將使用到的 script 內容顯示到屏幕上,這是很有用的參數!
范例:

范例一:測試 sh16.sh 有無語法的問題?
[root@linux ~]# sh -n sh16.sh?
# 若語法沒有問題,則不會顯示任何信息!

范例二:將 sh15.sh 的執行過程全部列出來~
[root@linux ~]# sh -x sh15.sh?
+ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/home/vbird/bin
+ export PATH
+ for animal in dog cat elephant
+ echo 'There are dogs.... '
There are dogs....
+ for animal in dog cat elephant
+ echo 'There are cats.... '
There are cats....
+ for animal in dog cat elephant
+ echo 'There are elephants.... '
There are elephants....
# 使用 -x 真的是追蹤 script 的好方法,他可以將所有有執行的程序段在執行前列出來,
# 如果是程序段落,則輸出時,最前面會加上 + 字號,表示他是程序代碼而已,
# 實際的輸出則與 standard output 有關啊~如上所示。

?
在上面的范例二當中,我們可以透過這個簡單的參數 -x 來達成 debug 的目的,這可是一個不可多得的參數, 通常如果您執行 script 卻發生問題時,利用這個 -x 參數,就可以知道問題是發生在哪一行上面了!

熟悉 sh 的用法,將可以使您在管理 Linux 的過程中得心應手!至于在 Shell scripts 的學習方法上面,需要『多看、多模仿、并加以修改成自己的樣式!』 是最快的學習手段了!網絡上有相當多的朋友在開發一些相當有用的 scripts ,若是您可以將對方的 scripts 拿來,并且改成適合自己主機的樣子!那么學習的效果會是最快的呢!

另外,我們 Linux 系統本來就有很多的啟動 script ,如果您想要知道每個 script 所代表的功能是什么? 可以直接以 vi 進入該 script 去查閱一下,通常立刻就知道該 script 的目的了。 舉例來說,我們的 Linux 里頭有個文件名稱為: /etc/init.d/portmap ,這個 script 是干嘛用的? 利用 vi 去查閱最前面的幾行字,他出現如下信息:
# description: The portmapper manages RPC connections, which are used by /
#????????????? protocols such as NFS and NIS. The portmap server must be /
#????????????? running on machines which act as servers for protocols which /
#????????????? make use of the RPC mechanism.
# processname: portmap

?
簡單的說,他是被用在 NFS 與 NIS 上面的一個啟動 RPC 的 script , 然后我們再利用 http://www.google.com.tw 去搜尋一下 NFS, NIS 與 RPC , 立刻就能夠知道這個 script 的功能啰~所以,下次您發現不明的 script 時, 如果是系統提供的,那么利用這個檢查的方式,一定可以約略了解的啦! 加油的啰~ ^_^

另外,本章所有的范例都可以在 http://linux.vbird.org/linux_basic/0340bashshell-scripts/scripts.tgz 里頭找到喔!加油~

?

--------------------------------------------------------------------------------
本章習題練習
( 要看答案請將鼠標移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )?
請建立一支 script ,當你執行該 script 的時候,該 script 可以顯示: 1. 你目前的身份 (用 whoami ) 2. 你目前所在的目錄 (用 pwd)?
#!/bin/bash
echo -e "Your name is ==> `whoami`"
echo -e "The current directory is ==> `pwd`"

請自行建立一支程序,該程序可以用來計算『您還有幾天可以過生日』啊???
#!/bin/bash
read -p "Pleas input your birthday (MMDD, ex> 0709): " bir
now=`date +%m%d`
if [ "$bir" == "$now" ]; then
echo "Happy Birthday to you!!!"
elif [ "$bir" -gt "$now" ]; then
year=`date +%Y`
total_d=$(($((`date --date="$year$bir" +%s`-`date +%s`))/60/60/24))
echo "Your birthday will be $total_d later"
else
year=$((`date +%Y`+1))
total_d=$(($((`date --date="$year$bir" +%s`-`date +%s`))/60/60/24))
echo "Your birthday will be $total_d later"
fi

讓使用者輸入一個數字,程序可以由 1+2+3... 一直累加到使用者輸入的數字為止。?
#!/bin/bash
read -p "Please input an integer number: " number
i=0
s=0
while [ "$i" != "$number" ]
do
i=$(($i+1))
s=$(($s+$i))
done
echo "the result of '1+2+3+...$number' is ==> $s"

撰寫一支程序,他的作用是: 1.) 先查看一下 /root/test/logical 這個名稱是否存在; 2.) 若不存在,則建立一個檔案,使用 touch 來建立,建立完成后離開; 3.) 如果存在的話,判斷該名稱是否為檔案,若為檔案則將之刪除后建立一個檔案,檔名為 logical ,之后離開; 4.) 如果存在的話,而且該名稱為目錄,則移除此目錄!?
#!/bin/bash
if [ ! -e logical ]; then
touch logical
echo "Just make a file logical"
exit 1
elif [ -e logical ] && [ -f logical ]; then
rm logical
mkdir logical
echo "remove file ==> logical"
echo "and make directory logical"
exit 1
elif [ -e logical ] && [ -d logical ]; then
rm -rf logical
echo "remove directory ==> logical"
exit 1
else
echo "Does here have anything?"
fi

我們知道 /etc/passwd 里面以 : 來分隔,第一欄為賬號名稱。請寫一只程序,可以將 /etc/passwd 的第一欄取出,而且每一欄都以一行字符串『The 1 account is "root" 』來顯示,那個 1 表示行數。?
#!/bin/bash
accounts=`cat /etc/passwd | cut -d':' -f1`
for account in $accounts
do
declare -i i=$i+1
echo "The $i account is /"$account/" "
done

http://www.chinaunix.net/jh/24/628472.html

總結

以上是生活随笔為你收集整理的shell 生活0806012145的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

久久免费国产精品1 | 网站你懂的 | 亚洲专区在线 | 日本性生活免费看 | av直接看| 99久久婷婷国产综合精品 | 一区二区精品久久 | 午夜av电影 | 亚洲精品国产区 | 日韩精品高清视频 | 国产伦理久久精品久久久久_ | 丁香婷婷色 | 国产成人精品在线播放 | 国产精品a久久久久 | 中文字幕人成乱码在线观看 | 欧美性色综合网站 | 国产成人在线看 | 主播av在线 | 天天做日日做天天爽视频免费 | 久久成人精品电影 | 日韩在线观看视频网站 | 国产成人精品电影久久久 | 欧美日韩在线观看一区 | 人人澡人人爱 | 丁香 久久 综合 | 偷拍久久久 | 免费在线电影网址大全 | 日日干夜夜爱 | 91在线麻豆 | 免费能看的黄色片 | 公开超碰在线 | 欧美黑人巨大xxxxx | 在线观看91av | 免费福利片2019潦草影视午夜 | www狠狠| 色吊丝在线永久观看最新版本 | 日本aaa在线观看 | 三级视频国产 | 久久国色夜色精品国产 | 日韩高清 一区 | 五月婷视频 | 国产精品久久久久9999吃药 | 九九九九色 | 精品国产乱码久久久久 | 亚洲精品网页 | 婷婷久久一区 | 婷婷色综合网 | 天天射天天操天天 | 免费看黄色小说的网站 | 黄色大片免费网站 | 日韩a免费 | av片免费播放 | 国产黄色片在线免费观看 | 免费在线色 | 91精品国产麻豆国产自产影视 | 在线观看日韩免费视频 | 一区 二区 精品 | 成人av久久 | 美女视频黄在线 | 国产精品18久久久 | 久草在线这里只有精品 | 免费在线观看av片 | 成人a在线观看高清电影 | 久久视频免费在线 | 精品久久久久久一区二区里番 | 超碰国产在线观看 | 黄色资源在线观看 | 久久99视频免费观看 | 狠狠狠狠狠操 | 99色在线 | 超薄丝袜一二三区 | 久精品视频 | 99精品一区二区三区 | 欧美精品在线一区二区 | 久久综合天天 | 久久精品九色 | 欧美视频在线观看免费网址 | 精品国产成人av | 91免费高清视频 | 黄色免费高清视频 | 激情综合中文娱乐网 | 国内精品久久久久久久久 | 国产一区二区在线播放视频 | 天堂av在线免费观看 | 91精品啪 | 午夜成人影视 | 国产精品久久久久久一二三四五 | 久久亚洲二区 | 玖玖在线观看视频 | 免费日p视频| 日韩三级在线 | 亚洲视频 一区 | 香蕉在线视频播放网站 | 日韩av专区 | 波多野结衣电影一区 | 久久亚洲婷婷 | 国内精品久久久久影院一蜜桃 | 992tv在线观看网站 | 在线观看岛国av | 欧美一级特黄aaaaaa大片在线观看 | 黄色免费视频在线观看 | 久久精品视频免费观看 | 小草av在线播放 | 九九九九精品 | 国产精品久久一 | 能在线看的av| 国产原创中文在线 | 久久久久久综合 | 精品国产成人在线 | 久久久91精品国产一区二区精品 | 99久久精品久久久久久清纯 | 99色视频 | 久久精品国产亚洲a | 久久草视频| 超碰在97 | 国产97色在线| 久久免费视频在线观看30 | 蜜臀aⅴ国产精品久久久国产 | 国产黄色a| 中日韩在线视频 | 久久se视频| 国产aaa大片 | 成人精品久久久 | 最新国产一区二区三区 | 狠狠操影视 | 亚洲 欧洲av | www日日| 国产尤物视频在线 | 国产精品成人品 | 亚洲精品综合欧美二区变态 | 欧美精品久久久久久久久久 | 国产精品你懂的在线观看 | 免费亚洲一区二区 | 久久久久国产精品午夜一区 | 美女视频一区二区 | 精品在线观看免费 | 日韩高清免费电影 | 欧美一区成人 | 欧美精彩视频在线观看 | 亚洲成aⅴ人片久久青草影院 | 久久久久久久久久影院 | 白丝av免费观看 | 999久久久久 | 成人四虎 | 国产高清网站 | 免费的黄色的网站 | 91在线视频免费观看 | 免费看成年人 | 一区久久久| 天天爽天天搞 | 中文字幕在线免费观看 | 丁香资源影视免费观看 | 国产黄色片免费 | 国产精品美女999 | 精品三级av | 日本精品视频一区二区 | 69精品久久久 | 精品专区 | 久久久久免费精品国产小说色大师 | 手机看片| 亚洲区另类春色综合小说校园片 | 美女网站视频免费都是黄 | 91传媒激情理伦片 | 天天做天天爱夜夜爽 | 亚洲涩涩涩| 免费视频97 | 九九视频在线观看视频6 | 国产一卡二卡在线 | 四虎在线影视 | 欧美日韩另类在线观看 | 久久99热这里只有精品国产 | 996久久国产精品线观看 | 国产精品久久久视频 | 精品国产免费一区二区三区五区 | 蜜桃麻豆www久久囤产精品 | 久久久国产精品麻豆 | 久草网视频在线观看 | 在线观看网站你懂的 | 欧美日韩高清 | 欧美91视频| 亚洲精品免费在线 | 亚洲成av人片在线观看www | 亚洲精品乱码白浆高清久久久久久 | 久久精品免费播放 | 日韩欧美精品一区 | 国产精品久久久久影院 | 日韩一二三在线 | 韩国精品在线观看 | 国产精品色婷婷 | 精品福利av | 亚洲国产精品小视频 | 干干夜夜| 国产精品专区h在线观看 | 麻花豆传媒mv在线观看网站 | 国产精品剧情在线亚洲 | 在线看黄色的网站 | 久久精品免费观看 | 久草网在线视频 | 欧美日韩精品免费观看 | 91麻豆精品国产午夜天堂 | 欧美日韩精品免费观看 | 91黄色免费看 | 中文字幕在线久一本久 | 黄色免费在线视频 | 丝袜制服综合网 | 成片人卡1卡2卡3手机免费看 | 99色人| 成人免费网站在线观看 | 久久久久免费精品 | 日韩欧美在线视频一区二区 | 91精品久久久久久综合乱菊 | 天堂在线视频免费观看 | 特级毛片在线免费观看 | 久久超 | 国产手机av在线 | 66av99精品福利视频在线 | 看毛片网站 | 国产精品黄 | 一区二区三区四区五区在线 | 日韩黄在线观看 | 免费国产一区二区 | 精品亚洲一区二区 | 成人午夜电影在线播放 | 在线观看网站av | 国产精品区一区 | 亚洲一级电影视频 | 久草久视频 | 国产黄色在线网站 | 五月婷婷六月丁香 | 在线免费观看麻豆视频 | 国产精品一区二区在线免费观看 | 国产精品久久久久久久久久ktv | 日韩精品免费一区二区三区 | 免费一级片在线观看 | 激情欧美一区二区三区免费看 | 婷婷丁香花五月天 | 夜夜躁日日躁狠狠躁 | 欧美男女爱爱视频 | 成年人网站免费观看 | 国产视频欧美视频 | 97精品免费视频 | 天堂网一区二区三区 | 国产中文字幕视频 | 在线午夜 | 色噜噜狠狠狠狠色综合久不 | 亚洲精品国偷拍自产在线观看蜜桃 | 日韩经典一区二区三区 | 激情五月看片 | 国产成人精品999在线观看 | 日韩av片无码一区二区不卡电影 | 日本视频精品 | 婷婷色狠狠 | 最新超碰| 超薄丝袜一二三区 | 欧美在线不卡一区 | 久久精品精品电影网 | 亚洲欧美日韩精品一区二区 | 免费av大全 | 亚洲理论影院 | 日韩av男人的天堂 | 视频在线观看一区 | 在线中文字幕播放 | 中文在线a∨在线 | 国产一级淫片免费看 | 狠狠操狠狠干天天操 | 黄色免费网站大全 | 欧美成年网站 | 久久呀| www日韩精品 | 中文字幕久久精品 | 精品国产伦一区二区三区观看方式 | 国产视频欧美视频 | 91视频88av| 日韩中文字幕a | 菠萝菠萝蜜在线播放 | 手机在线黄色网址 | 伊人国产女 | 国产精品一二 | 国产一级淫片免费看 | 国产麻豆成人传媒免费观看 | 中文在线天堂资源 | 天天爱天天操天天射 | 成人黄色电影在线 | 日韩一区二区三区在线观看 | 日韩av免费在线看 | 亚洲日本中文字幕在线观看 | 在线观看涩涩 | 激情片av | 在线国产福利 | 久久久久免费网 | 欧美在线一二区 | 色哟哟国产精品 | 在线视频亚洲 | 国精产品一二三线999 | 中文在线字幕免费观看 | 久久久久久久久久久电影 | 亚洲精品理论片 | 色综合中文字幕 | 日韩一二区在线观看 | 99精品视频在线免费观看 | 亚洲成人精品在线观看 | 久久区二区 | 国产麻豆视频网站 | 香蕉视频在线免费 | 国产精品成人一区二区三区吃奶 | 日韩免费一级a毛片在线播放一级 | 国产成人一区二区三区影院在线 | 视频在线日韩 | 新版资源中文在线观看 | 在线播放91 | 91精品国自产在线偷拍蜜桃 | 亚洲精品国产综合99久久夜夜嗨 | 91在线观看黄 | 久久精品亚洲综合专区 | 亚洲成a人片在线观看网站口工 | 超级碰碰碰免费视频 | 又黄又爽又色无遮挡免费 | 五月婷婷六月综合 | 色综合久久88色综合天天人守婷 | 日韩综合一区二区 | 久草在线电影网 | 精品久久一区二区三区 | 久草视频精品 | www.com黄 | av大全免费在线观看 | 五月婷婷操 | 欧美一进一出抽搐大尺度视频 | 精品一区二区免费在线观看 | 国产精品国产三级在线专区 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | 正在播放国产一区 | 黄色午夜网站 | 久久久免费播放 | 久久伊人91 | 九九视频精品免费 | 午夜视频一区二区 | 日韩精品视频网站 | 狠狠干夜夜爽 | 欧美成人va| 欧美精品色 | 日韩在线观看一区二区三区 | 一级全黄毛片 | 911免费视频| 欧美成人猛片 | 精品女同一区二区三区在线观看 | 丁香六月色 | 亚洲一区二区视频 | 在线成人高清电影 | 91亚洲影院 | 国产永久免费高清在线观看视频 | 国产精品久久久久永久免费 | 色吧av色av | 久久草精品 | 久久久久麻豆v国产 | 久草视频在线免费看 | 91精品免费看 | 欧美日本在线观看视频 | 天天操夜夜想 | 国产打女人屁股调教97 | 激情久久影院 | 亚洲欧美婷婷六月色综合 | 99视频网站 | 国产成人三级在线观看 | 狠狠综合| 中文在线a在线 | 欧洲亚洲精品 | www.国产精品| 国产色啪 | 欧美天堂影院 | 日韩| 亚洲精品资源在线 | 在线观看 亚洲 | 久久久久久草 | 91中文在线 | 日韩免费中文字幕 | 日韩午夜电影院 | 久久久久女人精品毛片九一 | 天天看天天干 | 在线观看视频免费大全 | 超碰在线人人 | 美女网站久久 | 国产精品久久久久久久7电影 | 久久久久久久久久影视 | 国产视频色 | 中文字幕在线观看视频一区 | 韩国视频一区二区三区 | 又黄又爽又色无遮挡免费 | 日日爱影视| 国产成人精品亚洲日本在线观看 | 18+视频网站链接 | 一本—道久久a久久精品蜜桃 | 国产精品乱码高清在线看 | 欧美日韩不卡一区二区三区 | 天天爱天天舔 | 国产亚洲精品电影 | 久久999久久 | 久久国产免费看 | 黄色三级在线观看 | 国产日韩欧美在线一区 | 国内精品久久久久影院优 | 国产精品九色 | 日韩精品久久久久久中文字幕8 | 免费黄色看片 | 色免费在线| 亚洲欧美精品一区二区 | 日日干夜夜爱 | 99人久久精品视频最新地址 | 日本在线观看一区 | 中文字幕不卡在线88 | 国产91小视频| 97伊人网 | 亚洲年轻女教师毛茸茸 | 午夜三级理论 | 精品一区二区三区久久 | 五月综合在线观看 | 伊人久久婷婷 | 欧美视频二区 | 国产高清视频免费观看 | 色插综合 | 九九视频精品在线 | 久久精品永久免费 | 色婷婷狠 | 狠狠狠狠狠操 | 8x8x在线观看视频 | 国产精品美女www爽爽爽视频 | 超碰97在线看 | 亚洲精品国产自产拍在线观看 | 日韩有码在线观看视频 | 日韩视频中文 | 欧美日韩一区二区三区在线观看视频 | 99亚洲视频| 亚洲欧洲成人 | 四虎国产精品成人免费影视 | aaa亚洲精品一二三区 | 521色香蕉网站在线观看 | 日韩欧美精品一区二区 | 国外av在线 | 在线观看91 | 欧美日韩一区二区在线 | 一级一片免费视频 | 毛片网站在线观看 | 91高清视频在线 | 色婷五月 | av综合站 | 国产视频综合在线 | 欧美一区二区三区在线 | 视频在线91 | 久久午夜网 | 日韩欧美精品在线 | 午夜精品久久久久99热app | 成人免费观看a | 中文av网站| 97电影在线看视频 | 国产高清成人在线 | 亚洲精品66 | 中文字幕成人在线 | 精品国产自在精品国产精野外直播 | 亚洲欧美偷拍另类 | 一本色道久久综合亚洲二区三区 | 五月开心激情 | 成人黄性视频 | 免费精品国产 | 日韩免费一区二区在线观看 | 伊人中文网 | 欧美男男tv网站 | 激情久久久 | 久久狠狠一本精品综合网 | 最新av在线免费观看 | 日韩电影精品一区 | 久久国产精品区 | 亚洲精品久久激情国产片 | 99视频久久 | 人人干人人干人人干 | 国产精品美 | 天天综合网天天综合色 | 在线视频第一页 | 狠狠伊人 | 午夜精品麻豆 | 99精品视频免费看 | 国产高清久久久久 | www久久九 | 日韩视频一区二区 | 91在线文字幕 | 国产成人精品一区二区三区福利 | 日日爱网站| 日韩三级免费观看 | 免费在线观看污网站 | 亚州精品在线视频 | 国产九九九九九 | 成人亚洲精品国产www | 黄色av网站在线免费观看 | 国产中文 | 欧美精品少妇xxxxx喷水 | 五月婷婷综合在线视频 | 国产亚洲精品久久久久久久久久 | 伊人午夜视频 | www.com.黄| 国产精品久久久久免费观看 | 亚洲一级黄色 | 亚洲午夜久久久久 | 97精品一区二区三区 | 日本黄色免费电影网站 | 91专区在线观看 | 一区二区三区四区五区在线视频 | 国产精品毛片一区视频播 | 黄色av一级 | 国产黄色播放 | 精品国产一区二区三区在线观看 | 国产精品麻豆99久久久久久 | 成人av电影网址 | 久久久久免费视频 | 九色精品免费永久在线 | 久99久中文字幕在线 | 日本精品久久久久中文字幕5 | 狠狠躁夜夜躁人人爽视频 | 久久精品亚洲一区二区三区观看模式 | 高清视频一区二区三区 | 在线观看中文字幕一区 | 日韩 在线观看 | 麻豆国产网站 | 蜜臀久久99精品久久久久久网站 | 精品一区二区免费 | 中国一区二区视频 | 久久9999久久免费精品国产 | 亚洲日本韩国一区二区 | 国产精品xxxx18a99 | 久久婷婷一区 | 久久久精品日本 | 人人要人人澡人人爽人人dvd | 国产精品久久久久毛片大屁完整版 | 9999免费视频 | 欧美日韩一级久久久久久免费看 | 亚洲综合视频在线 | 亚洲最新av在线网址 | 久久经典视频 | 久久久久久高潮国产精品视 | 日韩在观看线 | 992tv在线| 欧美国产视频在线 | 在线观看国产成人av片 | 国产精品成人在线观看 | 美女视频黄在线观看 | 欧美性生活久久 | www色片| 亚洲激情 在线 | 在线免费观看国产 | 色五月情 | av免费片 | 日韩高清精品一区二区 | 色偷偷88888欧美精品久久久 | 国产v视频 | 在线观看亚洲精品视频 | 免费网站色 | 91在线看黄| 日韩毛片久久久 | 亚洲午夜av久久乱码 | 色婷五月 | 亚洲春色奇米影视 | 亚洲视频h | 99精品国产99久久久久久97 | 久黄色| 国产精品美女久久久久久网站 | 午夜精品久久久99热福利 | www免费在线观看 | 亚洲激情综合网 | 182午夜在线观看 | 美腿丝袜一区二区三区 | 五月天激情在线 | 色婷五月天 | 久久9999久久免费精品国产 | 超碰大片 | 国产亚洲视频在线观看 | av电影 一区二区 | 丁香在线视频 | 99精品在线免费在线观看 | 久久久久五月 | 91成人午夜 | 日韩特级毛片 | 久久久黄视频 | 在线免费av网站 | 三级av免费观看 | av在线看网站 | 91精品啪在线观看国产 | 国产一级免费观看视频 | aaa黄色毛片 | 99免费视频 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 日日操夜夜操狠狠操 | 中文字幕888 | 亚洲综合日韩在线 | 精品久久久久亚洲 | 成人激情开心网 | 91av资源网| 成人9ⅰ免费影视网站 | 97超碰总站 | 日本久久高清视频 | 99 视频 高清 | 91免费试看 | 开心色插 | 超碰公开在线 | 国产 日韩 在线 亚洲 字幕 中文 | 国产成人精品一区二区三区网站观看 | 亚洲视频999| 婷婷性综合 | 91亚洲精| 久久草精品 | 麻豆影视在线播放 | 免费在线观看黄网站 | 亚洲精品动漫在线 | 五月花婷婷| 在线视频18在线视频4k | 日本午夜在线观看 | 久久久久在线观看 | 久久精品视频播放 | 成人av高清在线观看 | 欧美 亚洲 另类 激情 另类 | 国产亚洲精品久久网站 | 中文字幕资源在线观看 | 精品久久亚洲 | 免费毛片aaaaaa | 日韩一级精品 | 国产做aⅴ在线视频播放 | 亚洲色图 校园春色 | 久久精品国产成人 | 999精品 | japanesexxxhd奶水 国产一区二区在线免费观看 | 国产黄色播放 | 成年人在线视频观看 | 国产精品一区二区三区在线 | 日韩高清观看 | 中文字幕精品在线 | 在线视频观看成人 | 久久久综合香蕉尹人综合网 | 高清精品久久 | 亚洲第一成网站 | 在线观看免费91 | 99久久精品电影 | 欧美专区日韩专区 | 亚洲精品国产综合99久久夜夜嗨 | 亚洲久久视频 | 成人在线播放视频 | 天天插天天干天天操 | a v在线观看 | 国产日韩在线观看一区 | 日韩av网址在线 | 国产不卡在线观看 | sm免费xx网站 | 成人国产精品一区二区 | 在线观看完整版 | 麻豆一级视频 | 免费视频久久久久久久 | 国产精品福利一区 | 国产在线观看你懂的 | 日韩在线观看你懂的 | 日韩av网页 | 亚洲精品视频在线看 | 国产精品精品久久久久久 | 久久久久久久电影 | 国产aaa毛片| 欧美狠狠色 | 91毛片在线观看 | 色爽网站 | 色中文字幕在线观看 | 中文字幕 国产视频 | 六月天色婷婷 | 99热这里只有精品久久 | 99精品久久只有精品 | 精品国产一区二区三区日日嗨 | av在线观 | 狠狠操电影网 | 亚洲综合导航 | 奇米7777狠狠狠琪琪视频 | 国产福利一区在线观看 | 久久久久久免费网 | 国产第一页在线观看 | 亚州视频在线 | 国产不卡在线视频 | 亚洲精品乱码久久久久久蜜桃不爽 | 国产麻豆视频在线观看 | 久久久精品| 欧美一级片免费 | 国产一卡二卡四卡国 | 91看片在线免费观看 | 国产中文字幕视频 | 91麻豆精品国产91久久久使用方法 | 日韩免费电影在线观看 | 免费高清av在线看 | 狠狠干.com | 97人人超| 808电影| 狠狠狠狠狠狠狠狠 | 天天骚夜夜操 | 中文字幕 成人 | 丁香国产视频 | 国产在线成人 | 天天躁日日躁狠狠躁av中文 | 黄色小说视频在线 | 最近在线中文字幕 | av成人资源 | 成人免费av电影 | av不卡免费看 | 国产亚洲欧美精品久久久久久 | 亚洲精品美女久久 | 天天干夜夜爱 | 精品一区二区在线免费观看 | 看av免费网站| 婷婷丁香花五月天 | 麻豆91精品视频 | 精品一区二区日韩 | 色噜噜在线观看视频 | 黄色aaaaa| 在线激情电影 | 九九综合久久 | 免费三级大片 | 99在线观看免费视频精品观看 | 麻豆系列在线观看 | 青青河边草免费视频 | 欧美日韩另类在线 | 亚洲综合色丁香婷婷六月图片 | 色综合婷婷 | 午夜精品久久久久久久久久久久 | 久久精品成人 | 在线视频久 | 91精品日韩 | 91麻豆操 | 久久久久久久久久免费 | 最近免费观看的电影完整版 | 日韩中文字幕一区 | 狠狠色丁香 | 黄色视屏在线免费观看 | 久久99精品久久久久久清纯直播 | 久久另类小说 | 国产亚洲精品久久久久久网站 | 免费欧美精品 | 在线国产视频一区 | 国产第页 | 丝袜美腿在线视频 | 久久久久久久免费看 | 在线免费观看黄网站 | 免费网站污 | 国产精品丝袜久久久久久久不卡 | 免费av电影网站 | 国产午夜视频在线观看 | 日韩a级免费视频 | 色婷婷视频在线 | 成人在线播放网站 | 操高跟美女 | 丰满少妇一级 | 亚洲激情一区二区三区 | 国产日韩精品欧美 | 久久最新视频 | 香蕉视频在线视频 | 天天插狠狠干 | 看国产黄色大片 | 久久久久免费精品国产 | 天天爽天天搞 | 在线免费黄色片 | 国产在线视频资源 | 在线观看中文字幕av | 亚洲色图22p| 午夜久久久影院 | 白丝av免费观看 | 91桃色免费观看 | 狂野欧美激情性xxxx欧美 | 亚洲国产精品一区二区久久hs | 91成人蝌蚪| 国产一级二级在线观看 | 天天综合在线观看 | 久久色中文字幕 | 中文字幕在线一区观看 | 日本视频精品 | 99国产精品视频免费观看一公开 | 国产精品一区二区免费在线观看 | 免费在线一区二区三区 | 亚洲1级片 | 久久国产精品久久国产精品 | 在线蜜桃视频 | 成人影视免费看 | 玖玖精品在线 | 欧美日韩免费看 | 4438全国亚洲精品在线观看视频 | 精品国产伦一区二区三区观看体验 | 天天干.com | 久久精品美女 | 国产精品精品久久久 | 在线免费观看黄色小说 | 五月天色丁香 | 97人人澡人人爽人人模亚洲 | 成人av手机在线 | 欧美日在线观看 | 精品91视频 | 亚洲精品视频在线免费 | 在线黄色免费av | 久久久国产一区二区三区 | 欧美日韩在线精品一区二区 | 99热手机在线 | 国产高清在线a视频大全 | 久草爱 | 国产成人综合在线观看 | 超碰在线色 | 免费高清看电视网站 | 久久er99热精品一区二区 | 最新av观看 | 黄色日本免费 | 2017狠狠干 | 久久夜靖品 | 狠狠综合久久 | 国产一区福利在线 | 国产九九热视频 | 欧美成年人在线视频 | 欧美乱大交 | 国产精品久久久久久婷婷天堂 | 久久99亚洲精品久久久久 | 免费三级a | 色97在线 | av综合站 | 国产精品久久久久久影院 | 亚洲欧洲精品久久 | 91av播放 | 韩日av一区二区 | 国产一区二区中文字幕 | 久久综合九色综合久久久精品综合 | 国产成人精品电影久久久 | 日韩女同一区二区三区在线观看 | 日韩免费在线一区 | 91精品啪在线观看国产线免费 | 久久久天堂 | 黄色资源在线观看 | 青青草国产精品 | 亚洲成人精品在线观看 | 青青色影院 | 在线观看视频你懂的 | 综合网伊人 | 激情中文字幕 | 天天操狠狠操网站 | 91在线精品视频 | 在线日韩一区 | 又色又爽又黄高潮的免费视频 | 国产视频 亚洲视频 | 国产中文字幕视频在线观看 | 四虎成人精品在永久免费 | 91精品在线免费 | 国产亚洲免费观看 | 特级西西444www大胆高清无视频 | 国产精品av在线 | 黄色一级免费 | 亚洲国产中文字幕在线观看 | www.av免费 | 国产精品久久久毛片 | 国内精品亚洲 | 国产视频观看 | 亚洲成人黄色网址 | 亚洲国产成人久久综合 | 国产精品24小时在线观看 | 天堂在线一区二区三区 | 国产最新在线观看 | 精品96久久久久久中文字幕无 | 午夜精品一区二区三区在线播放 | 国产另类av | 国产一区二区久久精品 | 天天干天天干天天 | 日韩精品一区二区三区中文字幕 | 国产专区在线播放 | 日日干天天爽 | 青青草在久久免费久久免费 | 九九久久免费视频 | 久久国产精品免费一区二区三区 | 在线不卡a | 免费成人在线视频网站 | 精品国产免费人成在线观看 | 国产国产人免费人成免费视频 | 中文字幕一区在线观看视频 | 最近日本中文字幕a | 成人在线免费观看视视频 | 国产品久精国精产拍 | www.大网伊人 | 久草在线免费看视频 | 欧美黑吊大战白妞欧美 | 天天天天天操 | 色射爱 | 国产精品乱码久久 | 国产精品地址 | 国产丝袜高跟 | 婷婷激情av| 99久久精品免费看国产麻豆 | 国产五月天婷婷 | 国产黄色片久久久 | 在线韩国电影免费观影完整版 | 99久久综合国产精品二区 | 成人在线视频论坛 | 免费麻豆网站 | 手机在线黄色网址 | 久久天天操 | 国产精品一区二区三区99 | 日韩欧美在线视频一区二区三区 | 欧美日韩1区| 日韩不卡高清视频 | 91网页版在线观看 | 国产国语在线 | 免费看v片| av黄色在线播放 | 欧美一级乱黄 | 日韩视频一区二区三区在线播放免费观看 | 国产999 | 久久精品99国产国产精 | 五月在线视频 | 91精品夜夜| 91视频在线 | 中文字幕在线观看你懂的 | 国产成人一区二区三区在线观看 | 久久激情视频网 | 久久av免费观看 | 国产一级二级三级在线观看 | 国产精品久久久久久一区二区 | av大全在线播放 | 青青草国产精品视频 | 国产综合福利在线 | 久久久久久久国产精品视频 | av免费在线观看网站 | 成人在线观看日韩 | 国产69精品久久久久99 | 国内揄拍国内精品 | 一级淫片a | 亚洲国产网站 | 91精品国产91久久久久福利 | 99精彩视频在线观看免费 | 欧美视频日韩视频 | 国产一级大片在线观看 | 日韩高清 一区 | 91视频com | 精产嫩模国品一二三区 | 欧美三人交 | 久久无码av一区二区三区电影网 | 成年人免费在线观看网站 | 久久久2o19精品 | 国产久草在线 | 91色影院| 激情综合狠狠 | 国产精品专区在线 | 91在线影视 | 国产1区在线 | 在线看片一区 | 69国产精品视频免费观看 | 在线 成人 | 日韩免费在线网站 | 麻豆视频在线看 | 美女网站视频免费黄 | 伊人在线视频 | 欧美天堂久久 | 中文字幕欲求不满 | 96视频在线| 97在线视频免费 | 在线之家免费在线观看电影 | 97香蕉超级碰碰久久免费软件 | 国产在线1区 | 免费黄色av片| 国产一级片不卡 | 久草影视在线 | 国产黄色a | 91日韩国产 | 99久久精品久久久久久动态片 | 欧美精品免费在线 | 97精品久久| 久久久久久国产精品美女 | 亚洲国产一区二区精品专区 | 亚洲天堂网视频在线观看 | 免费在线观看成人小视频 | 国产精品免费看久久久8精臀av | 国产成人一区三区 | 亚洲撸撸 | 婷婷六月天综合 | 手机成人av在线 | 黄色在线看网站 | 亚洲天堂网站 | 久久超碰99 | 国产精品第10页 | 俺要去色综合狠狠 | 免费观看v片在线观看 | 午夜在线免费视频 | 亚洲成人精品影院 | 国产精品第一页在线观看 | 黄色大全免费网站 | 中文字幕在线免费观看视频 | 最新三级在线 | 精品一区av | 中文字幕日韩高清 | 久黄色 | 成人精品999 | 91九色精品女同系列 | 在线观看 国产 | 色视频在线观看 | 成人三级网址 | 手机av在线网站 | 日韩两性视频 | 视频 天天草 | 日韩高清一| 免费精品视频在线观看 | 久久成人18免费网站 |