博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
read命令
阅读量:4646 次
发布时间:2019-06-09

本文共 3276 字,大约阅读时间需要 10 分钟。

本文原创地址:博客园骏马金龙

bash&shell系列文章:


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_testwhat 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 $REPLYwhat is you name /

(3).限制输入字符。

例如,输入了5个字符后就结束。

[root@xuexi tmp]# read -n 512345[root@xuexi tmp]# echo $REPLY   # 输入12345共5个字符12345

如果输入的字符数小于5,按下回车会立即结束读取。

[root@xuexi ~]# read -n 5123[root@xuexi ~]# echo $REPLY123

但如果使用的是"-N 5"而不是"-n 5",则严格限制读满5个字符才结束读取。

[root@xuexi ~]# read -N 5123\n4[root@xuexi ~]# read -N 5123          # 3后的回车(换行)算是一个字符4

(4).使用-p选项给出输入提示。

[root@xuexi ~]# read -p "pls enter you name: "pls enter you name: Junmajinlong[root@xuexi ~]# echo $REPLYJunmajinlong

"-p"选项默认不带换行功能,且也不支持"\n"换行。但通过$'string'的方式特殊处理,就可以实现换行的功能。例如:

[root@node2 ~]# read -p $'Enter your name: \n'Enter your name: JunMaJinLong

关于$'String'和$"String"的作用,见

(5).禁止反斜线转义功能。

[root@xuexi ~]# read -rwhat is you name \?[root@xuexi ~]# echo $REPLYwhat is you name \?

(6).不回显输入的字符。比如输入密码的时候,不回显输入密码。

[root@xuexi ~]# read -s -p "please enter your password: "please enter your password:[root@xuexi ~]# echo $REPLY123456

(7).将读取的行分割后赋值给变量。

[root@xuexi ~]# read var1 var2 var3abc def    galsl djks[root@xuexi ~]# echo $var1:::$var2:::$var3abc:::def:::galsl djks

(8).给出输入时间限制。没完成的输入将被丢弃,所以变量将赋值为空(如果在执行read前,变量已被赋值,则此变量在read超时后将被覆盖为空)。

[root@xuexi ~]# var=5[root@xuexi ~]# read -t 3 var1[root@xuexi ~]# echo $var

1.3 while read line

如果read不明确指定按字符数读取文件(或标准输入),那么默认是按行读取的,而且每读一行都会在那一行处打上标记(即文件指针。当然,按字符数读取也一样会打上标记),表示这一次已经读取到了这个地方,使得下次仍然能够从这里开始继续向下读取。这使得read结合while使用的时候,是按行读数据非常好的方式。

例如:

[root@xuexi ~]# cat test1abcd # 用法示例1[root@xuexi ~]# cat test1 | while read line;do echo $line;doneabcd # 用法示例2[root@xuexi ~]# while read line;do echo $line;done 

关于while read line,需要注意几个事项:

1.强烈建议,不要在管道后面使用while read line。正如上面第1个示例中 cat test1|while read line。因为管道会开启子shell,使得while中的命令都在子shell中执行,而且,cat test1会一次性将test1文件所有数据装入内存,如果test1文件足够大,会直接占用巨量内存。而第二个示例使用输入重定向的方式则每次只占用一行数据的内存,而且是在当前shell环境下执行的,while内的变量赋值、数组赋值在退出while后仍然有效。

2.不要使用示例3,因为测试了就知道为什么不用,它会在每次循环的时候都重新打开test1文件,使得每次都从头开始读数据,而不是每次从上一次标记的地方继续读数据。

所以,在使用while read line的时候,能用示例2的方式就用示例2,如果你还不理解或者找不到其它方式,那么直接记住这个结论

 

转载于:https://www.cnblogs.com/xiangtingshen/p/11491065.html

你可能感兴趣的文章
XSS跨站脚本与CSRF跨站请求伪造
查看>>
分享20个最新的免费 UI 设计素材给设计师
查看>>
[Dynamics CRM 2016]如何配置多语言显示
查看>>
【面试】http协议知识
查看>>
mysql 运维常见操作
查看>>
python学习笔记11 ----线程、进程、协程
查看>>
MySQL查询今天/本周/上周/本月/上个月份的数据
查看>>
VS2010单元测试(转)
查看>>
WPF 四种尺寸单位
查看>>
ViewStub的应用场合
查看>>
(转)Android APK反编译详解
查看>>
MyBatis框架
查看>>
微信公众平台开发 - 微信支付(公众号支付)
查看>>
【每天学一点Linux】快速清除文件内容
查看>>
Myeclipse中易混淆的单词
查看>>
域账号修改后,导致vs中的git连接失败
查看>>
【数论】bzoj1477 青蛙的约会
查看>>
Vue学习
查看>>
redis集群结构图
查看>>
是用CXF开发Web Service
查看>>