1.1 shell read簡介
要與Linux交互,腳本獲取鍵盤輸入的結(jié)果是必不可少的,read可以讀取鍵盤輸入的字符。
shell作為一門語言,自然也具有讀數(shù)據(jù)的功能,read就是按行從文件(或標(biāo)準(zhǔn)輸入或給定文件描述符)中讀取數(shù)據(jù)的最佳選擇。當(dāng)使用管道、重定向方式組合命令時感覺達(dá)不到自己的需求時,不妨考慮下while read line。
read [-rs] [-a ARRAY] [-d delim] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [var_name1 var_name2 ...]
read命令用于從標(biāo)準(zhǔn)輸入中讀取輸入單行,并將讀取的單行根據(jù)IFS變量分裂成多個字段,并將分割后的字段分別賦值給指定的變量列表var_name。第一個字段分配給第一個變量var_name1,第二個字段分配給第二個變量var_name2,依次到結(jié)束。如果指定的變量名少于字段數(shù)量,則多出的字段數(shù)量也同樣分配給最后一個var_name,如果指定的變量命令多于字段數(shù)量,則多出的變量賦值為空。
如果沒有指定任何var_name,則分割后的所有字段都存儲在特定變量REPLY中。
選項(xiàng)說明:
-a:將分裂后的字段依次存儲到指定的數(shù)組中,存儲的起始位置從數(shù)組的index=0開始。
-d:指定讀取行的結(jié)束符號。默認(rèn)結(jié)束符號為換行符。
-n:限制讀取N個字符就自動結(jié)束讀取,如果沒有讀滿N個字符就按下回車或遇到換行符,則也會結(jié)束讀取。
-N:嚴(yán)格要求讀滿N個字符才自動結(jié)束讀取,即使中途按下了回車或遇到了換行符也不結(jié)束。其中換行符或回車算一個字符。
-p:給出提示符。默認(rèn)不支持"\n"換行,要換行需要特殊處理,見下文示例。例如,"-p 請輸入密碼:"
-r:禁止反斜線的轉(zhuǎn)義功能。這意味著"\"會變成文本的一部分。
-s:靜默模式。輸入的內(nèi)容不會回顯在屏幕上。
-t:給出超時時間,在達(dá)到超時時間時,read退出并返回錯誤。也就是說不會讀取任何內(nèi)容,即使已經(jīng)輸入了一部分。
-u:從給定文件描述符(fd=N)中讀取數(shù)據(jù)。
1.2 基本用法示例
(1).將讀取的內(nèi)容分配給數(shù)組變量,從索引號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).指定讀取行的結(jié)束符號,而不再使用換行符。
[root@xuexi ~]# read -d '/'
what is you name \// # 輸入完尾部的"/",自動結(jié)束read
由于沒有指定var_name,所以通過$REPLY變量查看read讀取的行。
[root@xuexi ~]# echo $REPLY
what is you name /
(3).限制輸入字符。
例如,輸入了5個字符后就結(jié)束。
[root@xuexi tmp]# read -n 5
12345
[root@xuexi tmp]# echo $REPLY # 輸入12345共5個字符
12345
如果輸入的字符數(shù)小于5,按下回車會立即結(jié)束讀取。
[root@xuexi ~]# read -n 5
123
[root@xuexi ~]# echo $REPLY
123
但如果使用的是"-N 5"而不是"-n 5",則嚴(yán)格限制讀滿5個字符才結(jié)束讀取。
[root@xuexi ~]# read -N 5
123\n4
[root@xuexi ~]# read -N 5
123 # 3后的回車(換行)算是一個字符
4
(4).使用-p選項(xiàng)給出輸入提示。
[root@xuexi ~]# read -p "pls enter you name: "
pls enter you name: Junmajinlong
[root@xuexi ~]# echo $REPLY
Junmajinlong
"-p"選項(xiàng)默認(rèn)不帶換行功能,且也不支持"\n"換行。但通過$'string'的方式特殊處理,就可以實(shí)現(xiàn)換行的功能。例如:
[root@node2 ~]# read -p $'Enter your name: \n'
Enter your name:
JunMaJinLong
關(guān)于$'String'和$"String"的作用
有些時候在某些服務(wù)管理腳本中看到$"$string"或$"string",經(jīng)過一些測試,又發(fā)現(xiàn)引號外面的$有和沒有是一樣的。一直也沒去找究竟,剛才有人問了我,于是就去翻了下man bash,找到了解釋。
(1).如果沒有特殊定制bash環(huán)境或有特殊需求,$"string"和"string"是完全等價的,使用$""只是為了保證本地化。
以下是man bash關(guān)于$""的解釋:
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ù)轉(zhuǎn)義,而不認(rèn)為它是字面符號(如果沒有$符號,單引號會強(qiáng)制將string翻譯為字面符號,包括反斜線)。簡單的例子:
[root@xuexi ~]# echo 'anb'
anb
[root@xuexi ~]# echo $'anb'
a
b
以下是man bash里關(guān)于$'的說明:
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).禁止反斜線轉(zhuǎn)義功能。
[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不明確指定按字符數(shù)讀取文件(或標(biāo)準(zhǔn)輸入),那么默認(rèn)是按行讀取的,而且每讀一行都會在那一行處打上標(biāo)記(即文件指針。當(dāng)然,按字符數(shù)讀取也一樣會打上標(biāo)記),表示這一次已經(jīng)讀取到了這個地方,使得下次仍然能夠從這里開始繼續(xù)向下讀取。這使得read結(jié)合while使用的時候,是按行讀數(shù)據(jù)非常好的方式。
例如:
[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
關(guān)于while read line,需要注意幾個事項(xiàng):
1.強(qiáng)烈建議,不要在管道后面使用while read line。正如上面第1個示例中 cat test1|while read line。因?yàn)楣艿罆_啟子shell,使得while中的命令都在子shell中執(zhí)行,而且,cat test1會一次性將test1文件所有數(shù)據(jù)裝入內(nèi)存,如果test1文件足夠大,會直接占用巨量內(nèi)存。而第二個示例使用輸入重定向的方式則每次只占用一行數(shù)據(jù)的內(nèi)存,而且是在當(dāng)前shell環(huán)境下執(zhí)行的,while內(nèi)的變量賦值、數(shù)組賦值在退出while后仍然有效。
2.不要使用示例3,因?yàn)闇y試了就知道為什么不用,它會在每次循環(huán)的時候都重新打開test1文件,使得每次都從頭開始讀數(shù)據(jù),而不是每次從上一次標(biāo)記的地方繼續(xù)讀數(shù)據(jù)。
所以,在使用while read line的時候,能用示例2的方式就用示例2,如果你還不理解或者找不到其它方式,那么直接記住這個結(jié)論。
到此這篇關(guān)于SHELL腳本read命令的具體用法的文章就介紹到這了,更多相關(guān)SHELL read命令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- 一條命令讓你明白shell中read命令的常用參數(shù)