第二十六課 LinuxShell編程四之處理用戶(hù)輸入

說(shuō)明:本文部分內(nèi)容均摘取自書(shū)籍《Linux命令行與shell腳本編程大全》,版權(quán)歸原作者所有?!禠inux命令行與shell腳本編程大全》(第三版)第十四章學(xué)習(xí)總結(jié)

第十四章:處理用戶(hù)輸入

本章內(nèi)容

傳遞參數(shù)
跟蹤參數(shù)
移動(dòng)變量
處理選項(xiàng)
將選項(xiàng)標(biāo)準(zhǔn)化
獲取用戶(hù)輸入

14.1 命令行參數(shù)

14.1.1 讀取參數(shù)

bash shell會(huì)將一些稱(chēng)為位置參數(shù)的特殊變量分配給輸入到命令行中的所有參數(shù)。

位置參數(shù)變量是標(biāo)準(zhǔn)的數(shù)字

$0是程序名
$1是第一個(gè)參數(shù)
$2是第二個(gè)參數(shù)
依次類(lèi)推,知道第九個(gè)參數(shù)$9

編寫(xiě)test1.sh腳本

#!/bin/bash

factorial=1
for (( number=1;number<=$1;number++ ))
do
    factorial=$[ $factorial * $number ]
done
echo The factorial of $1 is $factorial

執(zhí)行命令

./test1.sh 5

編寫(xiě)test2.sh腳本

#!/bin/bash

total=$[ $1 * $2 ]
echo The first paramter is $1.
echo The second paramter is $2.
echo Thetotal paramter is $total.

執(zhí)行命令

./test2.sh 2 5

編寫(xiě)test3.sh腳本

#!/bin/bash
echo Hello $1,glad to meet you.

執(zhí)行命令

./test3.sh 'Rich Blum'

如果腳本需要的命令行參超過(guò)9個(gè)時(shí),使用${10}形式獲取

編寫(xiě)test4.sh腳本

#!/bin/bash
total=$[ ${10} * ${11} ]
echo The tenth parameter is ${10}
echo The eleventh parameter is ${11}
echo The total is $total

執(zhí)行命令

./test4.sh 1 2 3 4 5 6 7 8 9 10 11 12

14.1.2 讀取腳本名

使用$0參數(shù)獲取shell在命令行啟動(dòng)的腳本名

編寫(xiě)test5.sh腳本

#!/bin/bash
echo The zero parameter is set to:$0

執(zhí)行命令

bash test5.sh 

使用basename命令獲取不包含路徑的腳本名

編寫(xiě)test5b.sh

#!/bin/bash
name=$(basename $0)
echo
echo The script name is:$name

使用這種方法來(lái)編寫(xiě)基于腳本名執(zhí)行不同功能的腳本

編寫(xiě)test6.sh腳本

#!/bin/bash
name=$(basename $0)

if [ $name = "addem" ]
then
    total=$[ $1 + $2 ]
elif [ $name = "multem" ]
then
    total=$[ $1 * $2 ]
fi

echo
echo The calculated value is $total

執(zhí)行命令

cp test6.sh addem
cp test6.sh multem
./addem 2 5
./multem 2 5

14.1.3 測(cè)試參數(shù)

腳本在使用參數(shù)前,需要檢查其中是否存在數(shù)據(jù)

編寫(xiě)test7.sh腳本

#!/bin/bash
if [ -n "$1" ]
then
    echo Hello $1,glad to meet you.
else
    echo "Sorry,you did not identify yourself."
fi

執(zhí)行命令

./test7.sh Rich
./test7.sh

14.2 特殊參數(shù)變量

14.2.1 參數(shù)統(tǒng)計(jì)

特殊變量$#含有腳本運(yùn)行時(shí)攜帶的命令行參數(shù)的個(gè)數(shù)

編寫(xiě)test8.sh腳本

#!/bin/bash
echo There were $# parameters supplied.

執(zhí)行命令

./test8.sh
./test8.sh 1 2 3 4 5
./test8.sh "Rich Blum"

編寫(xiě)test9.sh腳本

