《Linux命令列與shell指令碼編程大全》 第十三章 學習筆記

來源:互聯網
上載者:User

第十三章:處理使用者輸入

命令列參數
讀取參數
bash shell會將一些稱為位置參數(positional parameter)的特殊變數分配給命令列輸入的所有參數
甚至包括程式名
$0:程式名(程式的絕對路徑),可以對$0使用basename函數(basename $0),它只返回程式名
$i(9>i>0):第i個參數
如果需要的參數多於9個,那麼只需${10},這樣既可
如果指令碼需要參數,但是執行的時候並沒有輸入參數,執行的時候則會得到錯誤

if [ -n "$1" ]……

應該先檢查是否有參數,然後再做處理

特殊參數變數
$#:參數數量
${!#}:最後一個參數。花括弧({})中不允許使用貨幣符號($)這裡使用驚嘆號(!)

所以下面的代碼是錯誤的

#!/bin/bashecho We have "$#" "parameter(s)"echo The last parameter is "${$#}" # wrong wayecho The last parameter is "${!#}" # right way

執行結果:

$ param_test 1 1 1 5We have 4 parameter(s)The last parameter is 1535The last parameter is 5

注意:當命令列沒有任何參數時,$#返回0,而${!#}返回函數名

提取命令列上的所有參數
$*
將命令列上提供的所有參數當做1個單詞儲存
$@
所有參數的集合

#!/bin/bashecho "\$* and \$@ test"echo "\$* is:"$* #這裡兩個輸出結果是一樣的echo "\$@ is:"$@ #count=0for var in "$*"do    count=$[$count+1]    echo "$count:"$vardoneecho "\$* done."count=0for var in "$@"do    count=$[$count+1]    echo "$count:"$vardoneecho "\$@ done."

輸出結果:

$* and $@ test$* is:a b c$@ is:a b c1:a b c$* done.1:a2:b3:c$@ done.

移動資料
shift

將每個變數的位置都提前一個,$0不變,$1被移除。

count=1while [ -n "$1" ]do    echo "Paramter #$count=$1"    count=$[$count + 1]    shiftdone

注意:當參數被移除之後,無法恢複。

 

處理選項

while [-n $1 ]do    case "$1" in    -a) echo "Found the -a option" ;;    -b) echo "Found the -b option" ;;    *) echo "$1 is not a option" ;;    esac    shiftdone

分離參數和選項

Linux利用雙破折線(--)表明選項結束。

#!/bin/bashwhile [ -n "$1" ]do    case "$1" in    -a) echo "Found option a";;    -b) echo "Found option b";;    --) shift         break;;#跳出while,而不是case    *) echo "$1 not a option";;    esac    shiftdonefor p in $@do    echo "$p is a param ."done

處理帶值的選項
#!/bin/bashwhile [ -n "$1" ]do    case "$1" in    -a) echo "option a" ;;    -b) echo "option b. $2 is a param." #如果找到選項b,那麼此時$2就應該是選項b的值        shift;; #p281頁,原文為shift 2,實際不需要,因為並沒有break出迴圈    --) shift         break;;    -c) echo "option c" ;;    *) echo "$1 is not a option. ";;    esac    shiftdone
getopt 文法: getopt options optstring parametersoptstring中列出所有選項,帶值選項要在字母后加冒號(:),如果參數中包含無效參數,那麼會給出錯誤資訊
$ getopt ab:cd -a -b pb -cde p1 p2getopt: invalid option -- 'e' -a -b pb -c -d -- p1 p2
-q:屏蔽錯誤報表
$ getopt -q ab:cd -a -b pb -cde p1 p2 -a -b 'pb' -c -d -- 'p1' 'p2'

set -- command:set會將命令列參數替換為set命令列的值。set -- `getopt ab:cd "$@"`getopt將參數格式化好了之後,由set替換掉命令列原始參數。將下面指令碼儲存到檔案getopt_test中

#!/bin/bashset -- `getopt a:b:c "$@"`echo "param = $@"while [ -n "$1" ]do    case "$1" in      -a) echo "found option a and param = $2"          shift ;;     -b) echo "found option b and param = $2"         shift ;;     -c) echo "found option c, no param." ;;     --) ;;     *) echo "what's this?"         break ;;    esac    shiftdone

下面是運行結果

