bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html


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[]}
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 

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

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

[root@xuexi ~]# read -n 

[root@xuexi ~]# echo $REPLY

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

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

(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"的作用,见http://www.cnblogs.com/f-ck-need-u/p/8454364.html

(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

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

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

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

[root@xuexi ~]# var=

[root@xuexi ~]# read -t  var

[root@xuexi ~]# echo $var

1.3 while read line

如果read不明确指定按字符数读取文件(或标准输入),那么默认是按行读取的,而且每读一行都会在那一行处打上标记(即文件指针。当然,按字符数读取也一样会打上标记),表示这一次已经读取到了这个地方,使得下次仍然能够从这里开始继续向下读取。这使得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中执行,而且,cat test1会一次性将test1文件所有数据装入内存,如果test1文件足够大,会直接占用巨量内存。而第二个示例使用输入重定向的方式则每次只占用一行数据的内存,而且是在当前shell环境下执行的,while内的变量赋值、数组赋值在退出while后仍然有效。

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

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

1.4 精确输出每行数据

while read line在读取数据时,默认是按照IFS变量来将所读取的行数据进行切割保存到各对应的变量当中。这会使得所读取的数据在保存到line中时会丢失前缀空白。

所以,要想原原本本地输出每行数据,需要修改IFS。不仅如此,在保存到line中之后,在使用line时还需要加上双引号包围,否则前缀空格仍然会在变量替换后被忽略。

所以,最佳方式如下:

[root@xuexi ~]# while IFS= read -r line;do echo "$line";done <filename

上面还加上了-r选项,表示忽略原始数据中的反斜线转义功能,而是当作原本的反斜线字符输出。

这样,就真正的原原本本地输出了每行数据。

SHELL脚本--read命令的更多相关文章

  1. linux 执行远程linux上的shell脚本或者命令以及scp 上传文件到ftp--免密码登陆

    场景:在linux A 上执行Linux B上的shell脚本和命令 步骤1.设置ssh免登陆 1.SSH无密码登录 # 本地服务器执行(A机器):生成密钥对 ssh-keygen -t dsa -P ...

  2. shell 脚本控制命令的执行顺序

    &&,||,(),{},& 五个符号的运用shell脚本执行命令的时候,有时候会依赖于前一个命令是否执行成功.而&&和||就是用来判断前一个命令执行效果的. 也 ...

  3. Linux之Shell脚本计算命令行的所有和

    问题:设计一个Shell脚本:求命令行上所有整数和 Shell代码: 调用add.sh脚本结果:

  4. Makefile Shell 脚本;sed命令

    1. 在Makefile中想使用shell脚本,需要添加"@"符号,例如: @if [ -d xxx ]; then \                        //-d 判 ...

  5. Linux Shell脚本Ldd命令原理及使用方法

    1.首先ldd不是一个可执行程序,而只是一个shell脚本2.ldd能够显示可执行模块的dependency,其原理是通过设置一系列的环境变量如下:LD_TRACE_LOADED_OBJECTS.LD ...

  6. Shell 脚本常用命令

    Shell脚本是Linux开发工作中常用的工具,但是我一直没有找到一个适合自己的简明扼要的HandBook.在工作过程中整理了一下,贴在这里已备查看. 1           Shell中的特殊符号 ...

  7. linux shell脚本、命令学习

    1,echo "test" > test.txt    输出重定向到text.txt,文件不存在就创建 echo "test" >> test ...

  8. 使用getopt命令解析shell脚本的命令行选项 【转】

    本文转载自:http://yejinxin.github.io/parse-shell-options-with-getopt-command 在之前的一篇文章中,介绍了如何利用shell内置的get ...

  9. shell脚本常用命令汇总

    一.shell脚本概述和入门 (1)shell脚本是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核 (2)shell脚本的常用执行方式: 第一种:采用bash或sh+脚本的相对路径或 ...

  10. 用 shell 脚本做命令行工具扩展

    问题的提出 公司开发机与远程服务器之间有严格的隔离策略,不能直接使用 ssh 登录,而必需通过跳板机.这样一来,本地与服务器之间的一些文件传输变得非常不便.经过咨询,运维教了我一招: $ nc -l ...

随机推荐

  1. Windows 注册表 16进制时间转换( Convert Reg_binary Time to a Datetime )

    背景: Windows注册表中,存在大量16进制的时间,以 reg_binary存储在注册表中. 例如: 0D 6C A4 4B 37 C5 CE 01 这种值日常报表中需要转换为适合人阅读的格式,实 ...

  2. OpenCV3.30 画图函数

    画图函数(Draw Functions)都放在imgpro. 例如C++中用: #include <opencv2\imgproc.hpp>

  3. formated time string for file naming

    #include <stdio.h> #include <time.h> int main() { time_t rawtime; struct tm *timeinfo; ] ...

  4. PIL库图像处理

    PIL有如下几个模块 Image模块.ImageChops模块.ImageCrackCode模块 ImageDraw模块.ImageEnhance模块.ImageFile模块 ImageFileIO模 ...

  5. 10个经典的Java面试题集合

    这里有10个经典的Java面试题,也为大家列出了答案.这是Java开发人员面试经常容易遇到的问题,相信你了解和掌握之后一定会有所提高.让我们一起来看看吧. 1.Java的HashMap是如何工作的? ...

  6. 致我们再也回不去的 Github ...

    本文原文来自公众号 stormzhang,原作者自称“二流学校毕业.非科班出身.从 0 自学编程到现在的「段子张」”. 1.前言   相信大家都知道了,微软已确认要收购 GitHub 了,Github ...

  7. PackageManager整理

    一.PackageManager的功能 1.安装.卸载应用.2.查询permission相关信息.3.查询Application相关信息(application,activity,receiver,s ...

  8. 第四节:详细讲解Java中的类和面向对象思想

    前言 大家好,给大家带来详细讲解Java中的类和面向对象思想的概述,希望你们喜欢 类和面向对象 在Java中怎样理解对象,创建对象和引用:什么是引用,对于基础学习的同学,要深入了解引用.示例:Stri ...

  9. 用XMLHttpRequest制作一个简易ajax

    概述 jquery退出历史舞台之后,我们怎么来发送ajax请求呢?可以用相关的库,也可以自己制作一个简易的ajax. 需要说明的是,我们使用的是XMLHttpRequest 2,它几乎兼容所有主流浏览 ...

  10. [Postman]历史(8)

    邮递员将您发送的所有请求存储在左侧边栏的“历史记录”视图中.您可以使用历史记录快速尝试各种请求,而不必浪费时间从头开始构建请求.您还可以通过单击请求名称来加载先前的请求. 如果您创建了一个帐户并登录P ...