#!/bin/bash
if [ $# -ne 2 ]
then
    echo
    echo Usage:test9.sh a b
    echo
else
    total=$[ $1 + $2 ]
    echo
    echo The total is $total
    echo
fi

執(zhí)行命令

./test9.sh
./test9.sh 10
./test9.sh 10 15

獲取最后一個(gè)命令行參數(shù)變量

編寫(xiě)test10.sh腳本

#!/bin/bash
params=$#
echo
echo The total parameter is $params
echo The last parameter is ${!#}
echo

執(zhí)行命令

./test10.sh
./test10.sh 1 2 3
./test10.sh 1 2 3 4

14.2.2 抓取所有的數(shù)據(jù)

使用$*和$@變量來(lái)訪問(wèn)所有的參數(shù)
使用for命令遍歷這兩個(gè)變量時(shí)
$*變量會(huì)將所有參數(shù)當(dāng)成單個(gè)參數(shù)
$@變量會(huì)單獨(dú)處理每個(gè)參數(shù)

編寫(xiě)test11.sh腳本

#!/bin/bash
echo
echo "Using the \$* method:$*"
echo "Using the \$@ method:$@"
echo

執(zhí)行命令

./test11.sh rich barbara katie jseeica

編寫(xiě)test12.sh腳本

#!/bin/bash
echo
count=1
for param in "$*"
do
    echo "\$* parameter #Scount = $param"
    count=$[ $count + 1 ]
done
echo
count=1
for param in "$@"
do
    echo "\$@ parameter #Scount = $param"
    count=$[ $count + 1 ]
done

執(zhí)行命令

./test12.sh rich barbara katie jseeica

14.3 移動(dòng)變量

shift命令會(huì)根據(jù)所在的相對(duì)位置來(lái)移動(dòng)命令行參數(shù)

敲門(mén):使用shift命令的時(shí)候要小心。如果某個(gè)參數(shù)被移除,它的值就被丟棄了,無(wú)法再恢復(fù)

編寫(xiě)test13.sh腳本

#!/bin/bash
echo
count=1
while [ -n "$1" ]
do
    echo "Parameter #$count = $1"
    count=$[ $count+1 ]
    shift
done

執(zhí)行命令

./test13.sh rich barbara katie jessica

編寫(xiě)test14.sh腳本

#!/bin/bash
echo
echo "The original parameters: $*"
shift 2
echo "Here's the new first parameter: $1"

執(zhí)行命令

./test14.sh 1 2 3 4 5

14.4 處理選項(xiàng)

14.4.1 查找選項(xiàng)

1.處理簡(jiǎn)單選項(xiàng)

在提取每個(gè)單獨(dú)參數(shù)時(shí),用case語(yǔ)句來(lái)判斷某個(gè)參數(shù)是否為選項(xiàng)

編寫(xiě)test15.sh腳本

#!/bin/bash
echo
while [ -n "$1" ]
do
    case "$1" in
        -a) echo "Found the -a option" ;;
        -b) echo "Found the -b option" ;;
        -c) echo "Found the -c option" ;;
        *) echo "Found the an option" ;;
    esac
    shift
done

執(zhí)行命令

./test15.sh -a -b -c -d

2.分離參數(shù)和選項(xiàng)

Linux通過(guò)雙破折線(--)來(lái)區(qū)分選項(xiàng)和參數(shù)

編寫(xiě)test16.sh腳本

#!/bin/bash
echo
while [ -n "$1" ]
do
    case "$1" in
        -a) echo "Found the -a option" ;;
        -b) echo "Found the -b option" ;;
        -c) echo "Found the -c option" ;;
        --) shift
            break ;;
        *) echo "$1 is not an option" ;;
    esac
    shift
done
#
count=1
for param in $@
do
    echo "Parameter #count:$param"
    count=$[ $count+1 ]
done

執(zhí)行命令

./test16.sh -a -b -c test1 test2 test3
./test16.sh -a -b -c -- test1 test2 test3

3.處理帶值的選項(xiàng)

有些選項(xiàng)會(huì)帶上一個(gè)額外的參數(shù)值,腳本必須能夠檢測(cè)到并正確處理

編寫(xiě)test17.sh腳本

#!/bin/bash
echo
while [ -n "$1" ]
do
    case "$1" in
        -a) echo "Found the -a option" ;;
        -b) param="$2"
            echo "Found the -b option,with parameter value $param"
            shift ;;
        -c) echo "Found the -c option" ;;
        --)
            shift
            break ;;
        *) echo "$1 is not an option";;
    esac
    shift
done
#
count=1
for param in $@
do
    echo "Parameter #$count:$param"
    count=$[ $count+1 ]
done

執(zhí)行命令

./test17.sh -a -b test1 -d
./test17.sh -b test1 -a -d

14.4.2 使用getopt命令

getopt命令是一個(gè)在處理命令選項(xiàng)和參數(shù)時(shí)非常方便的工具。它能夠識(shí)別命令行參數(shù),從而在腳本中解析它們時(shí)更方便。

1.命令的格式

命令格式:getopt optstring parameters
命令說(shuō)明:getopt命令可以接受一系列任意形式的命令行選項(xiàng)和參數(shù)

