• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            興海北路

            ---男兒仗劍自橫行
            <2008年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            統(tǒng)計(jì)

            • 隨筆 - 85
            • 文章 - 0
            • 評(píng)論 - 17
            • 引用 - 0

            常用鏈接

            留言簿(6)

            隨筆分類

            隨筆檔案

            收藏夾

            全是知識(shí)啊

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            鳥(niǎo)哥學(xué)習(xí)Shell Scripts
            引用:
                學(xué)習(xí)Shell Scripts

                如果您真得很想要走信息這條路,并且想要好好的管理好屬于您的主機(jī),那么,別說(shuō)鳥(niǎo)哥不告訴您,Shell Scripts真的是必須要學(xué)習(xí)的一項(xiàng)課程!基本上,Shell scripts有點(diǎn)像是早期的批處理文件,亦即是將一些指令匯編起來(lái)一次執(zhí)行,但是Shell scripts擁有更強(qiáng)大的功能,那就是,他可以進(jìn)行類似程序(program)的撰寫(xiě),并且,不需要經(jīng)過(guò)編譯(compiler)就能執(zhí)行,真得很方便。加上,我們可透過(guò)shell script來(lái)簡(jiǎn)化我們?nèi)粘5墓ぷ鞴芾?,而且,整個(gè)Linux環(huán)境中,一些服務(wù)(services)的啟動(dòng)都是透過(guò)shell script的,如果您對(duì)于script不了解,嘿嘿!發(fā)生問(wèn)題時(shí),可真是會(huì)求助無(wú)門(mén)的!所以,好好的學(xué)一學(xué)他吧!

            什么是Shell scripts?
                這個(gè)有趣的問(wèn)題趕緊回答看看,什么是shell script呢?shell我們?cè)谡J(rèn)識(shí)bash當(dāng)中已經(jīng)提過(guò)了,那是一個(gè)文字接口底下讓我們與系統(tǒng)溝通的一個(gè)工具借口,那么script是啥?字面上的意義,script是[腳本、劇本]的意思。整句話是說(shuō),shell script是針對(duì)shell所寫(xiě)的[劇本!] 什么東西???呵呵!其實(shí),shell script是利用shell的功能所寫(xiě)的一個(gè)[程序(program)],這個(gè)程序是使用純文字文件,將一些shell的語(yǔ)法與指令寫(xiě)在里面,搭配正規(guī)表示法、管線命令與數(shù)據(jù)流重導(dǎo)向等功能,已達(dá)到我們所想要的處理目的。
                所以,簡(jiǎn)單的說(shuō),shell script就像是早期DOS年代的批處理(.bat),最簡(jiǎn)單的功能就是將許多指令匯整寫(xiě)在一起,讓使用者很輕易的就能夠one touch(執(zhí)行一個(gè)檔案“shell script”,就能夠一次執(zhí)行多個(gè)指令),而,shell script 更提供數(shù)組、循環(huán)、條件與邏輯判斷等重要功能,讓使用者也可以直接以shell 來(lái)撰寫(xiě)程序,而不必使用類似C程序語(yǔ)言等傳統(tǒng)程序撰寫(xiě)的語(yǔ)法呢!
                那,這么說(shuō)您可以了解了嗎?是的!shell script可以簡(jiǎn)單的被看成是批處理,也可以被說(shuō)成是一個(gè)程序語(yǔ)言,且這個(gè)程序語(yǔ)言由于都是利用shell與相關(guān)工具指令,所以不需要編譯即可執(zhí)行,且擁有不錯(cuò)的除錯(cuò)(debug)工具,所以,他可以幫助系統(tǒng)管理員快速的管理好主機(jī)。

            ---------------------------------------------------------------------------------
            干嗎學(xué)習(xí)shell scripts?

                這是一個(gè)好問(wèn)題,我又干嘛一定要學(xué)shell script?我又不是信息人,沒(méi)有寫(xiě)程序的概念,那我干嗎還要學(xué)shell script呢?不要學(xué)可不可以???呵呵~如果Linux對(duì)您而言,您只是想要[會(huì)用]而已,那么,不需要學(xué)shell script也還無(wú)所謂,這部分先給他跳過(guò)去,等到有空的時(shí)候,再來(lái)好好的瞧一瞧。但是,如果您是真的想要玩清楚Linux的來(lái)龍去脈,那么shell script就不可不知,為什么呢?因?yàn)椋?br>
            自動(dòng)化管理的重要依據(jù):
                不用鳥(niǎo)哥說(shuō)您也知道,管理一部主機(jī)真不是簡(jiǎn)單的事情,每天要進(jìn)行的任務(wù)就有:查詢登錄檔、追蹤流量、監(jiān)控使用者使用主機(jī)狀態(tài)、主機(jī)各項(xiàng)硬件設(shè)備狀態(tài)、主機(jī)軟件更新查詢、更不要說(shuō)得應(yīng)付其它使用者的突然要求了。而這些工作,您想要自行手動(dòng)處理,還是寫(xiě)個(gè)簡(jiǎn)單的程序來(lái)幫助您每日自動(dòng)處理分析,若有問(wèn)題才通知您呢?當(dāng)然是讓系統(tǒng)自動(dòng)工作比較好,對(duì)吧!呵呵~這就得要良好的shell script來(lái)幫忙的啦!

            追蹤與管理系統(tǒng)的重要工作:
                雖然我們還沒(méi)有提到服務(wù)啟動(dòng)的方法,不過(guò),這里可以先提一下,我們Linux系統(tǒng)的服務(wù)(services)啟動(dòng)的接口,在/etc/init.d/這個(gè)目錄下,所有的檔案都是scriptsl;另外,包括開(kāi)機(jī)(booting)過(guò)程也都是利用shell script來(lái)幫忙搜尋系統(tǒng)的相關(guān)設(shè)定數(shù)據(jù),然后再代入各個(gè)服務(wù)的設(shè)定參數(shù)?。∨e例來(lái)說(shuō),如果我們想要重新啟動(dòng)系統(tǒng)登錄文件,可以使用:[/etc/init.d/syslogd restart],那個(gè)syslogd檔案就是scripts啦!另外,我曾經(jīng)在某一代的FC上面發(fā)現(xiàn),啟動(dòng)MySQL這個(gè)數(shù)據(jù)庫(kù)服務(wù)時(shí),確實(shí)是可以啟動(dòng)的,但是屏幕上卻老是出現(xiàn)[failure],后來(lái)才發(fā)現(xiàn),原來(lái)啟動(dòng)MySQL那個(gè)script會(huì)主動(dòng)地以[空的密碼]去嘗試去登錄MySQL,但我修改過(guò)MySQL的密碼嘍~當(dāng)然就登入失敗~后來(lái)改了改script,就略去這個(gè)問(wèn)題啦!如此說(shuō)來(lái),script 確實(shí)是需要學(xué)習(xí)的啊!

            簡(jiǎn)單入侵偵測(cè)功能:
                當(dāng)我們的系統(tǒng)有異狀時(shí),大多會(huì)將這些異狀記錄在系統(tǒng)記錄器,也就是我們提到的[系統(tǒng)登錄文件],那么我們可以在固定的幾分鐘內(nèi)主動(dòng)地去分析系統(tǒng)登錄文件,若察覺(jué)有問(wèn)題,就立即通報(bào)管理員,或者是立刻加強(qiáng)防火墻的設(shè)定規(guī)則,如此一來(lái),您的主機(jī)可就能夠達(dá)到[自我保護(hù)]的聰明學(xué)習(xí)功能啦~舉例來(lái)說(shuō),我們可以通過(guò)shell script 去分析[當(dāng)該封包嘗試幾次還是聯(lián)機(jī)失敗后,就予以抵擋住該IP]之類的舉動(dòng),例如鳥(niǎo)哥寫(xiě)過(guò)一個(gè)關(guān)于抵擋砍站軟件的shell script,就是用這個(gè)想法去達(dá)成的呢!

            連續(xù)指令單一化:
                其實(shí),對(duì)于新手而言,script最簡(jiǎn)單的功能就是:[匯整一些在command line 下達(dá)的連續(xù)指令,將他寫(xiě)入scripts當(dāng)中,而由直接執(zhí)行scripts來(lái)啟動(dòng)一連串的command line 指令輸出入!]例如:防火墻連續(xù)規(guī)則(iptables),開(kāi)機(jī)加載程序的項(xiàng)目(就是在/etc/rc.d/rc.local里頭的數(shù)據(jù)),等等都是相似的功能啦!其實(shí),說(shuō)穿了,如果不考慮program的部分,那么scripts也可以想成,僅是幫我們把一大串的指令匯編在一個(gè)檔案里面,而直接執(zhí)行該檔案就可以執(zhí)行那一串又臭有長(zhǎng)的指令段!就是這么簡(jiǎn)單啦!

            簡(jiǎn)易的數(shù)據(jù)處理:       
                由前一章 正規(guī)表示法的awk程序說(shuō)明中,您可以發(fā)現(xiàn),awk可以用來(lái)處理簡(jiǎn)單的數(shù)據(jù)呢!例如薪資簡(jiǎn)單的處理啊。shell script的功能更強(qiáng)大,例如鳥(niǎo)哥曾經(jīng)用shell script直接處理數(shù)據(jù)的比對(duì)啊,文字?jǐn)?shù)據(jù)得處理啊等等的,撰寫(xiě)方便,速度又快(因?yàn)樵贚inux效能較佳),真的是很不錯(cuò)用的啦!

            跨平臺(tái)支持與學(xué)習(xí)歷程較短:
                幾乎所有的Unix Like上面都可以跑shell script,連MS Windows系列也有相關(guān)的仿真器可以用,此外,shell script的語(yǔ)法是相當(dāng)親和的,看都看得懂得文字,而不是機(jī)器碼,很容易學(xué)習(xí)~這些都是您可以加以考慮的學(xué)習(xí)點(diǎn)??!

            上面這些都是您考慮學(xué)習(xí)shell script的特點(diǎn)~此外,shell script還可以簡(jiǎn)單的以vi來(lái)直接編寫(xiě),實(shí)在是很方便的好東西!所以,還是建議您學(xué)習(xí)一下啦。

            不過(guò),雖然shell script號(hào)稱是程序(program),但實(shí)際上,shell script處理數(shù)據(jù)的速度上是不太夠的。因?yàn)椋瑂hell script 用的是外部的指令與bash shell 的一些預(yù)設(shè)工具,所以,他常常會(huì)去呼叫外部的函數(shù)庫(kù),因此,運(yùn)算速度上面當(dāng)然比不上傳統(tǒng)的程序語(yǔ)言。所以,shell script用在系統(tǒng)管理上面是很好的一項(xiàng)工具,但是用在處理大量數(shù)值運(yùn)算上,就不夠好了,而且還很麻煩,因?yàn)椋簊hell scripts 的速度較慢,且使用的CPU資源較多,造成主機(jī)資源的分配不良,還好,我們確實(shí)很少看到利用shell scripts在進(jìn)行大量數(shù)據(jù)運(yùn)算的,所以,不必?fù)?dān)心的啦!

            ----------------------------------------------------------------------------------------------------
            第一節(jié) script的撰寫(xiě)與執(zhí)行

            如同前面講到的,shell script其實(shí)就是純文字文件(ASCII),我們可以編輯這個(gè)檔案,然后讓這個(gè)檔案來(lái)幫我們一次執(zhí)行多個(gè)命令,或者是利用一些運(yùn)算與邏輯判斷來(lái)幫我們達(dá)成某些功能。所以,要編輯這個(gè)檔案的內(nèi)容時(shí),當(dāng)然就需要具備有bash shell 指令下達(dá)的相關(guān)知識(shí)。我們說(shuō)過(guò),要下達(dá)指令需要注意的事項(xiàng)在bash章節(jié)內(nèi)已經(jīng)提過(guò),在shell script的撰寫(xiě)同樣要用到這些注意事項(xiàng)的:
            如同前面bash command提到的,指令與參數(shù)間的多個(gè)空白會(huì)被忽略掉:
            而空白行也被忽略掉!并且[tab]也是不會(huì)被理會(huì)的!
            如果讀取到一個(gè)Enter符號(hào)(CR),就嘗試開(kāi)始執(zhí)行該行命令;
            至于如果一行的內(nèi)容太多,則可以使用\[Enter]來(lái)延伸至下一行;
            此外,使用最多的#可做為批注!任何加在#后面的字,將全部被視為批注文字而被忽略!
            如此一來(lái),我們?cè)趕cript內(nèi)所撰寫(xiě)的程序,就會(huì)被一行一行的執(zhí)行,好了,那么這個(gè)程序假設(shè)文件名是shell.sh 好了,如何執(zhí)行這個(gè)檔案呢?很簡(jiǎn)單,可以由底下幾個(gè)方法:
            將shell.sh加上可讀與執(zhí)行(rx)的權(quán)限,然后就能夠以./shell.sh來(lái)執(zhí)行了;
            直接以sh shell.sh的方式來(lái)直接執(zhí)行即可。
            反正重點(diǎn)就是要讓那個(gè)shell.sh內(nèi)的指令可以被執(zhí)行的意思!那我為何需要使用./shell.sh來(lái)下達(dá)指令?還記得我們?cè)赽ash 里面一直強(qiáng)調(diào)的,指令是否能夠被執(zhí)行與PATH這個(gè)環(huán)境變量有關(guān),所以,要執(zhí)行[目前這個(gè)目錄下的某個(gè)檔案]就需要加上 ./這個(gè)目錄!另外,其實(shí)您也可以將shell.sh放在您的家目錄下的~/bin這個(gè)目錄中,然后利用PATH="$PATH"~/bin的設(shè)定,就能夠直接執(zhí)行您的script了
                  那,為何sh shell.sh也可以執(zhí)行呢?這是因?yàn)?bin/sh其實(shí)就是/bin/bash,使用sh shell.sh亦即告訴系統(tǒng),我想要直接以bash的功能來(lái)執(zhí)行shell.sh這個(gè)檔案內(nèi)的相關(guān)指令的意思。而我們也可以利用sh的參數(shù),如 -n 及 -x來(lái)檢查與追蹤shell.sh的語(yǔ)法是否正確!

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

            撰寫(xiě)第一個(gè)script
            不論是那個(gè)門(mén)派,要學(xué)武功要從掃地做起,那么要學(xué)程序呢?呵呵,肯定是由[秀出Hello World!]這個(gè)字眼開(kāi)始的!OK!那么鳥(niǎo)哥就先寫(xiě)一個(gè)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


            在我們這個(gè)章節(jié)當(dāng)中,請(qǐng)將所有的撰寫(xiě)的script放置到您家目錄的~/scripts這個(gè)目錄內(nèi),比較好管理啦!上面的寫(xiě)法當(dāng)中,我主要將整個(gè)程序的撰寫(xiě)分成數(shù)段,大致是這樣:
            第一行 #!/bin/bash在宣告這個(gè)script使用的shell 名稱:
            因?yàn)槲覀兪褂玫氖莃ash,所以,必須要以[#!/bin/bash]來(lái)宣告這個(gè)檔案內(nèi)的語(yǔ)法使用bash的語(yǔ)法!那么當(dāng)這個(gè)程序被執(zhí)行時(shí),他就能夠加載bash的相關(guān)環(huán)境設(shè)定檔,并且執(zhí)行bash來(lái)使我們底下的指令能夠執(zhí)行!這很重要的!(在很多狀況中,如果沒(méi)有設(shè)定好這一行,那么該程序很可能會(huì)無(wú)法執(zhí)行,因?yàn)橄到y(tǒng)可能無(wú)法判斷該程序需要使用什么shell來(lái)執(zhí)行!)

            程序內(nèi)容的宣告:
                  整個(gè)script當(dāng)中,除了第一行的#!是用來(lái)宣告shell的之外,其他的#就是[批注]用途!所以上面的程序當(dāng)中,第二行以下就是用來(lái)說(shuō)明整個(gè)程序的狀態(tài)。一般來(lái)說(shuō),建議您一定要養(yǎng)成說(shuō)明該script的:1.內(nèi)容與功能;2.版本信息;3.作者與聯(lián)絡(luò)方式;4.建檔日期;5.歷史紀(jì)錄等等。這將有助于未來(lái)程序的改寫(xiě)與debug!

            主要環(huán)境變量的宣告:
                  建議務(wù)必要將一些重要的環(huán)境變量設(shè)定好,鳥(niǎo)哥個(gè)人認(rèn)為,PATH是當(dāng)中最重要的!如此一來(lái),則可讓我們這支程序在進(jìn)行時(shí),可以直接下達(dá)指令,而不必寫(xiě)絕對(duì)路徑!比較好!

            主要程序部分
                  就將主要的程序?qū)懞眉纯桑≡谶@個(gè)例子當(dāng)中,就是echo那一行。

            執(zhí)行成果告知
                  是否記得我們?cè)赽ash里面要討論一個(gè)指令的執(zhí)行成功與否,可以使用$?這個(gè)變量來(lái)觀察~那么我們就也可以利用exit這個(gè)指令來(lái)讓程序中斷,并且回傳一個(gè)數(shù)值給系統(tǒng),在我們這個(gè)例子當(dāng)中,我使用exit 0,這代表離開(kāi)script,并且回傳一個(gè)0給系統(tǒng),所以我執(zhí)行完這個(gè)script后,若接著下達(dá)echo $?則可以得到0的值!更聰明的讀者應(yīng)該也知道了,呵呵!利用這個(gè)exit n的功能,我們還可以自訂錯(cuò)誤訊息,讓這支程序變得更加的smart呢!
            接下來(lái)執(zhí)行看看結(jié)果是怎樣的?
            [root@linux scripts]# sh sh01.sh
            Hello World!


            您會(huì)看到屏幕是這樣,而且應(yīng)該還會(huì)聽(tīng)到[咚]的一聲,為什么呢?還記得前一章提到的printf吧?用echo接著那些特殊的按鍵也可以發(fā)生同樣的事情~不過(guò),echo必須要加上 -e 的參數(shù)才行,呵呵,在您寫(xiě)完這個(gè)小script之后,您就可以大聲地說(shuō):[我也會(huì)寫(xiě)程序了]!

            另外,你也可以利用:[chmod a+x sh01.sh; ./sh01.sh] 來(lái)執(zhí)行這個(gè)script呢!

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

            --------------------------------------------------------------------------------
            撰寫(xiě) shell script 的良好習(xí)慣建立

            一個(gè)良好習(xí)慣的養(yǎng)成是很重要的~大家在剛開(kāi)始撰寫(xiě)程序的時(shí)候,最容易忽略這部分, 認(rèn)為程序?qū)懗鰜?lái)就好了,其它的不重要。其實(shí),如果程序的說(shuō)明能夠更清楚, 那么對(duì)您自己是有很大的幫助的。

            舉例來(lái)說(shuō),鳥(niǎo)哥自己為了自己的需求,曾經(jīng)撰寫(xiě)了不少的 script 來(lái)幫我進(jìn)行主機(jī) IP 的偵測(cè)啊、 登錄檔分析與管理啊、自動(dòng)上傳下載重要 設(shè)定檔啊等等的,不過(guò),早期就是因?yàn)樘珣辛耍?/span> 管理的主機(jī)又太多了,常常同一個(gè)程序在不同的主機(jī)上面進(jìn)行更改,到最后,到底哪一支才是最新的都記不起來(lái),  而且,重點(diǎn)是,我到底是改了哪里??為什么做那樣的修改?都忘的一干二凈~真要命~

            所以,后來(lái)鳥(niǎo)哥在寫(xiě)程序的時(shí)候,通常會(huì)比較仔細(xì)的將程序的設(shè)計(jì)過(guò)程給他記錄下來(lái), 而且還會(huì)記錄一些歷史紀(jì)錄,如此一來(lái),好多了~ 至少很容易知道我修改了哪些數(shù)據(jù),以及程序修改的理念與邏輯概念等等, 在維護(hù)上面是輕松很多很多的喔!

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

            --------------------------------------------------------------------------------
            簡(jiǎn)單的 shell script 練習(xí)

            在第一支 shell script 撰寫(xiě)完畢之后,相信您應(yīng)該具有基本的撰寫(xiě)功力了。 接下來(lái),在開(kāi)始更深入的程序概念之前,我們先來(lái)玩一些比 較有趣的簡(jiǎn)單的小范例好了。 底下的范例中,達(dá)成結(jié)果的方式相當(dāng)?shù)亩啵ㄗh您先自行撰寫(xiě)看看,寫(xiě)完之后再與鳥(niǎo)哥寫(xiě)的內(nèi)容比對(duì), 這樣才能更加深概念喔! 好!不啰唆,我們就一個(gè)一個(gè)來(lái)玩吧!


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

            變量?jī)?nèi)容由使用者決定 
            很多時(shí)候我們需要使用者輸入一些內(nèi)容,好讓程序可以順利運(yùn)作。 簡(jiǎn)單的來(lái)說(shuō),大家應(yīng)該都有安裝過(guò)軟件的經(jīng)驗(yàn),安裝的時(shí)候,他不是會(huì)問(wèn)您『要安裝到那個(gè)目錄去?』嗎? 那個(gè)讓使用者輸入的數(shù)據(jù)的動(dòng)作,就是讓使用者輸入變量?jī)?nèi)容啦。

            你應(yīng)該還記得在 bash 的時(shí)候,我們有學(xué)到一個(gè) read 指令吧?忘記的話,請(qǐng)自行回頭去閱讀一番。 現(xiàn)在,請(qǐng)你以 read 指令的用 途,撰寫(xiě)一個(gè) script ,他可以讓使用者輸入:1 first name  2. last name, 最后并且在屏幕上顯示: Your full name is: 』的內(nèi)容:
            [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"

             
            將上面這個(gè) sh02.sh 執(zhí)行一下,你就能夠發(fā)現(xiàn)使用者自己輸入的變量可以被取用的哩! 很不錯(cuò)吧!加油!



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

            利用 date 進(jìn)行檔案的建立 
            想象一個(gè)狀況,如果我每天要進(jìn)行備份,而備份的數(shù)據(jù)又不想被覆蓋掉,也就是說(shuō), 我想要將每天備份的數(shù)據(jù)放在不同的檔案中。哇!這真困擾啊?難道 要我每天去修改 script  不需要?。∫?yàn)槊刻斓摹喝掌凇徊⒉幌嗤晕铱梢詫n名取成類似: backup.20050802 , 不就可以 每天一個(gè)不同檔名了嗎?呵呵!確實(shí)如此。好了,接下來(lái)出個(gè)例子: 我想要建立三個(gè)空的檔案,檔名最開(kāi)頭由使用者輸入決定,假設(shè)使用者輸入  filename 好了, 那今天的日期是 2005/08/23 ,我想要以前天、昨天、今天的日期來(lái)建立這個(gè)檔案,亦即  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 這個(gè)變量;
            echo -e "I will use 'touch' command to create 3 files."
            read -p "Please input the filename what you want: " fileuser

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

            # 3. 
            開(kāi)始利用 date 指令來(lái)取得所需要的檔名了;
            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

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



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

            數(shù)值運(yùn)算的方法 
            各位看官應(yīng)該還記得,我們可以使用 declare 來(lái)定義變量的類型吧?! 這樣才能夠進(jìn)行加減運(yùn)算?。】上У氖?, bash shell  頭預(yù)設(shè)僅支持到整數(shù)的數(shù)據(jù)。 OK!那我們來(lái)玩玩看,如果我們要使用者輸入兩個(gè)變量,然后將兩個(gè)變量的內(nèi)容相乘, 最后輸出相乘的結(jié)果,那可以怎么做?
            [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"

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

             
            這樣了解了吧?!多多學(xué)習(xí)與應(yīng)用喔! ^_^


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

             bash 章節(jié)中,我們提到過(guò) $? 這個(gè)變量所代表的意義, 此外,也透過(guò) &&  || 來(lái)作為前一個(gè)指令是否能夠成 功進(jìn)行的一個(gè)參考。 那么,如果我想要知道 /dmtsai 這個(gè)目錄是否存在時(shí),難道一定要使用 ls 來(lái)執(zhí)行, 然后再以 $? 來(lái)判斷執(zhí)行成果嗎? 呵呵!當(dāng)然不需要! 我們可以透過(guò)『 test 』這個(gè)指令來(lái)偵測(cè)呢!


            --------------------------------------------------------------------------------
            利用 test 指令的測(cè)試功能

            當(dāng)我要檢測(cè)系統(tǒng)上面某些檔案或者是相關(guān)的屬性時(shí),利用 test 這個(gè)指令來(lái)工作, 真是好用得不得了,舉例來(lái)說(shuō),我要檢查 /dmtsai 是否存在時(shí),使用:
            [root@linux ~]# test -e /dmtsai

             
            執(zhí)行結(jié)果并不會(huì)顯示任何訊息,但最后我們可以透過(guò) $?  &&  || 來(lái)展現(xiàn)整個(gè)結(jié)果呢! 例如我們?cè)趯⑸厦娴睦痈膶?xiě)成這樣:
            [root@linux ~]# test -e /dmtsai && echo "exist" || echo "Not exist"

             
            最終的結(jié)果可以告知我們是『exist』還是『Not exist』呢!那我知道 -e 是測(cè)試一個(gè)『東西』在不在, 如果還想要測(cè)試一下該檔名是啥玩意兒時(shí),還有哪些標(biāo)志可以來(lái)判斷的呢?呵呵!有底下這些東西喔!

            測(cè)試的標(biāo)志 代表意義 
            1. 
            關(guān)于某個(gè)檔名的『類型』偵測(cè)(存在與否),如 test -e filename 
            -e 
            該『檔名』是否存在?(常用
            -f 
            該『檔名』是否為檔案(file)(常用
            -d 
            該『文件名』是否為目錄(directory)?(常用
            -b 
            該『檔名』是否為一個(gè) block device 裝置? 
            -c 
            該『檔名』是否為一個(gè) character device 裝置? 
            -S 
            該『檔名』是否為一個(gè) Socket 檔案? 
            -p 
            該『檔名』是否為一個(gè) FIFO (pipe) 檔案? 
            -L 
            該『檔名』是否為一個(gè)連結(jié)檔? 
            2. 
            關(guān)于檔案的權(quán)限偵測(cè),如 test -r filename 
            -r 
            偵測(cè)該檔名是否具有『可讀』的屬性? 
            -w 
            偵測(cè)該檔名是否具有『可寫(xiě)』的屬性? 
            -x 
            偵測(cè)該檔名是否具有『可執(zhí)行』的屬性? 
            -u 
            偵測(cè)該文件名是否具有『SUID』的屬性? 
            -g 
            偵測(cè)該文件名是否具有『SGID』的屬性? 
            -k 
            偵測(cè)該文件名是否具有『Sticky bit』的屬性? 
            -s 
            偵測(cè)該檔名是否為『非空白檔案』? 
            3. 
            兩個(gè)檔案之間的比較,如: test file1 -nt file2 
            -nt (newer than)
            判斷 file1 是否比 file2  
            -ot (older than)
            判斷 file1 是否比 file2  
            -ef 
            判斷 file2  file2 是否為同一檔案,可用在判斷 hard link 的判定上。 主要意義在判定,兩個(gè)檔案是否均指向同一個(gè) inode 哩! 
            4. 
            關(guān)于兩個(gè)整數(shù)之間的判定,例如 test n1 -eq n2 
            -eq 
            兩數(shù)值相等 (equal) 
            -ne 
            兩數(shù)值不等 (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. 
            判定字符串的數(shù)據(jù) 
            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)
            兩狀況同時(shí)成立!例如 test -r file -a -x file,則 file 同時(shí)具有 r  x 權(quán)限時(shí),才回傳 true。 
            -o (or)
            兩狀況任何一個(gè)成立!例如 test -r file -o -x file,則 file 具有 r  x 權(quán)限時(shí),就可回傳 true 
            反相狀態(tài),如 test ! -x file ,當(dāng) file 不具有 x 時(shí),回傳 true 

            OK
            !現(xiàn)在我們就利用 test 來(lái)幫我們寫(xiě)幾個(gè)簡(jiǎn)單的例子。首先,判斷一下, 讓使用者輸入一個(gè)檔名,我們判斷:
            這個(gè)檔案是否存在,若不存在則給予一個(gè)『Filename does not exist』的訊息,并中斷程序; 
            若這個(gè)檔案存在,則判斷他是個(gè)檔案或目錄,結(jié)果輸出『Filename is regular file』或 Filename is directory 
            判斷一下,執(zhí)行者的身份對(duì)這個(gè)檔案或目錄所擁有的權(quán)限,并輸出權(quán)限數(shù)據(jù)!
            你可以先自行創(chuàng)作看看,然后再跟底下的結(jié)果討論討論。注意利用 test  && 還有 || 等標(biāo)志!
            [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. 
            開(kāi)始判斷檔案類型與屬性
            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. 
            開(kāi)始輸出信息!
            echo "The filename: $filename is a $filetype"
            echo "And the permission are : $perm"

             
            很有趣的例子吧!您可以自行再以其它的案例來(lái)撰寫(xiě)一下可用的功能呢!



            --------------------------------------------------------------------------------
            利用判斷符號(hào) [ ]

            除了我們很喜歡使用的 test 之外,其實(shí),我們還可以利用判斷符號(hào)『 [ ] 』來(lái)進(jìn)行數(shù)據(jù)的判斷呢! 舉例來(lái)說(shuō),如果我想要知道 $HOME 這個(gè)變量是否為空的,可以這樣做:
            [root@linux ~]# [ -z "$HOME" ]

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

             
            上面的例子在說(shuō)明,兩個(gè)字符串 $HOME  $MAIL 是否相同的意思,相當(dāng)于 test $HOME = $MAIL 的意思啦! 而如 果沒(méi)有空白分隔,例如 [$HOME==$MAIL] 時(shí),我們的 bash 就會(huì)顯示錯(cuò)誤訊息了!這可要很注意??! 所以說(shuō),您最好要注意:
            在中括號(hào) [] 內(nèi)的每個(gè)組件都需要有空格鍵來(lái)分隔; 
            在中括號(hào)內(nèi)的變量,最好都以雙引號(hào)來(lái)設(shè)定; 
            在中括號(hào)內(nèi)的常數(shù),最好都以單或雙引號(hào)來(lái)設(shè)定。
            舉例來(lái)說(shuō),假如我設(shè)定了 name="VBird Tsai" ,然后這樣判定:
            [root@linux ~]# name="VBird Tsai"
            [root@linux ~]# [ $name == "VBird" ]
            bash: [: too many arguments

             
            為什么呢?因?yàn)?/span> $name 如果沒(méi)有使用雙引號(hào)刮起來(lái),那么上面的判定式會(huì)變成: 
            [ VBird Tsai == "VBird" ] 
            而不是我們要的: 
            [ "VBird Tsai" == "VBird" ] 
            這可是差很多的喔!另外,中括號(hào)的使用方法與標(biāo)志與 test 幾乎一模一樣啊~ 只是中括號(hào)比較常用在條件判斷式 if ..... then ..... fi 的情況中就是了。 好,那我們也繼續(xù)來(lái)做一個(gè)小案例好了:
            當(dāng)執(zhí)行一個(gè)程序的時(shí)候,這個(gè)程序會(huì)讓使用者選擇 Y  N , 
            如果使用者輸入 Y  y 時(shí),就顯示『 OK, continue  
            如果使用者輸入 n  N 時(shí),就顯示『 Oh, interrupt !』 
            如果不是 Y/y/N/n 之內(nèi)的其它字符,就顯示『I don't know what is your choise
            利用中括號(hào)、 &&  || 來(lái)繼續(xù)吧!
            [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

             
            很有趣吧!利用這個(gè)字符串判別的方法,我們就可以很輕松的將使用者想要進(jìn)行的工作分門(mén)別類呢! 接下來(lái),我們?cè)賮?lái)談一些其它有的沒(méi)有的東西吧!

            Tips:
            為什么判斷式里面下達(dá)等于要用 == 而不是一個(gè) = 就好了呢?我們?cè)谇耙徽抡?guī)表示法里面的 awk 提到, 只有一個(gè) = 用來(lái)給予一個(gè)變量設(shè)定其內(nèi)容,邏輯判斷時(shí),則會(huì)給予兩個(gè)等于, 亦即『比較』而非『設(shè)定』的意思~這里要好好的分辨一下喔! ^_^   


            --------------------------------------------------------------------------------
            Shell script 
            的預(yù)設(shè)變數(shù)($0, $1...)

            其實(shí),當(dāng)我們執(zhí)行一個(gè) shell script 時(shí),在這個(gè) shell script 里面就已將幫我們做好一些可用的變量了。 舉例來(lái)說(shuō),在不久的將來(lái),您就會(huì)發(fā)現(xiàn),當(dāng)我們要啟動(dòng)一個(gè)系統(tǒng)服務(wù)時(shí),可能會(huì)下達(dá)類似這樣的指令:
            [root@linux ~]# /etc/init.d/crond restart

             
            那是啥玩意兒?呵呵!就是『向 /etc/init.d/crond 這個(gè) script 下達(dá) restart 的指令』, 咦!我們不是都使  read 來(lái)讀取使用者輸入的變量?jī)?nèi)容嗎?為啥我可以直接在 script 后面接上這個(gè)參數(shù)? 這是因?yàn)?/span> shell script 幫我們?cè)O(shè)定好 一些指定的變量了!變量的對(duì)應(yīng)是這樣的:

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

             
            這樣夠清楚了吧?!執(zhí)行的文件名為 $0 這個(gè)變量,第一個(gè)接的參數(shù)就是 $1 啊~ 所以,只要我們?cè)?/span> script 里面善用 $1 的話, 就可以很簡(jiǎn)單的立即下達(dá)某些指令功能了! 好了,來(lái)做個(gè)例子吧~假設(shè)我要執(zhí)行一個(gè) script ,執(zhí)行后,該 script 會(huì)自動(dòng)列出自己的檔名,  還有后面接的前三個(gè)參數(shù),該如何是好?
            [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

             
            這支程序里面鳥(niǎo)哥加上了一些控制式,亦即利用 &&  || 來(lái)加以判斷 $1 ~ $3 是否存在? 若存在才顯示,若不存在就中斷~執(zhí)行結(jié)果如下:
            [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

             
            上面這七的例子都很簡(jiǎn)單吧?幾乎都是利用 bash 的相關(guān)功能而已~ 不難啦~底下我們就要使用條件判斷式來(lái)進(jìn)行一些分別功能的設(shè)定了,好好瞧一瞧先~ 

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

            只要講到『程序』的話,那么條件判斷式,亦即是『 if then 』這種判別式肯定一定要學(xué)習(xí)的! 因?yàn)楹芏鄷r(shí)候,我們都必須要依據(jù)某些數(shù)據(jù)來(lái) 判斷程序該如何進(jìn)行。舉例來(lái)說(shuō),我們?cè)谏项^不是有練習(xí)當(dāng)使用者輸入 Y/N 時(shí),必須要執(zhí)行不同的訊息輸出嗎?簡(jiǎn)單的方式可以利用 &&   || ,但如果我還想要執(zhí)行一堆指令呢? 那真的得要 if then 來(lái)幫忙啰~底下我們就來(lái)聊一聊!


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

            這個(gè) if .... then 是最常見(jiàn)的條件判斷式了~簡(jiǎn)單的說(shuō),就是當(dāng)符合某個(gè)條件判斷的時(shí)候, 就予以進(jìn)行某項(xiàng)工作就是了。我們可以簡(jiǎn)單的這樣看:
            if [ 
            條件判斷式 ]; then
            當(dāng)條件判斷式成立時(shí),可以進(jìn)行的指令工作內(nèi)容;
            fi

             
            至于條件判斷式的判斷方法,與前一小節(jié)的介紹相同?。≥^特別的是,如果我有多個(gè)條件要判別時(shí), 除了 sh06.sh 那個(gè)案例,也就是將多個(gè)條 件寫(xiě)入一個(gè)中括號(hào)內(nèi)的情況之外, 我還可以有多個(gè)中括號(hào)來(lái)隔開(kāi)喔!而括號(hào)與括號(hào)之間,則以 &&  || 來(lái)隔開(kāi),他們的意義是: 
            && 
            代表 AND  
            || 
            代表 or ;
            所以,在使用中括號(hào)的判斷式中, &&  || 就與指令下達(dá)的狀態(tài)不同了。舉例來(lái)說(shuō), sh06.sh 那個(gè)例子我可以改寫(xiě)成這樣:
            [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

             
            不過(guò),由這個(gè)例子看起來(lái),似乎也沒(méi)有什么了不起吧? sh06.sh 還比較簡(jiǎn)單呢~ 但是,如果我們考慮底下的狀態(tài),您就會(huì)知道 if then 的好處了:
            if [ 
            條件判斷式 ]; then
            當(dāng)條件判斷式成立時(shí),可以進(jìn)行的指令工作內(nèi)容;
            else
            當(dāng)條件判斷式不成立時(shí),可以進(jìn)行的指令工作內(nèi)容;
            fi

             
            如果考慮更復(fù)雜的情況,則可以使用這個(gè)語(yǔ)法:
            if [ 
            條件判斷式一 ]; then
            當(dāng)條件判斷式一成立時(shí),可以進(jìn)行的指令工作內(nèi)容;
            elif [ 
            條件判斷式二 ]; then
            當(dāng)條件判斷式二成立時(shí),可以進(jìn)行的指令工作內(nèi)容;
            else
            當(dāng)條件判斷式一與二均不成立時(shí),可以進(jìn)行的指令工作內(nèi)容;
            fi

             
            那我就可以將 sh06-2.sh 改寫(xiě)成這樣:
            [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

             
            是否程序變得很簡(jiǎn)單,而且依序判斷,可以避免掉重復(fù)判斷的狀況,這樣真的很容易設(shè)計(jì)程序的啦! ^_^ 好了,那么如果我要偵測(cè)你所輸入的參數(shù)是 否為 hello   也就是說(shuō),如果我想要知道,你在程序后面所接的第一個(gè)參數(shù) (就是 $1 ?。?/span>是否為 hello ,
            如果是的話,就顯示 "Hello, how are you ?" 
            如果沒(méi)有加任何參數(shù),就提示使用者必須要使用的參數(shù)下達(dá)法; 
            而如果加入的參數(shù)不是 hello ,就提醒使用者僅能使用 hello 為參數(shù)。
            整個(gè)程序的撰寫(xiě)可以是這樣的:
            [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

             
            然后您可以執(zhí)行這支程序,分別在 $1 的位置輸入 hello, 沒(méi)有輸入與隨意輸入, 就可以看到不同的輸出啰~是否還覺(jué)得挺簡(jiǎn)單的??!  ^_^。事實(shí)上, 學(xué)到這里,也真的很厲害了~好了,底下我們繼續(xù)來(lái)玩一些比較大一點(diǎn)的啰~ 我們?cè)谇耙徽乱呀?jīng)學(xué)會(huì)了 grep 這個(gè)好用的玩意兒,那 么多學(xué)一個(gè)叫做 netstat 的指令, 這個(gè)指令可以查詢到目前主機(jī)有開(kāi)啟的網(wǎng)絡(luò)服務(wù)端口口 (service ports), 相關(guān)的功能我們會(huì)在 服務(wù)器架設(shè)篇繼續(xù)介紹,這里您只要知道,我可以利用『 netstat -tuln 』來(lái)取得目前主機(jī)有啟動(dòng)的服務(wù), 而且取得的信息有點(diǎn)像這樣:
            [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

             
            上面的重點(diǎn)是特殊字體的那個(gè)部分,那些特殊字體的部分代表的就是 port 啰~ 那么每個(gè) port 代表的意義為何呢?幾個(gè)常見(jiàn)的 port 與相關(guān)網(wǎng)絡(luò)服務(wù)的關(guān)系是: 
            80: WWW 
            22: ssh 
            21: ftp 
            25: mail
            那我如何透過(guò) netstat 去偵測(cè)我的主機(jī)是否有開(kāi)啟這四個(gè)主要的網(wǎng)絡(luò)服務(wù)端口口呢? 我可以簡(jiǎn)單的這樣去寫(xiě)這個(gè)程序喔:
            [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. 
            先作一些告知的動(dòng)作而已~
            echo "Now, the services of your Linux system will be detect!"
            echo -e "The www, ftp, ssh, and mail will be detect! \n"

            # 2. 
            開(kāi)始進(jìn)行一些測(cè)試的工作,并且也輸出一些信息啰!
            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

             
            這樣又能夠一個(gè)一個(gè)的檢查啰~是否很有趣??! ^_^。接下來(lái),我們?cè)賮?lái)玩更難一點(diǎn)的。 我們知道可以利用 date 來(lái)顯示日期與時(shí)間,也可以 利用 $((計(jì)算式)) 來(lái)計(jì)算數(shù)值運(yùn)算。 另外, date 也可以用來(lái)顯示自 19710101 以來(lái)的『總秒數(shù)』 (請(qǐng)自行查閱  man date  info date) 。那么,您是否可以撰寫(xiě)一支小程序,用來(lái)『計(jì)算退伍日期還剩幾天?』也就是說(shuō):
            先讓使用者輸入他們的退伍日期; 
            再由現(xiàn)在日期比對(duì)退伍日期; 
            由兩個(gè)日期的比較來(lái)顯示『還需要幾天』才能夠退伍的字樣。
            似乎挺難的樣子?其實(shí)也不會(huì)啦,利用『 date --date="YYYYMMDD" +%s 』就能夠達(dá)到我們所想要的啰~如果您已經(jīng)寫(xiě)完了程序,對(duì)照底下的寫(xiě)法試看看:
            [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. 
            告知使用者這支程序的用途,并且告知應(yīng)該如何輸入日期格式?
            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. 
            測(cè)試一下,這個(gè)輸入的內(nèi)容是否正確?利用正規(guī)表示法啰~
            date_d=`echo $date2 |grep '[0-9]\{8\}'`
            if [ "$date_d" == "" ]; then
            echo "You input the wrong format of date...."
            exit 1
            fi

            # 3. 
            開(kāi)始計(jì)算日期啰~
            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

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



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

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

             
            要注意的是,這個(gè)語(yǔ)法是以 case 為開(kāi)頭,而以 esac 為結(jié)尾,啥?為何是 esac 呢?想一想,既然 if 的結(jié)尾是 fi ,那么  case 的結(jié)尾當(dāng)然就是將 case 倒著寫(xiě),自然就是 esac 啰~ ^_^,很好記吧~ 另外,每一個(gè)變量?jī)?nèi)容的程序段最后都需要兩個(gè)分號(hào)  (;;) 來(lái)代表該程序段落的結(jié)束,這挺重要的喔! 至于為何需要有 * 這個(gè)變量?jī)?nèi)容在最后呢?這是因?yàn)?,如果使用者不是輸入變量?jī)?nèi)容一或二時(shí), 我們 可以告知使用者相關(guān)的信息?。∨e例來(lái)說(shuō),我們?nèi)绻麑?/span> sh08.sh 改寫(xiě)的話, 他應(yīng)該會(huì)變成這樣喔!
            [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

             
            在上面這個(gè) sh08-2.sh 的案例當(dāng)中,如果你輸入『 sh sh08-2.sh test 』來(lái)執(zhí)行, 那么屏幕上就會(huì)出現(xiàn) Usage sh08-2.sh {hello}』的字樣,告知執(zhí)行者僅能夠使用 hello 喔~ 這樣的方式對(duì)于需要某些固定字符串來(lái)執(zhí)行的變量?jī)?nèi) 容就顯的更加的方便呢? 這種方式您真的要熟悉喔!這是因?yàn)橄到y(tǒng)的很多服務(wù)的啟動(dòng) scripts 都是使用這種寫(xiě)法的, 舉例來(lái)說(shuō),我們 Linux  的服務(wù)啟動(dòng)放置目錄是在 /etc/init.d/ 當(dāng)中,我已經(jīng)知道里頭有個(gè) syslog 的服務(wù),我想要重新啟動(dòng)這個(gè)服務(wù),可以這樣做: 
            /etc/init.d/syslog restart
            重點(diǎn)是那個(gè) restart 啦~如果您進(jìn)入 /etc/init.d/syslog 就會(huì)看到他使用的是 case 語(yǔ)法, 并且會(huì)規(guī)定某些既 定的變量?jī)?nèi)容,你可以直接下達(dá) /etc/init.d/syslog ,  script 就會(huì)告知你有哪些后續(xù)接的變量可以使用啰~方便吧!  ^_^

            一般來(lái)說(shuō),使用『 case $變量 in 』這個(gè)語(yǔ)法中,當(dāng)中的那個(gè) $變量 大致有兩種取得的方式:
            直接下達(dá)式:例如上面提到的,利用『 script.sh variable  的方式來(lái)直接給予 $1 這個(gè)變量的內(nèi)容,這也是在 /etc/init.d 目錄下大多數(shù)程序的設(shè)計(jì)方式。 
            交互式:透過(guò) read 這個(gè)指令來(lái)讓使用者輸入變量的內(nèi)容。
            這么說(shuō)或許您的感受性還不高,好,我們直接寫(xiě)個(gè)程序來(lái)玩玩:讓使用者能夠輸入 one, two, three  并且將使用者的變量顯示到屏幕上,如果不是 one, two, three 時(shí),就告知使用者僅有這三種選擇。
            [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í),您可以使用『 sh sh11.sh two 』的方式來(lái)下達(dá)指令,就可以收到相對(duì)應(yīng)的響應(yīng)了。 上面使用的是直接下達(dá)的方式,而如果使用 的是交互式時(shí),那么將上面第 10, 11 行的 "#" 拿掉, 并將 12 行加上批注 (#),就可以讓使用者輸入?yún)?shù)啰~這樣是否很有趣啊?!



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

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

             
            那個(gè) fname 就是我們的自訂的執(zhí)行指令名稱~而程序段就是我們要他執(zhí)行的內(nèi)容了。 要注意的是,在 shell script 當(dāng)中,  function 的設(shè)定一定要在程序的最前面, 這樣才能夠在執(zhí)行時(shí)被找到可用的程序段喔!好~我們將 sh11.sh 改寫(xiě)一下:
            [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

             
            以上面的例子來(lái)說(shuō),我做了一個(gè)函數(shù)名稱為 printif ,所以,當(dāng)我在后續(xù)的程序段里面, 只要執(zhí)行 printit 的話,就表示我的  shell script 要去執(zhí)行『 function printit ....  里面的那幾個(gè)程序段落啰! 當(dāng)然啰,上面這個(gè)例子舉得太簡(jiǎn)單 了,所以您不會(huì)覺(jué)得 function 有什么好厲害的, 不過(guò),如果某些程序代碼一再地在 script 當(dāng)中重復(fù)時(shí),這個(gè) function 可就重 要的多啰~ 不但可以簡(jiǎn)化程序代碼,而且可以做成類似『模塊』的玩意兒,真的很棒啦!

            另外, function 也是擁有內(nèi)建變量的~他的內(nèi)建變量與 shell script 很類似, 函數(shù)名稱代表示 $0 ,而后續(xù)接的變量 也是以 $1, $2... 來(lái)取代的~ 這里很容易搞錯(cuò)喔~因?yàn)椤?/span> function fname() { 程序段 } 』內(nèi)的 $0, $1...  等等與 shell script  $0 是不同的。以上面 sh11-2.sh 來(lái)說(shuō),假如我下達(dá):『 sh sh11-2.sh one   表示在 shell script 內(nèi)的 $1  "one" 這個(gè)字符串。但是在 printit() 內(nèi)的 $1 則與這個(gè) one 無(wú)關(guān)。 我們 將上面的例子再次的改寫(xiě)一下,讓您更清楚!
            [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

             
            在上面的例子當(dāng)中,如果您輸入『 sh sh11-3.sh one 』就會(huì)出現(xiàn)『 Your choice is 1 』的字樣~ 為什么是  1 呢?因?yàn)樵诔绦蚨温洚?dāng)中,我們是寫(xiě)了『 printit 1 』那個(gè) 1 就會(huì)成為 function 當(dāng)中的 $1 喔~ 這樣是否理解呢?  function 本身其實(shí)比較困難一點(diǎn),如果您還想要進(jìn)行其它的撰寫(xiě)的話。 不過(guò),我們僅是想要更加了解 shell script 而已,所以,這 里看看即可~了解原理就好啰~ ^_^ 

            --------------------------------------------------------------------------------
            循環(huán) (loop)

            除了 if...then...fi 這種條件判斷式之外,循環(huán)可能是程序當(dāng)中最重要的一環(huán)了~ 循環(huán)可以不斷的執(zhí)行某個(gè)程序段落,直到使用者設(shè)定的條件達(dá)成為止。 所以,重點(diǎn)是那個(gè)『條件的達(dá)成』是什么。底下我們就來(lái)談一談:


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

            一般來(lái)說(shuō),循環(huán)最常見(jiàn)的就是底下這兩種狀態(tài)了:
            while [ condition ]
            do
            程序段落
            done

             
            這種方式中, while 是『當(dāng)....時(shí)』,所以,這種方式說(shuō)的是『當(dāng) condition 條件成立時(shí),就進(jìn)行循環(huán),直到 condition 的條件不成立才停止』的意思。
            until [ condition ]
            do
            程序段落
            done

             
            這種方式恰恰與 while 相反,它說(shuō)的是『當(dāng) condition 條件成立時(shí),就終止循環(huán), 否則就持續(xù)進(jìn)行循環(huán)的程序段。』是否剛好相反 啊~我們以 while 來(lái)做個(gè)簡(jiǎn)單的練習(xí)好了。 假設(shè)我要讓使用者輸入 yes 或者是 YES 才結(jié)束程序的執(zhí)行,否則就一直進(jìn)行告知使用者輸入字符 串。
            [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

             
            上面這個(gè)例題的說(shuō)明是『當(dāng) $yn 這個(gè)變量不是 "yes"  $yn 也不是 "YES" 時(shí),才進(jìn)行循環(huán)內(nèi)的程序?!?/span> 而如果 $yn  "yes"  "YES" 時(shí),就會(huì)離開(kāi)循環(huán)啰~那如果使用 until 呢?呵呵有趣啰~ 他的條件會(huì)變成這樣:
            [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

             
            仔細(xì)比對(duì)一下這兩個(gè)東西有啥不同喔! ^_^再來(lái),如果我想要計(jì)算 1+2+3+....+100 這個(gè)數(shù)據(jù)呢? 利用循環(huán)啊~他是這樣的:
            [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"

             
            嘿嘿!當(dāng)您執(zhí)行了『 sh sh13.sh 』之后,就可以得到 5050 這個(gè)數(shù)據(jù)才對(duì)??!這樣瞭呼~ 那么讓您自行做一下,如果想要讓使用者 自行輸入一個(gè)數(shù)字,讓程序由 1+2+... 直到您輸入的數(shù)字為止, 該如何撰寫(xiě)呢?應(yīng)該很簡(jiǎn)單吧?!答案可以參考一下習(xí)題練習(xí)里面的一題喔!



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

            相對(duì)于 while, until 的循環(huán)方式是必須要『符合某個(gè)條件』的狀態(tài), for 這種語(yǔ)法,則是『 已經(jīng)知道要進(jìn)行幾次循環(huán)』的狀態(tài)!他的語(yǔ)法是:
            for (( 
            初始值限制值執(zhí)行步階 ))
            do
            程序段
            done

             
            這種語(yǔ)法適合于數(shù)值方式的運(yùn)算當(dāng)中,在 for 后面的括號(hào)內(nèi)的三串內(nèi)容意義為:
            初始值:某個(gè)變量在循環(huán)當(dāng)中的起始值,直接以類似 i=1 設(shè)定好; 
            限制值:當(dāng)變量的值在這個(gè)限制值的范圍內(nèi),就繼續(xù)進(jìn)行循環(huán)。例如 i<=100 
            執(zhí)行步階:每作一次循環(huán)時(shí),變量的變化量。例如 i=i+1
            值得注意的是,在『執(zhí)行步階』的設(shè)定上,如果每次增加 1 ,則可以使用類似『i++』的方式,亦即是 i 每次循環(huán)都會(huì)增加一的意思。好,我們以這種方式來(lái)進(jìn)行 1 累加到 100 的循環(huán)吧!
            [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"

             
            一樣也是很簡(jiǎn)單吧!利用這個(gè) for 則可以直接限制循環(huán)要進(jìn)行幾次呢!這么好用的東西難道只能在數(shù)值方面動(dòng)作? 當(dāng)然不是啦~我們還可以利用底下的方式來(lái)進(jìn)行非數(shù)字方面的循環(huán)運(yùn)作喔!
            for $var in con1 con2 con3 ...
            do
            程序段
            done

             
            以上面的例子來(lái)說(shuō),這個(gè) $var 的變量?jī)?nèi)容在循環(huán)工作時(shí):
            第一次循環(huán)時(shí), $var 的內(nèi)容為 con1 ; 
            第二次循環(huán)時(shí), $var 的內(nèi)容為 con2  
            第三次循環(huán)時(shí), $var 的內(nèi)容為 con3  
            ....
            我們可以做個(gè)簡(jiǎn)單的練習(xí)。假設(shè)我有三種動(dòng)物,分別是 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

             
            很簡(jiǎn)單是吧! ^_^。好了,那么如果我想要讓使用者輸入某個(gè)目錄, 然后我找出某目錄內(nèi)的文件名的權(quán)限呢?又該如何是好?呵呵!可以這樣做啦~
            [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. 
            先看看這個(gè)目錄是否存在???
            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. 
            開(kāi)始測(cè)試檔案啰~
            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

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

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

            scripts 
            在執(zhí)行之前,最怕的就是出現(xiàn)問(wèn)題了!那么我們?nèi)绾?/span> debug 呢?有沒(méi)有辦法不需要透過(guò)直接執(zhí)行該 scripts 就可以來(lái)判斷是否有問(wèn)題呢?。亢呛?! 當(dāng)然是有的!我們就直接以 bash 的相關(guān)參數(shù)來(lái)進(jìn)行判斷吧!
            [root@linux ~]# sh [-nvx] scripts.sh
            參數(shù):
            -n  
            :不要執(zhí)行 script,僅查詢語(yǔ)法的問(wèn)題;
            -v  
            :再執(zhí)行 sccript 前,先將 scripts 的內(nèi)容輸出到屏幕上;
            -x  
            :將使用到的 script 內(nèi)容顯示到屏幕上,這是很有用的參數(shù)!
            范例:

            范例一:測(cè)試 sh16.sh 有無(wú)語(yǔ)法的問(wèn)題?
            [root@linux ~]# sh -n sh16.sh 
            若語(yǔ)法沒(méi)有問(wèn)題,則不會(huì)顯示任何信息!

            范例二:將 sh15.sh 的執(zhí)行過(guò)程全部列出來(lái)~
            [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 的好方法,他可以將所有有執(zhí)行的程序段在執(zhí)行前列出來(lái),
            如果是程序段落,則輸出時(shí),最前面會(huì)加上 + 字號(hào),表示他是程序代碼而已,
            實(shí)際的輸出則與 standard output 有關(guān)啊~如上所示。

             
            在上面的范例二當(dāng)中,我們可以透過(guò)這個(gè)簡(jiǎn)單的參數(shù) -x 來(lái)達(dá)成 debug 的目的,這可是一個(gè)不可多得的參數(shù), 通常如果您執(zhí)行 script 卻發(fā)生問(wèn)題時(shí),利用這個(gè) -x 參數(shù),就可以知道問(wèn)題是發(fā)生在哪一行上面了!

            熟悉 sh 的用法,將可以使您在管理 Linux 的過(guò)程中得心應(yīng)手!至于在 Shell scripts 的學(xué)習(xí)方法上面,需要『多看、多模 仿、并加以修改成自己的樣式!』 是最快的學(xué)習(xí)手段了!網(wǎng)絡(luò)上有相當(dāng)多的朋友在開(kāi)發(fā)一些相當(dāng)有用的 scripts ,若是您可以將對(duì)方的  scripts 拿來(lái),并且改成適合自己主機(jī)的樣子!那么學(xué)習(xí)的效果會(huì)是最快的呢!

            另外,我們 Linux 系統(tǒng)本來(lái)就有很多的啟動(dòng) script ,如果您想要知道每個(gè) script 所代表的功能是什么? 可以直接以  vi 進(jìn)入該 script 去查閱一下,通常立刻就知道該 script 的目的了。 舉例來(lái)說(shuō),我們的 Linux 里頭有個(gè)文件名稱為:  /etc/init.d/portmap ,這個(gè) script 是干嘛用的? 利用 vi 去查閱最前面的幾行字,他出現(xiàn)如下信息:
            # 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

             
            簡(jiǎn)單的說(shuō),他是被用在 NFS  NIS 上面的一個(gè)啟動(dòng) RPC  script , 然后我們?cè)倮?/span> http: //www.google.com.tw 去搜尋一下 NFS, NIS  RPC , 立刻就能夠知道這個(gè) script 的功能啰~所以,下次您發(fā) 現(xiàn)不明的 script 時(shí), 如果是系統(tǒng)提供的,那么利用這個(gè)檢查的方式,一定可以約略了解的啦! 加油的啰~ ^_^

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



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

            請(qǐng)自行建立一支程序,該程序可以用來(lái)計(jì)算『您還有幾天可以過(guò)生日』???? 
            #!/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

            讓使用者輸入一個(gè)數(shù)字,程序可以由 1+2+3... 一直累加到使用者輸入的數(shù)字為止。 
            #!/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"

            撰寫(xiě)一支程序,他的作用是: 1.) 先查看一下 /root/test/logical 這個(gè)名稱是否存在; 2.) 若不存在,則建立一個(gè)檔 案,使用 touch 來(lái)建立,建立完成后離開(kāi); 3.) 如果存在的話,判斷該名稱是否為檔案,若為檔案則將之刪除后建立一個(gè)檔案,檔名為  logical ,之后離開(kāi); 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 里面以 : 來(lái)分隔,第一欄為賬號(hào)名稱。請(qǐng)寫(xiě)一只程序,可以將 /etc/passwd 的第一欄取出,而且每一欄都以一行字符串『The 1 account is "root" 』來(lái)顯示,那個(gè) 1 表示行數(shù)。 
            #!/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

            posted on 2008-03-16 18:40 隨意門(mén) 閱讀(500) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            日本精品久久久久中文字幕8| 久久国产精品无| 久久99国产综合精品| 久久精品人妻一区二区三区| 人妻无码αv中文字幕久久琪琪布 人妻无码精品久久亚瑟影视 | 久久人人爽人人爽人人爽| 久久黄视频| 77777亚洲午夜久久多喷| 亚洲人成无码www久久久| 久久久久国产一区二区| 狠狠色狠狠色综合久久| 人人狠狠综合久久亚洲婷婷| 精品伊人久久久| 四虎国产精品免费久久5151| 久久久久亚洲国产| 欧美精品一区二区精品久久 | 亚洲精品午夜国产VA久久成人| 性做久久久久久免费观看| 日韩久久久久中文字幕人妻 | 久久午夜福利电影| 日产久久强奸免费的看| 国产91色综合久久免费| 亚洲成人精品久久| 爱做久久久久久| 久久久久99精品成人片三人毛片| 亚洲国产欧洲综合997久久| 久久精品国产精品亚洲艾草网美妙| 亚洲综合伊人久久大杳蕉| 久久精品99无色码中文字幕| 国产精品久久久久天天影视| 国产精品99久久久精品无码 | 国产色综合久久无码有码| 久久香蕉综合色一综合色88| 日韩精品久久久久久久电影蜜臀 | 伊人久久大香线蕉影院95| 亚洲午夜无码久久久久| 色99久久久久高潮综合影院| 青青草国产成人久久91网| 久久婷婷成人综合色综合| 久久亚洲sm情趣捆绑调教| 午夜精品久久久久久久无码|