SHELL脚本read命令的具体用法
1.1shellread简介
要与Linux交互,脚本获取键盘输入的结果是必不可少的,read可以读取键盘输入的字符。
shell作为一门语言,自然也具有读数据的功能,read就是按行从文件(或标准输入或给定文件描述符)中读取数据的最佳选择。当使用管道、重定向方式组合命令时感觉达不到自己的需求时,不妨考虑下whilereadline。
read[-rs][-aARRAY][-ddelim][-nnchars][-Nnchars][-pprompt][-ttimeout][-ufd][var_name1var_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-aarray_test whatisyouname? [root@xuexi~]#echo${array_test[@]} whatisyouname? [root@xuexi~]#echo${array_test[0]} what
(2).指定读取行的结束符号,而不再使用换行符。
[root@xuexi~]#read-d'/' whatisyouname\//#输入完尾部的"/",自动结束read
由于没有指定var_name,所以通过$REPLY变量查看read读取的行。
[root@xuexi~]#echo$REPLY whatisyouname/
(3).限制输入字符。
例如,输入了5个字符后就结束。
[root@xuexitmp]#read-n5 12345 [root@xuexitmp]#echo$REPLY#输入12345共5个字符 12345
如果输入的字符数小于5,按下回车会立即结束读取。
[root@xuexi~]#read-n5 123 [root@xuexi~]#echo$REPLY 123
但如果使用的是"-N5"而不是"-n5",则严格限制读满5个字符才结束读取。
[root@xuexi~]#read-N5 123\n4 [root@xuexi~]#read-N5 123#3后的回车(换行)算是一个字符 4
(4).使用-p选项给出输入提示。
[root@xuexi~]#read-p"plsenteryouname:" plsenteryouname:Junmajinlong [root@xuexi~]#echo$REPLY Junmajinlong
"-p"选项默认不带换行功能,且也不支持"\n"换行。但通过$'string'的方式特殊处理,就可以实现换行的功能。例如:
[root@node2~]#read-p$'Enteryourname:\n' Enteryourname: JunMaJinLong
关于$'String'和$"String"的作用
有些时候在某些服务管理脚本中看到$"$string"或$"string",经过一些测试,又发现引号外面的$有和没有是一样的。一直也没去找究竟,刚才有人问了我,于是就去翻了下manbash,找到了解释。
(1).如果没有特殊定制bash环境或有特殊需求,$"string"和"string"是完全等价的,使用$""只是为了保证本地化。
以下是manbash关于$""的解释:
A double-quoted string precededbyadollarsign($"string")willcausethestringtobetranslatedaccordingtothecurrentlocale. If
thecurrentlocaleisCorPOSIX,thedollarsignisignored. Ifthestringistranslatedandreplaced,thereplacementisdouble-quoted.
(2).还有$后接单引号的$'string',这在bash中被特殊对待:会将某些反斜线序列(如\n,\t,\",\'等)继续转义,而不认为它是字面符号(如果没有$符号,单引号会强制将string翻译为字面符号,包括反斜线)。简单的例子:
[root@xuexi~]#echo'a\nb' a\nb [root@xuexi~]#echo$'a\nb' a b
以下是manbash里关于$'的说明:
Wordsoftheform$'string'aretreatedspecially. Thewordexpandstostring,withbackslash-escapedcharactersreplacedasspecified by theANSICstandard. Backslashescapesequences,ifpresent,aredecodedasfollows:
\a alert(bell)
\b backspace
\e
\E anescapecharacter
\f formfeed
\n newline
\r carriagereturn
\t horizontaltab
\v verticaltab
\\ backslash
\' singlequote
\" doublequote
\nnn theeight-bitcharacterwhosevalueistheoctalvaluennn(onetothreedigits)
\xHH theeight-bitcharacterwhosevalueisthehexadecimalvalueHH(oneortwohexdigits)
\uHHHHtheUnicode(ISO/IEC10646)characterwhosevalueisthehexadecimalvalueHHHH(onetofourhexdigits)
\UHHHHHHHH
theUnicode(ISO/IEC10646)characterwhosevalueisthehexadecimalvalueHHHHHHHH(onetoeighthexdigits)
\cx acontrol-xcharacter
(5).禁止反斜线转义功能。
[root@xuexi~]#read-r whatisyouname\? [root@xuexi~]#echo$REPLY whatisyouname\?
(6).不回显输入的字符。比如输入密码的时候,不回显输入密码。
[root@xuexi~]#read-s-p"pleaseenteryourpassword:" pleaseenteryourpassword: [root@xuexi~]#echo$REPLY 123456
(7).将读取的行分割后赋值给变量。
[root@xuexi~]#readvar1var2var3 abcdefgalsldjks [root@xuexi~]#echo$var1:::$var2:::$var3 abc:::def:::galsldjks
(8).给出输入时间限制。没完成的输入将被丢弃,所以变量将赋值为空(如果在执行read前,变量已被赋值,则此变量在read超时后将被覆盖为空)。
[root@xuexi~]#var=5 [root@xuexi~]#read-t3var 1 [root@xuexi~]#echo$var
1.3whilereadline
如果read不明确指定按字符数读取文件(或标准输入),那么默认是按行读取的,而且每读一行都会在那一行处打上标记(即文件指针。当然,按字符数读取也一样会打上标记),表示这一次已经读取到了这个地方,使得下次仍然能够从这里开始继续向下读取。这使得read结合while使用的时候,是按行读数据非常好的方式。
例如:
[root@xuexi~]#cattest1 a b c d #用法示例1 [root@xuexi~]#cattest1|whilereadline;doecho$line;done a b c d #用法示例2 [root@xuexi~]#whilereadline;doecho$line;done关于whilereadline,需要注意几个事项:
1.强烈建议,不要在管道后面使用whilereadline。正如上面第1个示例中cattest1|whilereadline。因为管道会开启子shell,使得while中的命令都在子shell中执行,而且,cattest1会一次性将test1文件所有数据装入内存,如果test1文件足够大,会直接占用巨量内存。而第二个示例使用输入重定向的方式则每次只占用一行数据的内存,而且是在当前shell环境下执行的,while内的变量赋值、数组赋值在退出while后仍然有效。
2.不要使用示例3,因为测试了就知道为什么不用,它会在每次循环的时候都重新打开test1文件,使得每次都从头开始读数据,而不是每次从上一次标记的地方继续读数据。
所以,在使用whilereadline的时候,能用示例2的方式就用示例2,如果你还不理解或者找不到其它方式,那么直接记住这个结论。
到此这篇关于SHELL脚本read命令的具体用法的文章就介绍到这了,更多相关SHELLread命令内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!