1. 程式人生 > >shell程式設計之處理使用者輸入

shell程式設計之處理使用者輸入

目錄

讀取引數

測試引數

抓取引數

③移動變數

④處理選項

基本的讀取

超時

前言

>>>目前為止,我們涉及到的知識包括如何編寫指令碼,處理資料、變數和檔案

>>>bash shell提供了不同方法來從使用者獲取資料,包括命令列引數,命令列選項,以及從鍵盤讀取輸入等

①命令列引數

讀取引數

>>>bash shell會將一些稱為位置引數(positional parameter)的特殊變數分配給輸入到命令列中的所有引數

>>>當需要輸入多個命令列引數,需要在命令列上每個引數用空格隔開

案例

[[email protected] test]$ cat parameter.sh
#!/bin/bash
echo "file_name=$0"
echo "parameter1=$1"
echo "parameter2=$2"
[[email protected] test]$ bash parameter.sh para_1 para_2
file_name=parameter.sh
parameter1=para_1
parameter2=para_2

說明

>>>位置引數變數是標準的數字,$0是程式名parameter.sh,$1是第一個引數para_1,$2是第二個引數para_2

>>>變數在第9個之後變數最好用大括號括起來 ${10}

>>>如果引數含有空格,則需要將引數用引號引起來,否則會當做兩個變數使用

測試引數

>>>在shell指令碼使用命令列引數時,如果指令碼沒有加引數可能會出問題,為了避免此情況,      在使用引數前,可以先用test命令測試引數是否存在

案例

[[email protected] test]$ cat parameter.sh
#!/bin/bash
if [ -z "$1" ]                #使用test命令"-z"測試$1字串是否為0
then
        echo "usage:bash $0 para_1"    #$1字串為0的話的話,提示使用者該以什麼格式輸入,並退出
        exit
else
        echo "Great,parameter1=$1"
fi
[
[email protected]
test]$ bash parameter.sh usage:bash parameter.sh para_1 [[email protected] test]$ bash parameter.sh hello Great,parameter1=hello

②特殊變數——記錄命令列引數

獲取位置引數的個數:使用特殊變數$#

     可以在指令碼任何地方使用這個變數,即用法用普通變數

案例

[[email protected] test]$ cat parameter.sh
#!/bin/bash
echo "count of parameter : $# "
[[email protected] test]$ bash parameter.sh
count of parameter : 0
[[email protected] test]$ bash parameter.sh 1 2 3
count of parameter : 3

案例:在使用引數前測試引數的總數,並測試引數是否為空

