【shell】shell編程(五)-讀取參數


  通過前幾篇文章的學習,我們學會了shell的基本語法。在linux的實際操作中,我們經常看到命令會有很多參數,例如:ls -al 等等,那么這個參數是怎么處理的呢? 接下來我們就來看看shell腳本對於用戶輸入參數的處理。

命令行參數處理

根據參數位置獲取參數

  bash shell可根據參數位置獲取參數。通過 $1 到 $9 獲取第1到第9個的命令行參數。$0為shell名。如果參數超過9個,那么就只能通過${}來獲取了, 例如獲取第10個參數,那么可以寫為${10}。

示例一:

#!/bin/bash
#testinput.sh
echo "file name: $0"
echo "base file name: $(basename $0)"
echo "param1: $1"
echo "param2: ${2}"

 

運行上面的的shell

./testinput.sh 12 34

 

最終得到的結果如下:

file name: ./testinput4.sh

base file name: testinput4.sh

param1: 12

param2: 34

成功的得到文件名和命令行輸入的參數(命令行參數以空格分隔,如果參數包含了空格,那么久必須添加引號了)

$0默認會獲取到當前shell文件的名稱,但是,它也包含(./),如果你以完整路徑運行,那么這還會包含目錄名。因此,上面通過basename命令來獲取單純的文件名$(basename $0)

試想一下,假如我們寫的shell的這個參數很多,那如果像上面那樣一個一個去獲取參數,那豈不是要寫瘋!下面就來看看如何解決這種情況。

另外,還有幾個特殊字符用來處理參數:

參數處理 說明
$# 傳遞到腳本的參數個數
$* 以一個單字符串顯示所有向腳本傳遞的參數。
如"$*"用「"」括起來的情況、以"$1 $2 … $n"的形式輸出所有參數。
$$ 腳本運行的當前進程ID號
$! 后台運行的最后一個進程的ID號
$@ 與$*相同,但是使用時加引號,並在引號中返回每個參數。
如"$@"用「"」括起來的情況、以"$1" "$2" … "$n" 的形式輸出所有參數。
$- 顯示Shell使用的當前選項,與set命令功能相同。
$? 顯示最后命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。

  上面重要的是$#和$?,$#可以獲取參數的格式,$?可用於判斷一個命令執行的狀態。

例如下面一個批量刪除用戶的腳本就是根據$?獲取上一個命令的執行狀態碼,然后判斷是否正確執行命令:

#!/bin/bash
#delete user batch
echo "please input username word to delete"
read word
#get All users like word*
users=`/usr/bin/grep ${word} /etc/passwd | awk -F: -v word1=${word} 'index($1,wo
rd1)>0 {print $1}'`
if [ "${users}" = '' ]
 then
        echo "user is does not exist!"
        exit 1
fi
for username in ${users}
do
        /usr/sbin/userdel -rf ${username} > /dev/null 2>/dev/null
done
if [ "0" = "$?" ]
        then
        echo "delete ok!"
else
        echo "delete failed!"
fi

 

 

讀取所有參數

方法一

既然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的輸入參數以及接收用戶輸入。大家可以舉一反三,結合之前所學的基礎知識,可以寫一些小的腳本應用了。

 

 

接下來可以學習shell編程六:http://www.cnblogs.com/qlqwjy/p/8683972.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM