shell腳本學習五(處理用戶輸入)

處理用戶輸入:

 1、命令行參數

       向shell腳本傳遞數據的最基本的方法是使用命令行參數,命令行參數允許在運行腳本時向命令行添加數據。

2、讀取參數

       bash shell中有一些特殊變量叫做 位置參數,位置變量參數是標準的數字:$0 是程序名,$1 是第一個參數,$2是第二個參數,以此類推,直到第九個參數$9 ,$0~$9 可以定義在腳本中,通過命令行向其賦值。

          

          

 

          當向shell腳本傳遞字符串時,如果希望將多個字符串當做一個變量,需要加上單引號 ' '

          .

          

          如果腳本需要的命令行參數不止9個,你仍然可以處理,但是需要稍微修改一下變量名,在第9個變量之後,你必須在變量數字周圍加上花括號,比如  ${ 10 }

          

          

3、讀取腳本名

         可以使用$0 參數獲取shell在命令行啓動的腳本名,這在編寫多功能工具時很方便

           (同樣的腳本如果需要根據不同的腳本名執行不同的功能時,就需要用到 $0 了)

             

             

            但是出現一個潛在的問題,如果使用另一個命令來執行腳本,命令會和腳本名混合在一起出現出現在$0參數中

           

               這不是唯一的問題,當傳給$0 變量的實際字符串不僅僅是腳本名,而是完整的腳本路徑時,變量$0就會使用整個路徑

           

        解決這一問題可以使用basename命令,它會返回不包含路徑的腳本名

          

         

        現在可以結和$0 和basename 來編寫基於腳本名執行不同功能的腳本了。

           

           

4、 特殊參數變量:

           $# 含有腳本運行時攜帶的命令行參數的個數,可以在腳本中任何地方使用這個特殊變量,就跟普通變量一樣

                           

                         

     基於$#實現特定功能:

            

           

      5、 抓取命令行上提供的所有參數: $*     $@

              區別就是: $*       會將所有參數當成單個參數

                                 $@     會單獨處理每個參數

              

              

 6、移動變量:

         下面這個腳本通過shift命令實現了使用一個參數完成多個數據的遍歷,當第一個參數的長度爲0時,循環結束。測試完第一個參數後,shift命令會將所有的參數的位置移動一個位置。

 ( 要注意的是:使用shift命令時,一定要小心,如果某個參數被移出,它的值就被丟棄了,無法再恢復 )

               

                   留個小疑問:爲什麼 -n  判斷$1 是否爲0時要加上雙引號?

              

          shift 也可以一次性移動多個位置,例如: shift  2  一次移動2 

               注意:我們來看下面這個例子,我特意檢測了一下當只有 一個特殊變量$1卻有多個參數時shift在while和case中的具體如何工作的

                   

            此時我們在腳本中先不使用shift,看看有多個選項時情況如何:

          ( 我們發現它會進行一個死循環,一直輸出-a 選項,不能夠讀取之後的選項 )

               

             此時我們加上shift,重新運行你會發現一切正常

                 

                 

             這說明 在while 和 case 中 ,每執行完一個選項,就需要shift一次,將原來的選項移出以此來讀取新的選項,這對我們理解接下來的 帶參數的選項很有幫助   

7、 處理選項:

                  

            用一組普通的選項和參數來運行這個腳本,結果說明在處理時腳本認爲所有的命令行參數都是選項

                       

          當腳本遇到雙破折線時,它會停止處理選項,並將剩下的參數都當做命令行參數。

                   

8、處理帶值的選項

          有的選項會帶上一個額外的參數值,當命令行選項要求額外的參數時,腳本必須能檢測到並正確處理。

         ( 這種情況下,如$ ./testing.sh  -a test1  -b  -c -d   test2 ) 

              

(  此處執行此腳本帶有命令行參數爲:  ./difOption.sh  -a  -b  test  -c   

                如上文所說,先將 -a 存入$1變量,執行完-a 選項之後執行do的shift命令將-a 選項移出,遇到-b 選項將其存入$1,因爲-b選項帶有參數test,所以需要另外準備一個變量$2來存入參數值test,執行完-b選項之後,在-b選項之後執行一次shift將$1中的-b值移出,再在while循環最後執行一次shift將被移入$1的參數test也移出(所以此處是執行了兩次shift ),最後在將-c選項讀入$1變量,自後執行完畢退出)

                     

 9、使用getopt命令

                9.1 命令的格式

            getopt命令可以接受一系列任意形式的命令行選項和參數,並自動將它們轉換成適當的格式,其命令格式如下:

                getopt   optstring   parameters

             optstring 定義了命令行有效的選項字母,還定義了哪些選項字母需要參數值,在optstring中列出你要在腳本中用到的每個命令行選項字母,然後,在每個需要參數值的選項字母之後加一個冒號。getopt命令會基於你定義的optstring解析提供的參數

             

例如:  $ getopt  ab:cd  -a  -b  test1 -cd  test2   test3

                           (      -a  -b  test1   -c  -d   --  test2 test3    ) 

      optstring定義了四個有效選項字母:a、b、c、d,冒號(:)被放在了字母b後面,因爲b選項需要一個參數值,當getopt命令運行時,它會檢查提供的參數列表

( -a  -b test1  -cd  test2  test3 ),並基於提供的optstring進行解析。注意,它會自動將-cd 選項分成兩個單獨的選項,並插入雙破折線來分割行中的額外參數

如果指定了一個不在optstring中的選項,默認情況下,getopt會產生一條錯誤消息。