[[email protected] test]$ cat parameter.sh
#!/bin/bash
if [ $# -ne 2 ]
then
        echo "Usage:bash $0 parameter1 parameter2"
else
        if [ -z $1 ] || [ -z $2 ]
        then
                echo "error:check the parameter"
        else
                echo "Graet parameter1=$1,parameter2=$2"
        fi
fi
[[email protected] test]$ bash parameter.sh
Usage:bash parameter.sh parameter1 parameter2
[[email protected] test]$ bash parameter.sh hello ""
error:check the parameter
[[email protected] test]$ bash parameter.sh hello world
Graet parameter1=hello,parameter2=world

命令列最後一個引數: ${!#}

[[email protected] test]$ cat parameter.sh
#!/bin/bash
echo "the last parameter is ${!#}"
[[email protected] test]$ bash parameter.sh 1 2 3
the last parameter is 3

抓取引數

>>>需求:將命令列引數全部抓取下來,然後再去遍歷

>>>思路:bash shell提供了連個變數$*[email protected]區隊所有引數快速訪問

說明:

>>>$*是將命令列上提供的所有引數當做單個單詞儲存,即將所有引數當做一個整體的變數

>>>$@是將命令上提供的所有引數當做一個個獨立的引數,即當做一個列表,會單獨處理每個引數

案例

[[email protected] test]$ cat parameter.sh
#!/bin/bash
#testing $* and [email protected]
echo "Using the \$* method: $*"
echo "Using the \[email protected] method: [email protected]"
[[email protected] test]$ bash parameter.sh hello world
Using the $* method: hello world
Using the [email protected] method: hello world

         從表面上看,兩個變數產生的輸出是一樣的,都顯示了所有命令列引數

         下面的案例給出二者的差異

案例

[[email protected] test]$ cat parameter.sh
#!/bin/bash
count=1
for i in "$*"
do
        echo "\$* parameter #$count : $i"
        count=$[ $count + 1 ]
done
count=1
for j in "[email protected]"
do
        echo "\[email protected] parameter $count : $j"
        count=$[ $count + 1 ]
done
[[email protected] test]$ bash parameter.sh hello world
$* parameter 1 : hello world
[email protected] parameter 1 : hello
[email protected] parameter 2 : world

注意:[email protected]$*最好用引號引起來,否則輸出會有差異

③移動變數

>>>bash shell提供了shift命令來操作命令列引數根據它們的相對位置來移動命令列引數

>>>此方法在你不知道有多少引數是個不錯的選擇,你可以只操作第一個引數,移動引數,然後繼續操作第一個引數

案例

[[email protected] test]$ cat shift.sh
#!/bin/bash
count=1
while [ -n "$1" ]
do
        echo "parameter $count: $1"
        count=$[ $count + 1 ]
        shift
done
[[email protected] test]$ bash shift.sh a b c d
parameter 1: a
parameter 2: b
parameter 3: c
parameter 4: d

>>> shift預設步長為1,引數左移1位,若為shift 2,步長為2

案例

[[email protected] test]$ cat shift.sh
#!/bin/bash
count=1
while [ -n "$1" ]
do
        echo "parameter $count: $1"
        count=$[ $count + 1 ]
        shift 2
done
[[email protected] test]$ bash shift.sh 1 2 3 4 5 6 7 8
parameter 1: 1
parameter 2: 3
parameter 3: 5
parameter 4: 7

注意:執行此指令碼不能傳入奇數個命令列引數,否則會造成死迴圈

>>>使用shift命令的時候要小心,如果引數被移除了,這些值就會被丟棄了,無法再恢復

[[email protected] test]$ cat shift.sh
#!/bin/bash
count=1
while [ -n "$1" ]
do
        echo "parameter $count: $1"
        count=$[$count+1]
        shift
done
echo""
echo "$*"
[[email protected] test]$ bash shift.sh  a b c d
parameter 1: a
parameter 2: b
parameter 3: c
parameter 4: d

說明:當我執行完shift命令後,再去echo命令列引數,輸出為空,即原來的引數被丟棄了

④處理選項

>>>bash命令後面的選項是在單破折號後的字母,他能改變命令的行為

>>>處理簡單選項可以使用while迴圈和case語句

處理簡單選項

案例

[[email protected] test]$ cat option.sh
#!/bin/bash
while [ -n "$1" ]
do
        case "$1" in
                -a) echo "Found the option -a";;
                -b) echo "Found the option -b";;
                -c) echo "Found the option -c";;
                *) echo "$1 is not an option";;
        esac
        shift
done
[[email protected] test]$ bash option.sh -a -b -c -d
Found the option -a
Found the option -b
Found the option -c
-d is not an option

分離引數和選項

>>>在執行指令碼的時候,同時用到選項和引數的情況下,如何將二者分開

>>>使用特殊字元雙破折號(--)即shell會用雙破折號表明選項列表結束,         在雙破折號之後,指令碼就可以將剩下的命令列引數當引數處理

案例

[[email protected] test]$ cat option.sh
#!/bin/bash
while [ -n "$1" ]
do
        case "$1" in
                -a) echo "Found the option -a";;
                -b) echo "Found the option -b";;
                -c) echo "Found the option -c";;
                --) shift
                        break;;
                *) echo "$1 is not an option"
        esac
        shift
done
count=1
for i in "[email protected]"
do
        echo "parameter $count = $i"
        count=$[ $count + 1 ]
done
[[email protected] test]$ bash option.sh -a -b -c -- hello world
Found the option -a
Found the option -b
Found the option -c
parameter 1 = hello
parameter 2 = world