敲門(mén):getopt命令有一個(gè)更高級(jí)的版本叫做getopts(注意這是復(fù)數(shù)形式)。getopts命令會(huì)在本章隨后部分降到。因?yàn)檫@兩個(gè)命令的拼寫(xiě)幾乎一摸一樣,所以很容易混淆,一定要小心。

命令演示:getopt ab:cd -a -b test1 -cd test2 test3
演示結(jié)果:-a -b test1 -c -d – test2 test3
演示說(shuō)明:optstring定義了四個(gè)有效選項(xiàng)字母:a,b,c和d。冒號(hào)(:)被放在了字母b后面,因?yàn)閎選項(xiàng)需要一個(gè)參數(shù)值。當(dāng)getopt命令運(yùn)行時(shí),它會(huì)檢查提供的參數(shù)列表(-a -b test1 -c -d – test2 test3),并基于提供的optstring進(jìn)行解析。注意,它會(huì)自動(dòng)將-cd選項(xiàng)分成兩個(gè)單獨(dú)的選項(xiàng),并插入雙破折線來(lái)分割行中的額外參數(shù)。

getopt說(shuō)明

如果指定了一個(gè)不在optstring中的選項(xiàng),getopt命令會(huì)產(chǎn)生一條錯(cuò)誤的消息
如果想忽略這條錯(cuò)誤消息,可以在命令后加-q選項(xiàng)
getopt命令選項(xiàng)必須出現(xiàn)在optstring之前
getopt命令并不擅長(zhǎng)處理帶空格和引號(hào)的參數(shù)值

2.在腳本中使用getopt

編寫(xiě)test18.sh腳本

#!/bin/bash
#
set -- $(getopt -q ab:cd "$@")
#
echo
while [ -n "$1" ]
do
    case "$1" in
        -a) echo "Found the -a option" ;;
        -b) param="$2"
            echo "Found the -b option, with parameter value $param"
            shift ;;
        -c) echo "Found the -c option" ;;
        -d) echo "Found the -d option" ;;
        --) shift
            break ;;
        *)  echo "$1 is not an option" ;;
    esac
    shift
done
#
count=1
for param in "$@"
do
    echo "Parameter #$count:$param"
    count=$[ $count+1 ]
done

執(zhí)行命令

./test18.sh -ac
./test18.sh -a -b test1 -cd test2 test3 test4

14.4.3 使用更高級(jí)的getopts

getopts命令(注意是復(fù)數(shù))內(nèi)建于bash shell。

命令格式:getopts optstring variable
命令說(shuō)明: optstring與 getopt命令中的optstring相同

使用OPTARG環(huán)境變量獲取選項(xiàng)的參數(shù)值

編寫(xiě)test19.sh腳本

#!/bin/bash
echo
while getopts :ab:c opt
do
    case "$opt" in
        a) echo "Found the -a option" ;;
        b) echo "Found the -b option, with value $OPTARG" ;;
        c) echo "Found the -c option" ;;
        *) echo "Unknown option: $opt" ;;
    esac
done

執(zhí)行命令

./test19.sh -ab test1 -c
./test19.sh -b "test1 test2" -a
./test19.sh -abtest1
./test19.sh -acde

使用shift命令和OPTIND值來(lái)移動(dòng)參數(shù)

編寫(xiě)test20.sh腳本

#!/bin/bash
echo
while getopts :ab:cd opt
do
    case "$opt" in
    a) echo "Found the -a option" ;;
    b) echo "Found the -b option, with value $OPTARG" ;;
    c) echo "Found the -c option" ;;
    d) echo "Found the -d option" ;;
    *) echo "Unknown option: $opt" ;;
    esac
done
#
shift $[ $OPTIND - 1 ]
#
echo
count=1
for param in "$@"
do
    echo "Parameter $count: $param"
    count=$[ $count+1 ]
done

執(zhí)行命令

./test20.sh -a -b test1 -d test2 test3 test4

14.5 將選項(xiàng)標(biāo)準(zhǔn)化

在創(chuàng)建shell腳本時(shí),可以決定使用哪些字母以及它們的用法

但有些字母選項(xiàng)在linux世界里已經(jīng)擁有了某種程度的標(biāo)準(zhǔn)含義

常用的Linux命令選項(xiàng)

