Shell腳本read用法實現(xiàn)
1.概述
到目前為止,編寫的腳本都缺少一個常用于大多數(shù)計算機程序的特性–交互性,或者說與用戶互動的能力。盡管很多程序并不需要是交互式的,但能夠直接接受用戶輸入,確實有利于某些程序。
2. read從標準輸入讀取值
內建命令read可用于從標準輸入中讀取一行。該命令可以讀取鍵盤輸入,如果使用了重定向,也可以讀取文件的數(shù)據(jù)行。該命令用法如下:
read [-options] [variable...]
其中,option是一個或多個選項,variable是一個或多個變量,用于保存輸入值。如果未指定變量,則輸入值保存在Shell變量REPLAY中。使用read命令改寫之前的整數(shù)驗證腳本:
#!/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也可以將輸入賦給多個變量
[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ù)量少于預期,則多出的變量為空值,如果數(shù)量多于預期,則額外的輸入全部保存在最后一個變量中。
[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選項
選項 | 描述 |
---|---|
-a array | 將輸入分配給數(shù)組(從索引0開始)。 |
-d delimiter | 將字符串delimter中的第一個字符(而非換行符)作為輸入的結束 |
-e | 使用readline處理輸入,允許使用和命令行相同的方式編輯輸入 |
-i string | 如果用戶直接按Enter鍵,使用string作為默認值,需要配合-e選項使用 |
-n num | 從輸入中讀取num個字符,而非讀取一整行 |
-p prompt | 將字符prompt作為輸入提示來顯示 |
-r | 原始模式,不將反斜線符解釋為轉義 |
-s | 靜默模式,在用戶輸入字符時不回顯,該模式適用于輸入密碼或其他機密信息 |
-t seconds | 超時,seconds秒之后終止輸入,如果輸入超時,read返回非0退出狀態(tài)值 |
-u fd | 從文件描述符fd中讀取輸入 |
選項-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]$
選項-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]$
選項-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通常會提供給read的輸入進行單詞分割,這意味著輸入行中被一個或多個空白字符分割的多個單詞會變成若干獨立項,再由read分配給各個變量。Shell變量內部字段分割符(Internal Filed Separator,IFS)控制著此行為。IFS的默認值包含了空格符,制表符,換行符,它們都可用于分割單詞。
我們可以調整IFS的值,控制read的輸入字段。例如:/etc/passwd文件中的數(shù)據(jù)行采用冒號作為字段分隔符。將IFS的值改成冒號,就可以使用read讀入/etc/passwd的內容并順利將字段分割存入各個變量。來看下面的實現(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允許一個或多個變量賦值直接出現(xiàn)在命令之前。這些賦值會修改緊隨其后的命令的環(huán)境。這種賦值效果是臨時的。對環(huán)境所作的改動僅限于命令執(zhí)行期間有效。<<< 標識here string。here string類似于here document,但是更簡短,僅由單個字符串組成。
2.3 驗證輸入
好程序和差程序之間的區(qū)別往往在于處理意外情況的能力,而意外情況多以錯誤輸入的形式出現(xiàn)。重要的是,每次程序接收到輸入的時候,都要執(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 菜單
菜單驅動是一中常見的交互方式,菜單驅動的程序會為用戶呈現(xiàn)一系列的選項,要求用戶從中選擇。
[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í)行相應的菜單項功能。注意腳本中exit命令的用法,在完成用戶選定的功能后,exit可以防止繼續(xù)執(zhí)行不必要的代碼。
到此這篇關于Shell腳本read用法實現(xiàn)的文章就介紹到這了,更多相關Shell read內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
在Linux?中使用?pidstat?命令監(jiān)控進程性能?的操作方法
pidstat是Linux系統(tǒng)中一個用于監(jiān)控各種統(tǒng)計信息的命令行工具,它能夠幫助用戶了解系統(tǒng)中各個進程的資源使用情況,如CPU、內存、I/O等,本文介紹了如何安裝pidstat,以及如何使用其不同的選項來監(jiān)控進程的各種性能指標,感興趣的朋友一起看看吧2024-09-09Shell腳本實現(xiàn)的基于SVN的代碼提交量統(tǒng)計工具
這篇文章主要介紹了Shell腳本實現(xiàn)的基于SVN的代碼提交量統(tǒng)計工具,本文直接給出實現(xiàn)腳本代碼,需要的朋友可以參考下2015-06-06shell腳本學習指南[三](Arnold?Robbins?&?Nelson?H.F.?Beebe著)
這篇文章主要介紹了shell腳本學習指南[三](Arnold?Robbins?&?Nelson?H.F.?Beebe著),需要的朋友可以參考下2014-02-02Shell腳本實現(xiàn)監(jiān)控swap空間使用情況和查看占用swap的進程
這篇文章主要介紹了Shell腳本實現(xiàn)監(jiān)控swap空間使用情況和查看占用swap的進程,曾經有一段時間機器的swap不停上漲,監(jiān)控后發(fā)現(xiàn)是一些java進程占用swap空間后,完全不釋放,殺死這些java進程后,釋放swap,需要的朋友可以參考下2014-12-12