說明:break命令之前的shift命令,是用來移除雙破折號,避免出現在引數中

⑤獲得使用者輸入——read命令

>>>當需要在指令碼執行時,實現人與指令碼的互動,即為實時獲得使用者的輸入,          比如寫一個用來獲得使用者實時輸入的密碼的指令碼          bash shell提供了一個命令:read命令,解決了我們的需求

基本的讀取

>>>read命令從標準輸入(鍵盤)或另一個檔案描述符中接受輸入,在收到輸入後,raad命令會將資料放進一個變數

案例:

[[email protected] test]$ cat read.sh
#!/bin/bash
echo -n "Please input your username:"
read username
echo "-----------"
echo "Welcome,$username!"
[[email protected] test]$ bash read.sh
Please input your username:bei
-----------
Welcome,bei!

注意:倒數第三行的"bei"是我自己在鍵盤上敲的,即標準輸入,然後放進變數username,在指令碼後面使用

         echo-n選項把文字字串和命令輸出顯示在同一行,即該選項不會在字串末尾輸出換行符

案例:使用-p選項,直接在read命令列指定提示符

[[email protected] test]$ cat read.sh
#!/bin/bash
read -p "Please input your username: " username
echo "-----------"
echo "Welcome,$username"
[[email protected] test]$ bash read.sh
Please input your username: bei
-----------
Welcome,bei

超時

>>>指令碼啟動後,執行read命令時,若使用者遲遲未輸入,指令碼會一直苦等著

>>>如果想讓使用者是否有輸入,指令碼都會繼續往下執行,可以使用-t選項來制定一個定時器

>>>當計時器到期後,read命令會返回一個非零退出狀態碼

案例

[[email protected] test]$ cat read.sh
#!/bin/bash
if read -t 5 -p "Please input your username: " username
then
        echo "Welcome,$username"
else
        echo "Sorry,you are too late to input your username."
fi
[[email protected] test]$ bash read.sh
Please input your username: Sorry,you are too late to input your username.
[[email protected] test]$ bash read.sh
Please input your username: bei
Welcome,bei

隱藏方式讀取

>>>需求:當希望在螢幕輸入的內容,不想被“顯示”在螢幕上,比如在輸入密碼的時候

>>>方法:使用-s選項,該選項會避免將傳給read命令的資料顯示在顯示器上

(實際上,資料會被顯示,只是read命令會將文字顏色設成跟背景色一樣)

案例

[[email protected] test]$ cat read.sh
#!/bin/bash
read -t 5 -p "Please input your username: " username
read -t 5 -s -p "Please input your password: " password
echo ""
echo "Welcome,$username,your password is $password"
[[email protected] test]$ bash read.sh
Please input your username: bei
Please input your password:
Welcome,bei,your password is hahahaha

從檔案中讀取

>>>使用read命令讀取Linux系統上檔案裡儲存的資料,每次呼叫read命令,都會從檔案中讀取一行文字

>>>當檔案中再沒有內容時,read命令會退出並返回非零退出狀態碼

>>>read命令從檔案讀取輸入——cat $file | while read line

案例

[[email protected] test]$ cat date
IP1 1.1.1.1
IP2 192.168.1.1
IP6 2.2.2.2
IP9 172.16.1.1
[[email protected] test]$ cat read.sh
#!/bin/bash
count=1
read -p "Input the file you want to read:" file
cat $file | while read line
do
        echo "line $count : $line"
        count=$[ $count + 1 ]
done
echo "Finished processing the file $file"
[[email protected] test]$ bash read.sh
Input the file you want to read:./date
line 1 : IP1 1.1.1.1
line 2 : IP2 192.168.1.1
line 3 : IP6 2.2.2.2
line 4 : IP9 172.16.1.1
Finished processing the file ./date

說明:

>>>cat命令的輸出內容通過管道符傳遞作為read的輸入內容

>>>當檔案讀取完最後一行,read命令返回一個非零狀態碼,while迴圈結束

說明:

>>>以上內容是本人學習的總結

>>>如還有錯誤,請留言,指正

>>>亦可分享自己的想法,互相學習