例如: $ getopt   ab:cd   -a  -b  test1   -cde   test2 test3 

        9.2 在腳本中使用getopt

              set  -- $( getopt -q  ab:cd  "$@" )

             雙破折線是set命令的的選項之一,它會將命令行參數替換成set命令的命令行值,然後該方法會將原始腳本的命令行參數傳給getopt命令,之後再將getopt命令的輸出傳給set命令,用getopt格式化後的命令行參數來替換原始的命令行參數。

               

                

               getopt命令並不擅長處理帶空格和引號的參數值,它會將空格當做參數分隔符,而不是根據雙引號將兩者當做一個參數,我們可以使用getopts來解決這個問題。

 10、使用getopts命令

               每次調用getopts命令時,它一次只處理命令行上檢測到的一個參數,處理完所有的參數後,他會推出並返回一個大於0的退出狀態碼,這讓他非常適合用解析命令行所有參數的循環中。

                 getopts   optstring   variable   

                 有效的選項字母都會列在optstring 中,如果選項字母要求有個參數值,就加一個冒號。要去掉錯誤消息的話,可以在optstring 之前加一個冒號。getopts命令將當前參數保存在命令行中定義的variable中。

                 getopts命令會用到兩個環境變量,如果選項需要跟一個參數值,OPTARG環境變量就會保存這個值,OPTIND環境變量保存了參數列表中getopts 正在處理的參數位置,這樣你就能在處理完選項之後繼續處理其他命令行參數了。

             

        while語句定義了getopts命令,指明瞭要查找哪些命令行選項,以及每次迭代中存儲它們的變量名(opt),getopts命令解析命令行選項時會移除開頭的單破折線( 即運行腳本時的命令行參數的-a等。。),所以在case定義中不用單破折線

                  

               getopts對新手來說有幾個好用的功能

              ①可以在參數值中包括空格

                  

               ②可以將選項字母和參數值放在一起使用,而不用加空格

                      

              ③除此之外getopts還能夠將命令行上找到的所有未定義的選項統一輸出成問號

                    

                     

           getopts命令知道何時停止處理選項,並將參數留給你處理。在getopts處理每個選項時,它會將OPTIND環境變量值增一,在getopts完成處理時,你可以使用shift命令和OPTIND值來移動參數。

                    

                    

         現在你就擁有了一個能在所有shell腳本中使用的全功能命令行選項和參數處理工具

常用的linux命令選項 :

選項

描述

-a

顯示所有對象

-c

生成一個計數

-d

指定一個目錄

-e

擴展一個對象

-f

指定讀入數據的文件

--help

顯示命令的幫助信息

-i

忽略文本大小寫

-l

產生輸出的長格式文本

-n

使用非交互模式(批處理)

-o

將所有輸出重定向到的指定的輸出文件

-q

以安靜模式運行

-r

遞歸的處理目錄和文件

-s 

以安靜模式運行

-v

生成詳細輸出

-x

排除某個對象

-y

對所有問題回答yes

 11、獲得用戶輸入

            11.1  基本的讀取

                  read命令從標準輸入(鍵盤)或另一個文件描述符中接受輸入。在收到輸入後,read命令會將數據放進一個變量。

                  

                  

             此處的echo 使用了 -n選項,該選項不會在字符串末尾輸出換行符,允許腳本用戶緊跟其後輸入數據,而不是下一行,這讓腳本看起來更像表單

             實際上,read  的選項 -p 也允許直接在read命令行指定提示符

              

                  

             read命令會將提示符後輸入的所有數據分配給單個變量,要麼你就指定多個變量,輸入的每個數據值都會分配給變量列表的下一個變量,如果變量數量不夠,剩下的數據就全部分配給最後一個變量

             在read命令行中也可以不指定變量,如果是這樣,read命令會將它收到的任何數據都放進特殊環境變量REPLY中,REPLY環境變量會保存輸入的所有數據,可以在shell腳本中像其他變量一樣使用

           11.2  超時

              使用read命令時腳本很可能會一直苦等着腳本用戶的輸入,如果不管是否有數據輸入,腳本都必須繼續執行,你可以使用  - t  選項來指定一個計時器,-t 選項指定了read 命令等待輸入的秒數,當計時器過期後,read命令會返回一個非零退出狀態碼

                  

                   

              如果計時器過期,read命令會以非零退出狀態碼退出,可以使用if - then 或 while 循環這種標準的結構化語句來理清所發生的具體情況,在本例中,計數器過期時,if語句不成立,shell會執行else部分的命令

                也可以讓read命令來統計輸入的字符數,當輸入的字符達到預設的字符數時,就自動退出,將輸入的數據賦給變量

                   

                   

              本例中將-n 選項和值1一起使用,告訴read命令在接受單個字符後退出,只要按下單個字符回答後,read命令就會接受輸入並將它傳給變量,無需按回車鍵

              11.3  隱藏方式讀取

               有時候你需要從腳本用戶處獲得輸入,但是又不能在屏幕上顯示輸入信息,典型的例子就是輸入密碼,除此之外還有很多其他需要隱藏的數據類型。

               read命令的-s 選項可以避免在read 命令中輸入的數據出現在顯示器上(實際上,數據會被顯示,只是read命令會將文本顏色設成跟背景色一樣)

                  

                  

             11.4   從文件讀取

                   也可以用read命令來讀取linux系統上文件裏保存的數據,每次調用read命令,它都會從文件中讀取一行文本,當文件在沒有內容時,read命令會退出並返回非零退出狀態碼。

                   最常見的搭配是對文件使用cat 命令 ,將結果通過管道直接傳給含有read命令的while 命令

                      

                    

                 while循環會持續通過read命令處理文件中的行,直到read命令以非零退出狀態碼退出。       

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章