$ getopt_test -a test -b test -egetopt: invalid option -- 'e'param = -a test -b test --found option a and param = testfound option b and param = test
可以看出, getopt 可以識別出未知選項但是,它還是有些不足 下面是一個沒有正確提供選項的例子
$ getopt_test -a -b -cparam = -a -b -c --found option a and param = -bfound option c, no param.

這裡將-b識別為-a的參數了,當然這是因為使用者輸入不正確導致的。但是getopt並沒有正確的識別出來

再看一個參數中含有空格的例子
$ getopt_test -a "x y"param = -a x y --found option a and param = xwhat's this?
顯然這裡getopt錯把"x y"當成了兩個參數/選項最後一個問題,我們可以用下面的命令解決  getopts 文法: getopts optstring variable getopts用到的兩個環境變數 OPTARG:如果選項需要跟著有一個參數值,那麼此變數就儲存這個參數值 OPTIND:儲存getopts正在處理的參數的位置 注意:如果想屏蔽錯誤訊息,需要在optstring前面加冒號,而不是使用-q getopts將當前參數儲存在命令列中定義的variable 每調用一次getopts,它只處理命令列中的一個參數,處理完所有參數後,它會退出並返回一個大於0的退出狀態代碼
#!/bin/bashwhile getopts abc:d optdo    case $opt in    a) echo "option -a found";;    b) echo "option -b found";;    c) echo "option -c found and param = $OPTARG";;    d) echo "option -d found";;    ?) p=$[$OPTIND-1]        echo "what's this? "${!p}        echo "what's this? "$opt;;    esacdone

這裡與getopt不同,getopts會自動移出“-”,所以case中就不要加“-”了輸出結果

$ param_test -a -b -c "a param" -d -eoption -a foundoption -b foundoption -c found and param = a paramoption -d found./param_test: illegal option -- ewhat's this? -ewhat's this? ?
getopts將不認識的選項一律以問號輸出,所以最後一行我們會多看到一個問號  將選項標準化下面是一些命令中選項的常用的含義(原文為通用,其實並不是很通用)
選項 描述
-a 顯示所有對象
-c 產生一個計數
-d 指定一個目錄
-e 擴充一個對象
-f 指定讀取資料的檔案
-h 顯示命令的協助資訊
-i 忽略文字大小寫
-l 產生輸出的長格式版本
-n 使用非互動模式(批量)
-o 指定將所有輸出重新導向到的輸出檔案
-q 以安靜模式運行
-r 遞迴處理目錄和檔案
-s 以安靜模式運行
-v 產生詳細輸出
-x 排除某個對象
-y 對所有問題回答yes
  獲得使用者輸入 read:接受從標準輸入(鍵盤)或另一個檔案描述符的輸入在收到輸入後,read命令會將資料放進一個標準變數 
#!/bin/bashecho -n "Enter your name:"read nameecho "Hello $name"read -p "Enter your age:" ageecho "You are $age years old..."

echo的-n選項會移除末尾的換行-p可以指定提示句可以將輸入儲存到多個變數中,如果變數表中變數不夠用,之後的輸入將都儲存到最後一個變數中

read -p "What would you like to eat?" f1 f2echo "you would like to eat $f1 and $f2"

如果不給read指定變數,那麼read到的內容將儲存到REPLY環境變數中-t:指定逾時時間,單位為秒逾時之後,read會返回一個非0的退出狀態代碼

#!/bin/bashread -n1 -p "Are you a boy?" answerechocase $answer iny|Y) echo "Oh, you're a boy.";;N|n) echo "Oh, you are not a boy.";;esac

-n number當輸入達到number個字元的時候,read結束,並將結果賦給變數上面樣本中,當輸入了一個字元後,程式將自動運行,不需要使用者輸入斷行符號確定-s:隱藏方式讀取(其實是將文字顏色設定為背景色而已)

#!/bin/bashwhile read -n1 -s cdo    echo -n "*"done

輸入的字元以*替代,當然,上面的例子中,如果輸入退格鍵,*號是不會刪除,依然繼續增加……

從檔案中讀取 read將一次讀取檔案中的一行,當讀取完畢的時候,read會退出並返回非0狀態代碼
#!/bin/bashcount=0while read linedo    count=$[ $count + 1 ]done < $1echo "$count line(s) in all."

如果用管道給read傳送資料,將會開啟一個子shell,這樣在while外再查看$count,會發現它依然為0

 

轉貼請保留以下連結

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.