SHELL腳本read命令的具體用法
1.1 shell read簡介
要與Linux交互,腳本獲取鍵盤輸入的結果是必不可少的,read可以讀取鍵盤輸入的字符。
shell作為一門語言,自然也具有讀數據的功能,read就是按行從文件(或標準輸入或給定文件描述符)中讀取數據的最佳選擇。當使用管道、重定向方式組合命令時感覺達不到自己的需求時,不妨考慮下while read line。
read [-rs] [-a ARRAY] [-d delim] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [var_name1 var_name2 ...]
read命令用于從標準輸入中讀取輸入單行,并將讀取的單行根據IFS變量分裂成多個字段,并將分割后的字段分別賦值給指定的變量列表var_name。第一個字段分配給第一個變量var_name1,第二個字段分配給第二個變量var_name2,依次到結束。如果指定的變量名少于字段數量,則多出的字段數量也同樣分配給最后一個var_name,如果指定的變量命令多于字段數量,則多出的變量賦值為空。
如果沒有指定任何var_name,則分割后的所有字段都存儲在特定變量REPLY中。
選項說明:
-a:將分裂后的字段依次存儲到指定的數組中,存儲的起始位置從數組的index=0開始。
-d:指定讀取行的結束符號。默認結束符號為換行符。
-n:限制讀取N個字符就自動結束讀取,如果沒有讀滿N個字符就按下回車或遇到換行符,則也會結束讀取。
-N:嚴格要求讀滿N個字符才自動結束讀取,即使中途按下了回車或遇到了換行符也不結束。其中換行符或回車算一個字符。
-p:給出提示符。默認不支持"\n"換行,要換行需要特殊處理,見下文示例。例如,"-p 請輸入密碼:"
-r:禁止反斜線的轉義功能。這意味著"\"會變成文本的一部分。
-s:靜默模式。輸入的內容不會回顯在屏幕上。
-t:給出超時時間,在達到超時時間時,read退出并返回錯誤。也就是說不會讀取任何內容,即使已經輸入了一部分。
-u:從給定文件描述符(fd=N)中讀取數據。
1.2 基本用法示例
(1).將讀取的內容分配給數組變量,從索引號0開始分配。
[root@xuexi ~]# read -a array_test what is you name? [root@xuexi ~]# echo ${array_test[@]} what is you name? [root@xuexi ~]# echo ${array_test[0]} what
(2).指定讀取行的結束符號,而不再使用換行符。
[root@xuexi ~]# read -d '/' what is you name \// # 輸入完尾部的"/",自動結束read
由于沒有指定var_name,所以通過$REPLY變量查看read讀取的行。
[root@xuexi ~]# echo $REPLY what is you name /
(3).限制輸入字符。
例如,輸入了5個字符后就結束。
[root@xuexi tmp]# read -n 5 12345 [root@xuexi tmp]# echo $REPLY # 輸入12345共5個字符 12345
如果輸入的字符數小于5,按下回車會立即結束讀取。
[root@xuexi ~]# read -n 5 123 [root@xuexi ~]# echo $REPLY 123
但如果使用的是"-N 5"而不是"-n 5",則嚴格限制讀滿5個字符才結束讀取。
[root@xuexi ~]# read -N 5 123\n4 [root@xuexi ~]# read -N 5 123 # 3后的回車(換行)算是一個字符 4
(4).使用-p選項給出輸入提示。
[root@xuexi ~]# read -p "pls enter you name: " pls enter you name: Junmajinlong [root@xuexi ~]# echo $REPLY Junmajinlong
"-p"選項默認不帶換行功能,且也不支持"\n"換行。但通過$'string'的方式特殊處理,就可以實現換行的功能。例如:
[root@node2 ~]# read -p $'Enter your name: \n' Enter your name: JunMaJinLong
關于$'String'和$"String"的作用
有些時候在某些服務管理腳本中看到$"$string"或$"string",經過一些測試,又發(fā)現引號外面的$有和沒有是一樣的。一直也沒去找究竟,剛才有人問了我,于是就去翻了下man bash,找到了解釋。
(1).如果沒有特殊定制bash環(huán)境或有特殊需求,$"string"和"string"是完全等價的,使用$""只是為了保證本地化。
以下是man bash關于$""的解釋:
A double-quoted string preceded by a dollar sign ($"string") will cause the string to be translated according to the current locale. If
the current locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted.
(2).還有$后接單引號的$'string',這在bash中被特殊對待:會將某些反斜線序列(如\n,\t,\",\'等)繼續(xù)轉義,而不認為它是字面符號(如果沒有$符號,單引號會強制將string翻譯為字面符號,包括反斜線)。簡單的例子:
[root@xuexi ~]# echo 'a\nb' a\nb [root@xuexi ~]# echo $'a\nb' a b
以下是man bash里關于$'的說明:
Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows:
\a alert (bell)
\b backspace
\e
\E an escape character
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote
\" double quote
\nnn the eight-bit character whose value is the octal value nnn (one to three digits)
\xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
\uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
\UHHHHHHHH
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)
\cx a control-x character
(5).禁止反斜線轉義功能。
[root@xuexi ~]# read -r what is you name \? [root@xuexi ~]# echo $REPLY what is you name \?
(6).不回顯輸入的字符。比如輸入密碼的時候,不回顯輸入密碼。
[root@xuexi ~]# read -s -p "please enter your password: " please enter your password: [root@xuexi ~]# echo $REPLY 123456
(7).將讀取的行分割后賦值給變量。
[root@xuexi ~]# read var1 var2 var3 abc def galsl djks [root@xuexi ~]# echo $var1:::$var2:::$var3 abc:::def:::galsl djks
(8).給出輸入時間限制。沒完成的輸入將被丟棄,所以變量將賦值為空(如果在執(zhí)行read前,變量已被賦值,則此變量在read超時后將被覆蓋為空)。
[root@xuexi ~]# var=5 [root@xuexi ~]# read -t 3 var 1 [root@xuexi ~]# echo $var
1.3 while read line
如果read不明確指定按字符數讀取文件(或標準輸入),那么默認是按行讀取的,而且每讀一行都會在那一行處打上標記(即文件指針。當然,按字符數讀取也一樣會打上標記),表示這一次已經讀取到了這個地方,使得下次仍然能夠從這里開始繼續(xù)向下讀取。這使得read結合while使用的時候,是按行讀數據非常好的方式。
例如:
[root@xuexi ~]# cat test1 a b c d # 用法示例1 [root@xuexi ~]# cat test1 | while read line;do echo $line;done a b c d # 用法示例2 [root@xuexi ~]# while read line;do echo $line;done <test1 a b c d # 用法示例3:請對比下面這條命令和上面的 [root@xuexi ~]# while read line <test1;do echo $line;done
關于while read line,需要注意幾個事項:
1.強烈建議,不要在管道后面使用while read line。正如上面第1個示例中 cat test1|while read line。因為管道會開啟子shell,使得while中的命令都在子shell中執(zhí)行,而且,cat test1會一次性將test1文件所有數據裝入內存,如果test1文件足夠大,會直接占用巨量內存。而第二個示例使用輸入重定向的方式則每次只占用一行數據的內存,而且是在當前shell環(huán)境下執(zhí)行的,while內的變量賦值、數組賦值在退出while后仍然有效。
2.不要使用示例3,因為測試了就知道為什么不用,它會在每次循環(huán)的時候都重新打開test1文件,使得每次都從頭開始讀數據,而不是每次從上一次標記的地方繼續(xù)讀數據。
所以,在使用while read line的時候,能用示例2的方式就用示例2,如果你還不理解或者找不到其它方式,那么直接記住這個結論。
到此這篇關于SHELL腳本read命令的具體用法的文章就介紹到這了,更多相關SHELL read命令內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Linux shell腳本編程if語句的使用方法(條件判斷)
這篇文章主要介紹了Linux shell腳本編程if語句的使用方法,大家參考使用吧2013-12-12Linux C中sockaddr和sockaddr_in的區(qū)別
這篇文章主要介紹了Linux C中sockaddr和sockaddr_in的區(qū)別的相關資料,需要的朋友可以參考下2017-07-07