經過前幾篇文章的學習,咱們學會了shell的基本語法。在linux的實際操做中,咱們常常看到命令會有不少參數,例如:ls -al 等等,那麼這個參數是怎麼處理的呢? 接下來咱們就來看看shell腳本對於用戶輸入參數的處理。
java
bash shell可根據參數位置獲取參數。經過 $1 到 $9 獲取第1到第9個的命令行參數。$0爲shell名。若是參數超過9個,那麼就只能經過${}來獲取了, 例如獲取第10個參數,那麼能夠寫爲${10}。linux
示例一:shell
#!/bin/bash #testinput.sh echo "file name: $0" echo "base file name: $(basename $0)" echo "param1: $1" echo "param2: ${2}"
運行上面的的shellbash
./testinput.sh 12 34
最終獲得的結果以下:oop
file name: ./testinput4.sh學習
base file name: testinput4.sh命令行
param1: 12code
param2: 34字符串
成功的獲得文件名和命令行輸入的參數(命令行參數以空格分隔,若是參數包含了空格,那麼久必須添加引號了)get
$0默認會獲取到當前shell文件的名稱,可是,它也包含(./),若是你以完整路徑運行,那麼這還會包含目錄名。所以,上面經過basename命令來獲取單純的文件名$(basename $0)。
試想一下,假如咱們寫的shell的這個參數不少,那若是像上面那樣一個一個去獲取參數,那豈不是要寫瘋!下面就來看看如何解決這種狀況。
既然bash shell經過位置可獲取參數,那意味着若是咱們知道參數的總個數就能夠經過循環依次獲取參數。那麼如何獲取參數總個數呢?
在bash shell中經過 $# 可獲取參數總數。
示例:(循環獲取參數)
#!/bin/bash for (( index=0; index <= $#; index++ )) do echo ${!index} done
以上示例,咱們經過 $# 獲取總參數個數。而後經過循環獲取每一個位置的參數。注意: 按照正常的理解,上面的 ${!index} 應該是 ${$index}纔對, 對吧? 可是,因爲${}內不能再寫$符號,bash shell在這個地方是用了!符號,因此以上才寫爲了${!index}。
在bash shell中還能夠經過 $* 和 $@ 來獲取全部參數。可是這二者之間有着很大的區別:
$* 會將命令行上提供的全部參數看成一個單詞保存, 咱們獲得的值也就至關因而個字符串總體。
$@ 會將命令行上提供的全部參數看成同一字符串中的多個獨立的單詞。
可能文字看起來描述的不太清楚,那麼仍是經過示例來看兩者的區別吧:
#!/bin/bash #testinput.sh var1=$* var2=$@ echo "var1: $var1" echo "var2: $var2" countvar1=1 countvar2=1 for param in "$*" do echo "first loop param$countvar1: $param" countvar1=$[ $countvar1 + 1 ] done echo "countvar1: $countvar1" for param in "$@" do echo "second param$countvar2: $param" countvar2=$[ $countvar2 + 1 ] done echo "countvar2: $countvar2"
執行上面的示例:
./testinput.sh 12 34 56 78
上面示例的輸出結果爲:
var1: 12 34 56 78
var2: 12 34 56 78
param1: 12 34 56 78
countvar1: 2
param1: 12
param2: 34
param3: 56
param4: 78
countvar2: 5
經過上面的結果可見,直接輸出看起來兩者結果同樣,可是經過for循環就可看出兩者的區別了。上一篇文章咱們講到for循環會經過IFS定義的值進行分割,所以默認狀況下,若是咱們上面在for循環處不加引號,那麼根據IFS中所定義的空格分割,最終也會致使看不出兩者區別。
有時候,咱們在shell執行過程當中獲取用戶的輸入,以此與用戶進行交互。這是經過read命令來實現的。下面就來看看其用法:
示例一:
#!/bin/bash echo -n "yes or no(y/n)?" read choice echo "your choice: $choice"
運行以上示例,首先會輸出」yes or no(y/n)?「, 而後會等待用戶輸入(-n參數表示不換行,所以會在本行等待用戶輸入),當用戶輸入後,會把用戶輸入的值賦值給choice變量, 而後最終輸出 「your choice: (你輸入的內容)」。
事實上,咱們能夠不指定read後面的變量名,若是咱們不指定, read命令會將它收到的任何數據都放進特殊環境變量REPLY中。以下:
示例二:
#!/bin/bash echo -n "yes or no(y/n)?" read echo "your choice: $REPLY"
以上示例與示例一是等價的。
有時候,咱們須要用戶輸入多個參數,固然,shell是支持一次接受多個參數輸入的。
示例三:
#!/bin/bash read -p "what's your name?" first last echo first: $first echo last: $last
以上示例首先輸出「what's your name?」, 而後在本行等待用戶輸入(此處用read -p實現以上示例的echo -n + read命令的不換行效果),輸入的參數以空格分隔,shell會把輸入的值依次賦值給first和last兩個變量。若是輸入的值過多,假如我輸入了3個值,那麼shell會把剩下的值都賦值給最後一個變量(即第二三兩個的值都會賦值給last變量)。
細想一下,有個問題,假如用戶一直不輸入,怎麼辦?一直等待?
咱們能夠經過read -t 來指定超時時間(單位爲秒),若是用戶在指定時間內沒輸入,那麼read命令就會返回一個非0的狀態碼。
示例四:
#/bin/bash if read -t 5 -p "Please enter your name: " name then echo "Hello $name" else echo "Sorry, timeout! " fi
運行以上示例,若是超過5秒沒輸入,那麼就會執行else裏面的。
本篇簡單的介紹了shell的輸入參數以及接收用戶輸入。你們能夠觸類旁通,結合以前所學的基礎知識,能夠寫一些小的腳本應用了。
個人獨立博客: javafan.cn