Shell腳本read用法實(shí)現(xiàn)
1.概述
到目前為止,編寫的腳本都缺少一個(gè)常用于大多數(shù)計(jì)算機(jī)程序的特性–交互性,或者說與用戶互動(dòng)的能力。盡管很多程序并不需要是交互式的,但能夠直接接受用戶輸入,確實(shí)有利于某些程序。
2. read從標(biāo)準(zhǔn)輸入讀取值
內(nèi)建命令read可用于從標(biāo)準(zhǔn)輸入中讀取一行。該命令可以讀取鍵盤輸入,如果使用了重定向,也可以讀取文件的數(shù)據(jù)行。該命令用法如下:
read [-options] [variable...]
其中,option是一個(gè)或多個(gè)選項(xiàng),variable是一個(gè)或多個(gè)變量,用于保存輸入值。如果未指定變量,則輸入值保存在Shell變量REPLAY中。使用read命令改寫之前的整數(shù)驗(yàn)證腳本:
#!/bin/bash # read-integer echo -n "Please enter an integer -> " read int if [[ "$int" =~ ^-?[0-9]+$ ]]; then if [ "$int" -eq 0 ]; then echo "$int is zero." else if [ "$int" -lt 0 ]; then echo "$int is negative." else echo "$int is positive" fi fi if [ $((int % 2)) -eq 0 ]; then echo "$int is even." else echo "$int is odd." fi else echo "Input value is not an integer." >&2 exit 1 fi
read也可以將輸入賦給多個(gè)變量
[sysadmin@ansible bin]$ cat read1 #!/bin/bash #read-multiple echo -n "Enter one or more values > " read var1 var2 var3 var4 var5 echo "var1 = '$var1'" echo "var2 = '$var2'" echo "var3 = '$var3'" echo "var4 = '$var4'" echo "var5 = '$var5'" [sysadmin@ansible bin]$ read1 Enter one or more values > 1 2 3 4 5 var1 = '1' var2 = '2' var3 = '3' var4 = '4' var5 = '5'
如果read接收到的值數(shù)量少于預(yù)期,則多出的變量為空值,如果數(shù)量多于預(yù)期,則額外的輸入全部保存在最后一個(gè)變量中。
[sysadmin@ansible bin]$ cat read1 #!/bin/bash #read-multiple echo -n "Enter one or more values > " read var1 var2 var3 var4 var5 echo "var1 = '$var1'" echo "var2 = '$var2'" echo "var3 = '$var3'" echo "var4 = '$var4'" echo "var5 = '$var5'" [sysadmin@ansible bin]$ read1 Enter one or more values > a var1 = 'a' var2 = '' var3 = '' var4 = '' var5 = '' [sysadmin@ansible bin]$ read1 Enter one or more values > a b c d e f g var1 = 'a' var2 = 'b' var3 = 'c' var4 = 'd' var5 = 'e f g' [sysadmin@ansible bin]$
如果沒有為read命令指定變量,則所有的輸入全部保存在Shell變量REPLY中
[sysadmin@ansible bin]$ cat read2 #!/bin/bash #read-multiple echo -n "Enter one or more values > " read echo "REPLY = '$REPLY'" [sysadmin@ansible bin]$ read2 Enter one or more values > a b c d REPLY = 'a b c d' [sysadmin@ansible bin]$
2.1 read選項(xiàng)
選項(xiàng) | 描述 |
---|---|
-a array | 將輸入分配給數(shù)組(從索引0開始)。 |
-d delimiter | 將字符串delimter中的第一個(gè)字符(而非換行符)作為輸入的結(jié)束 |
-e | 使用readline處理輸入,允許使用和命令行相同的方式編輯輸入 |
-i string | 如果用戶直接按Enter鍵,使用string作為默認(rèn)值,需要配合-e選項(xiàng)使用 |
-n num | 從輸入中讀取num個(gè)字符,而非讀取一整行 |
-p prompt | 將字符prompt作為輸入提示來顯示 |
-r | 原始模式,不將反斜線符解釋為轉(zhuǎn)義 |
-s | 靜默模式,在用戶輸入字符時(shí)不回顯,該模式適用于輸入密碼或其他機(jī)密信息 |
-t seconds | 超時(shí),seconds秒之后終止輸入,如果輸入超時(shí),read返回非0退出狀態(tài)值 |
-u fd | 從文件描述符fd中讀取輸入 |
選項(xiàng)-p
[sysadmin@ansible bin]$ cat read2 #!/bin/bash #read-single read -p "Enter one or more values > " echo "REPLY = '$REPLY'" [sysadmin@ansible bin]$ read2 Enter one or more values > a REPLY = 'a' [sysadmin@ansible bin]$
選項(xiàng)-t和-s
[sysadmin@ansible bin]$ cat readpass #!/bin/bash #read-pass if read -t 10 -sp "Enter password > " passwd; then ? ? ? ? echo -e "\nSecret passphrase = '$passwd'" else ? ? ? ? echo -e "\nInput timed out" >&2 ? ? ? ? exit 1 fi [sysadmin@ansible bin]$ readpass Enter password > Secret passphrase = 'abcdef' [sysadmin@ansible bin]$
選項(xiàng)-e和-i
[sysadmin@ansible bin]$ cat readdefault #!/bin/bash #read-default read -e -p "What is your user name? " -i $USER echo "You answered: '$REPLY'" [sysadmin@ansible bin]$ readdefault What is your user name? sysadmin You answered: 'sysadmin' [sysadmin@ansible bin]$
2.2 IFS
Shell通常會(huì)提供給read的輸入進(jìn)行單詞分割,這意味著輸入行中被一個(gè)或多個(gè)空白字符分割的多個(gè)單詞會(huì)變成若干獨(dú)立項(xiàng),再由read分配給各個(gè)變量。Shell變量內(nèi)部字段分割符(Internal Filed Separator,IFS)控制著此行為。IFS的默認(rèn)值包含了空格符,制表符,換行符,它們都可用于分割單詞。
我們可以調(diào)整IFS的值,控制read的輸入字段。例如:/etc/passwd文件中的數(shù)據(jù)行采用冒號作為字段分隔符。將IFS的值改成冒號,就可以使用read讀入/etc/passwd的內(nèi)容并順利將字段分割存入各個(gè)變量。來看下面的實(shí)現(xiàn)腳本。
[sysadmin@ansible bin]$ cat read-ifs #!/bin/bash # read-ifs FILE=/etc/passwd read -p "Enter a user > " user_name file_info="$(grep "^$user_name:" $FILE)" if [ -n "$file_info" ]; then ? ? ? ? IFS=":" read user pw uid gid name home shell <<< "$file_info" ? ? ? ? echo "User = ? ? ? ? ? ?'$user'" ? ? ? ? echo "UID = ? ? ? ? ? ? '$uid'" ? ? ? ? echo "GID = ? ? ? ? ? ? '$gid'" ? ? ? ? echo "Full Name = ? ? ? '$name'" ? ? ? ? echo "Home Dir = ? ? ? ?'$home'" ? ? ? ? echo "Shell = ? ? ? ? ? '$shell'" else ? ? ? ? echo "No such user '$user_name'" >&2 ? ? ? ? exit 1 fi [sysadmin@ansible bin]$ read-ifs Enter a user > jticnoc User = ? ? ? ? ?'jticnoc' UID = ? ? ? ? ? '2099' GID = ? ? ? ? ? '2099' Full Name = ? ? '' Home Dir = ? ? ?'/home/jticnoc' Shell = ? ? ? ? '/bin/bash' [sysadmin@ansible bin]$
Shell允許一個(gè)或多個(gè)變量賦值直接出現(xiàn)在命令之前。這些賦值會(huì)修改緊隨其后的命令的環(huán)境。這種賦值效果是臨時(shí)的。對環(huán)境所作的改動(dòng)僅限于命令執(zhí)行期間有效。<<< 標(biāo)識here string。here string類似于here document,但是更簡短,僅由單個(gè)字符串組成。
2.3 驗(yàn)證輸入
好程序和差程序之間的區(qū)別往往在于處理意外情況的能力,而意外情況多以錯(cuò)誤輸入的形式出現(xiàn)。重要的是,每次程序接收到輸入的時(shí)候,都要執(zhí)行此類檢查,以防止非法數(shù)據(jù)。
[sysadmin@ansible bin]$ cat read-validate #!/bin/bash #read-validate invalid_input () { ? ? ? ? echo "Invalid input '$REPLAY'" >&2 ? ? ? ? exit 1 } read -p "Enter a single item > " # input is null [[ -z "$REPLY" ]] && invalid_input # input is multi items (( "$(echo "$REPLY" |wc -w)" > 1 )) && invalid_input # input filename is valid if [[ "$REPLY" =~ ^[-[:alnum:]\._]+$ ]]; then ? ? ? ? echo "'$REPLY' is a valid filename." ? ? ? ? if [[ -e "$REPLY" ]]; then ? ? ? ? ? ? ? ? echo "And file '$REPLY' exists." ? ? ? ? else ? ? ? ? ? ? ? ? echo "However, file '$REPLY' does not exist." ? ? ? ? fi ? ? ? ? # input is float ? ? ? ? if [[ "$REPLY" =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then ? ? ? ? ? ? ? ? echo "'$REPLY' is a floating point number." ? ? ? ? else ? ? ? ? ? ? ? ? echo "'$REPLY' is not a floating point number." ? ? ? ? fi ? ? ? ? # input is int ? ? ? ? if [[ "$REPLY" =~ ^-?[[:digit:]]+$ ]]; then ? ? ? ? ? ? ? ? echo "'$REPLY' is an integer." ? ? ? ? else ? ? ? ? ? ? ? ? echo "'$REPLY' is not an integer." ? ? ? ? fi else ? ? ? ? echo "The string '$REPLY' is not a valid filename." fi [sysadmin@ansible bin]$
2.4 菜單
菜單驅(qū)動(dòng)是一中常見的交互方式,菜單驅(qū)動(dòng)的程序會(huì)為用戶呈現(xiàn)一系列的選項(xiàng),要求用戶從中選擇。
[sysadmin@ansible bin]$ cat read-menu #!/bin/bash #read-menu clear echo " Please Select: 1.Display System Information 2.Display Disk Space 3.Display Home Space Utilization 4.Quit " read -p "Enter selection [0-3] > " if [[ "$REPLY" =~ ^[0-3]$ ]]; then ? ? ? ? if [[ "$REPLY" == 0 ]]; then ? ? ? ? ? ? ? ? echo "Program terminated." ? ? ? ? ? ? ? ? exit ? ? ? ? fi ? ? ? ? if [[ "$REPLY" == 1 ]]; then ? ? ? ? ? ? ? ? echo "Hostname: $HOSTNAME" ? ? ? ? ? ? ? ? uptime ? ? ? ? ? ? ? ? exit ? ? ? ? fi ? ? ? ? if [[ "$REPLY" == 2 ]]; then ? ? ? ? ? ? ? ? df -h ? ? ? ? ? ? ? ? exit ? ? ? ? fi ? ? ? ? if [[ "$REPLY" == 3 ]]; then ? ? ? ? ? ? ? ? if [[ "$(id -u)" -eq 0 ]]; then ? ? ? ? ? ? ? ? ? ? ? ? echo "Home Space Utilization (ALL Users)" ? ? ? ? ? ? ? ? ? ? ? ? du -sh /home/* ? ? ? ? ? ? ? ? else ? ? ? ? ? ? ? ? ? ? ? ? echo "Home Space Utilizaion ($USER)" ? ? ? ? ? ? ? ? ? ? ? ? du -sh "$HOME" ? ? ? ? ? ? ? ? fi ? ? ? ? ? ? ? ? exit ? ? ? ? fi else ? ? ? ? echo "Invalid entry." >&2 ? ? ? ? exit 1 fi
第一部分展示了菜單并獲取用戶輸入,第二部分識別輸入并執(zhí)行相應(yīng)的菜單項(xiàng)功能。注意腳本中exit命令的用法,在完成用戶選定的功能后,exit可以防止繼續(xù)執(zhí)行不必要的代碼。
到此這篇關(guān)于Shell腳本read用法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Shell read內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Linux?中使用?pidstat?命令監(jiān)控進(jìn)程性能?的操作方法
pidstat是Linux系統(tǒng)中一個(gè)用于監(jiān)控各種統(tǒng)計(jì)信息的命令行工具,它能夠幫助用戶了解系統(tǒng)中各個(gè)進(jìn)程的資源使用情況,如CPU、內(nèi)存、I/O等,本文介紹了如何安裝pidstat,以及如何使用其不同的選項(xiàng)來監(jiān)控進(jìn)程的各種性能指標(biāo),感興趣的朋友一起看看吧2024-09-09shell 隨機(jī)從文件中抽取若干行的實(shí)現(xiàn)方法
這篇文章主要介紹了shell 隨機(jī)從文件中抽取若干行的實(shí)現(xiàn)方法,需要的朋友可以參考下2016-03-03Shell獲取當(dāng)前正在執(zhí)行腳本的絕對路徑
本文主要介紹了Shell獲取當(dāng)前正在執(zhí)行腳本的絕對路徑,主要有三種方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Shell腳本實(shí)現(xiàn)的基于SVN的代碼提交量統(tǒng)計(jì)工具
這篇文章主要介紹了Shell腳本實(shí)現(xiàn)的基于SVN的代碼提交量統(tǒng)計(jì)工具,本文直接給出實(shí)現(xiàn)腳本代碼,需要的朋友可以參考下2015-06-06shell腳本學(xué)習(xí)指南[三](Arnold?Robbins?&?Nelson?H.F.?Beebe著)
這篇文章主要介紹了shell腳本學(xué)習(xí)指南[三](Arnold?Robbins?&?Nelson?H.F.?Beebe著),需要的朋友可以參考下2014-02-02Shell腳本實(shí)現(xiàn)監(jiān)控swap空間使用情況和查看占用swap的進(jìn)程
這篇文章主要介紹了Shell腳本實(shí)現(xiàn)監(jiān)控swap空間使用情況和查看占用swap的進(jìn)程,曾經(jīng)有一段時(shí)間機(jī)器的swap不停上漲,監(jiān)控后發(fā)現(xiàn)是一些java進(jìn)程占用swap空間后,完全不釋放,殺死這些java進(jìn)程后,釋放swap,需要的朋友可以參考下2014-12-12