Linux之read

1.read

read命令用于从标准输入中读取输入单行,并将读取的单行根据IFS变量分裂成多个字段,并将分割后的字段分别赋值给指定的变量列表var_name。第一个字段分配给第一个变量var_name1,第二个字段分配给第二个变量var_name2,依次到结束。如果指定的变量名少于字段数量,则多出的字段数量也同样分配给最后一个var_name,如果指定的变量命令多于字段数量,则多出的变量赋值为空。

如果没有指定任何var_name,则分割后的所有字段都存储在特定变量REPLY中。

2.read 参数

-a:将分裂后的字段依次存储到指定的数组中,存储的起始位置从数组的index=0开始。
-d:指定读取行的结束符号。默认结束符号为换行符。
-n:限制读取N个字符就自动结束读取,如果没有读满N个字符就按下回车或遇到换行符,则也会结束读取。
-N:严格要求读满N个字符才自动结束读取,即使中途按下了回车或遇到了换行符也不结束。其中换行符或回车算一个字符。
-p:给出提示符。默认不支持"\n"换行,要换行需要特殊处理,见下文示例。例如,"-p 请输入密码:"
-r:禁止反斜线的转义功能。这意味着"\"会变成文本的一部分。
-s:静默模式。输入的内容不会回显在屏幕上。
-t:给出超时时间,在达到超时时间时,read退出并返回错误。也就是说不会读取任何内容,即使已经输入了一部分。
-u:从给定文件描述符(fd=N)中读取数据。

3.用例

 3.1 将读取的内容分配给数组变量,从索引号0开始分配。

[root@VM-4-13-centos shell]# read -a array
AA BB CC
[root@VM-4-13-centos shell]# echo ${array[0]}
AA
[root@VM-4-13-centos shell]# echo ${array[1]}
BB
[root@VM-4-13-centos shell]# echo ${array[2]}
CC
[root@VM-4-13-centos shell]# echo ${array[3]}

[root@VM-4-13-centos shell]# echo ${array[@]}
AA BB CC

 3.2 指定读取行的结束符号,而不再使用换行符。

[root@VM-4-13-centos shell]# read -d "@"
123abcABC@[root@VM-4-13-centos shell]# echo $REPLY
123abcABC
[root@VM-4-13-centos shell]# 

输入完尾部的"@",自动结束read命令。由于没有用其它的字符值来指定输入的值,所以通过默认$REPLY变量查看read读取的行。$REPLY : 当没有参数变量提供给read命令的时候,这个变量会作为默认变量提供给read命令

 3.3 限制输入字符。

例如输入三个字符就结束。

[root@VM-4-13-centos sed]# read -n 3
ab2[root@VM-4-13-centos sed]# echo $REPLY
ab2

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

[root@VM-4-13-centos sed]# echo $REPLY
a2
[root@VM-4-13-centos sed]# 

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

[root@VM-4-13-centos sed]# read -N 3
a       #a后的回车(换行)算是一个字符
1[root@VM-4-13-centos sed]# echo $REPLY
a 1
[root@VM-4-13-centos sed]# 

3.4 使用-p选项给出输入提示。

[root@VM-4-13-centos sed]# read -p "please enter you password:"
please enter you password:123
[root@VM-4-13-centos sed]# echo $REPLY
123
[root@VM-4-13-centos sed]# 

"-p"选项默认不带换行功能,且也不支持"\n"换行。但通过$'string'的方式特殊处理,就可以实现换行的功能。$'string',在bash中被特殊对待:会将某些反斜线序列(如\n,\t,\",\'等)继续转义,而不认为它是字面符号(如果没有$符号,单引号会强制将string翻译为字面符号,包括反斜线)。

[root@VM-4-13-centos sed]# echo 'a\nb'
a\nb
[root@VM-4-13-centos sed]# echo $'a\nb'
a
b
[root@VM-4-13-centos sed]# read -p $'please enter you password:\n'
please enter your password:
123
[root@VM-4-13-centos sed]# echo $REPLY
123
[root@VM-4-13-centos sed]# 

3.5 禁止反斜线转义功能。

[root@VM-4-13-centos sed]# read 
where is \?
[root@VM-4-13-centos sed]# echo $REPLY
where is ?
[root@VM-4-13-centos sed]# read -r
where is \?
[root@VM-4-13-centos sed]# echo $REPLY
where is \?

3.6 不回显输入的字符。比如输入密码的时候,不回显输入密码。

[root@VM-4-13-centos sed]# read -s -p "please your enter password:"
please your enter password:[root@VM-4-13-centos sed]# echo $REPLY
123
[root@VM-4-13-centos sed]# 

3.7 将读取的行分割后赋值给变量。

[root@VM-4-13-centos sed]# read a b c
11 2 3
[root@VM-4-13-centos sed]# echo $a $b $c
11 2 3

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

[root@VM-4-13-centos sed]# read -t 3
12
[root@VM-4-13-centos sed]# echo $REPLY
12

3.9 while read line

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

[root@VM-4-13-centos shell]# cat test.txt 
a
b
c
d

用法1:

[root@VM-4-13-centos shell]# cat test.txt |while read line ;do echo $line ;done; 
a
b
c
d

用法2:

[root@VM-4-13-centos shell]# while read line ;do echo $line ;done <test.txt
a
b
c
d

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

 

posted @ 2022-09-26 14:07  家乐福的搬砖日常  阅读(586)  评论(0编辑  收藏  举报