選項(xiàng):描述
-a:顯示所有對(duì)象
-c:生成一個(gè)計(jì)數(shù)
-d:指定一個(gè)目錄
-e:擴(kuò)展一個(gè)對(duì)象
-f:指定讀入數(shù)據(jù)的文件
-h:顯示命令的幫助信息
-i:忽略文本大小寫(xiě)
-l:產(chǎn)生輸出的長(zhǎng)格式版本
-n:使用非交互模式(批處理)
-o:將所有輸出重定向到指定的輸出文件
-q:以安靜模式運(yùn)行
-r:遞歸地處理目錄和文件
-s:以安靜模式運(yùn)行
-v:生成詳細(xì)輸出
-x:排除某個(gè)對(duì)象
-y:對(duì)所有問(wèn)題回答yes

14.6 獲得用戶(hù)輸入

14.6.1 基本的讀取

read命令從標(biāo)準(zhǔn)輸入(鍵盤(pán))或另一個(gè)文件描述符中接受輸入。

編寫(xiě)test21.sh腳本

#!/bin/bash
echo -n "Enter your name:"
read name
echo "Hello $name,welcome to my program."

編寫(xiě)test22.sh腳本

#!/bin/bash
read -p "Please enter your age:" age
days=$[ $age * 365]
echo "That makes you over $days days old!"

編寫(xiě)test23.sh腳本

#!/bin/bash
read -p "Enter your name:" first last
echo "Checking data for $last, $first..."

read命令會(huì)將它收到的任何數(shù)據(jù)都放進(jìn)特殊環(huán)境變量REPLY中

編寫(xiě)test24.sh腳本

#!/bin/bash
read -p "Enter your name:"
echo
echo Hello $REPLY, welcome to my program.

14.6.2 超時(shí)

使用read命令時(shí),可以使用-t選項(xiàng)指定read命令等待輸入的秒數(shù)。當(dāng)計(jì)數(shù)器過(guò)期后,read命令返回一個(gè)非零退出狀態(tài)碼

編寫(xiě)test25.sh

#!/bin/bash
if read -t 5 -p "Please enter your name:" name
then
    echo "Hello $name,welcome to my script"
else
    echo
    echo "Sorry,too slow!"
fi

使用read命令-n選項(xiàng)統(tǒng)計(jì)輸入的字符數(shù)。當(dāng)輸入的字符達(dá)到預(yù)設(shè)的字符數(shù)時(shí),就自動(dòng)退出,將輸入的數(shù)據(jù)賦給變量

編寫(xiě)test26.sh腳本

#!/bin/bash
read -n1 -p "Do you want to continue [Y/N]?" answer
case $answer in

Y | y)  echo
        echo "fine,continue on..." ;;
N | n)  echo
        echo "OK,goodbay"
        exit;;
esac
echo "The is the end of the script"

14.6.3 隱藏方式讀取

使用-s選項(xiàng),隱藏read命令中輸出的數(shù)據(jù),避免直接出現(xiàn)在顯示器上

編寫(xiě)test27.sh命令

#!/bin/bash
read -s -p "Enter your password:" pass
echo
echo "Is your password really $pass?"

14.6.4 從文件中讀取

使用read讀取Linux系統(tǒng)上文件里保存的數(shù)據(jù)。每次調(diào)用read命令時(shí),它都會(huì)從文件中讀取一行數(shù)據(jù)。當(dāng)文件中沒(méi)有內(nèi)容時(shí),read命令退出并返回非零退出狀態(tài)碼

編寫(xiě)test文本

One
Two
Three

編寫(xiě)test28.sh腳本

#!/bin/bash
count=1
cat test | while read line
do
    echo "line $count: $line"
    count=$[ $count+1 ]
done
echo "Finished processing the file"

14.7 小結(jié)

本章講述了3種不同的方法來(lái)從腳本用戶(hù)處理獲得數(shù)據(jù)。命令行參數(shù)允許用戶(hù)運(yùn)行腳本時(shí)直接從命令行輸入數(shù)據(jù)。腳本通過(guò)位置參數(shù)來(lái)取回命令行參數(shù)并將它們賦給變量

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第十四章:處理用戶(hù)輸入 本章內(nèi)容 14.1 命令行參數(shù) 14.1.1 讀取參數(shù) bash shell會(huì)將一些稱(chēng)為位...
    數(shù)據(jù)萌新閱讀 291評(píng)論 0 0
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,695評(píng)論 0 5
  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 6,311評(píng)論 0 10
  • 月亮_6ddc閱讀 344評(píng)論 0 0
  • 這世道,無(wú)論是達(dá)官貴人,還是無(wú)名小卒,均爾虞我詐,令人可怕。好在這大千世界很公正,人人都是匆匆過(guò)客,無(wú)一幸免。 翻...
    DrJoseph閱讀 361評(píng)論 0 0

友情鏈接更多精彩內(nèi)容