SHELL脚本read命令的具体用法

 更新时间:2020年7月11日 15:10  点击:2017

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[0]}
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 5
12345

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

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

[root@xuexi ~]# read -n 5
123

[root@xuexi ~]# echo $REPLY
123

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

[root@xuexi ~]# read -N 5
123\n4

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

(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"的作用

有些时候在某些服务管理脚本中看到$"$string"或$"string",经过一些测试,又发现引号外面的$有和没有是一样的。一直也没去找究竟,刚才有人问了我,于是就去翻了下man bash,找到了解释。

(1).如果没有特殊定制bash环境或有特殊需求,$"string"和"string"是完全等价的,使用$""只是为了保证本地化。

以下是man bash关于$""的解释:

       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,\",\'等)继续转义,而不认为它是字面符号(如果没有$符号,单引号会强制将string翻译为字面符号,包括反斜线)。简单的例子:

[root@xuexi ~]# echo 'a\nb'
a\nb
[root@xuexi ~]# echo $'a\nb'
a
b

以下是man bash里关于$'的说明:

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).禁止反斜线转义功能。

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

[root@xuexi ~]# var=5

[root@xuexi ~]# read -t 3 var
1

[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,如果你还不理解或者找不到其它方式,那么直接记住这个结论。

到此这篇关于SHELL脚本read命令的具体用法的文章就介绍到这了,更多相关SHELL read命令内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • php webshell下直接反弹shell的例子

    webshell对于我们站长来讲肯定听到比较多了,我们网站可能经常被人使用期webshell方式注入一些东西了,下面一起来看一个php webshell下直接反弹shell的例子,具体如下。...2016-11-25
  • Powershell实现编写和运行脚本

    本文为那些对学习 Windows PowerShell 命令行和脚本编写环境感兴趣的系统管理员提供了资源。也请告诉我们本网站如何才能对您更有用处。...2020-06-30
  • Shell脚本中让进程休眠的方法(sleep用法)

    这篇文章主要介绍了Shell脚本中让进程休眠的方法,本文讲解的就是sleep的用法,可以实现睡觉若干秒、若干分钟、若干小时,需要的朋友可以参考下...2020-07-11
  • Linux 下使用shell脚本定时维护数据库的案例

    这篇文章主要介绍了Linux 下使用shell脚本定时维护数据库,本文通过案例分析给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11
  • 解决使用OpenCV中的imread()内存报错问题

    这篇文章主要介绍了解决使用OpenCV中的imread()内存报错问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • shell脚本实战-while循环语句

    这篇文章主要介绍了shell脚本实战-while循环语句,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-09
  • Shell字符串比较相等、不相等方法小结

    这篇文章主要介绍了Shell字符串比较相等、不相等方法小结,本文直接给出代码,但代码中含有大量注释,需要的朋友可以参考下...2020-07-11
  • C#多线程之Thread类详解

    这篇文章主要为大家详细介绍了C#多线程之Thread类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • 自动设置安卓手机wifi代理的PowerShell脚本

    这篇文章主要介绍了自动设置安卓手机wifi代理的PowerShell脚本,帮助大家进行抓包测试,感兴趣的朋友可以了解下...2020-10-17
  • shell中的for循环用法详解

    这篇文章主要介绍了shell中的for循环用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-11
  • PowerShell中使用Get-Date获取日期时间并格式化输出的例子

    这篇文章主要介绍了PowerShell中使用Get-Date获取日期时间并格式化输出的例子,本文讲解了直接调用Get-Date、在Write-Host中使用Get-Date、格式化输出的方法,需要的朋友可以参考下...2020-06-30
  • PowerShell读取文件内容、替换文件内容、读取限定行的例子

    这篇文章主要介绍了PowerShell读取文件内容、替换文件内容、读取限定行的例子,本文使用3个例子来说明实现这3个需求的操作技巧,需要的朋友可以参考下...2020-06-30
  • shell脚本多实例部署nginx的详细教程

    周一今天给大家分享shell脚本多实例部署nginx的详细教程,文章通过实例代码脚本给大家详细介绍,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...2021-10-26
  • Linux Shell脚本中获取本机ip地址方法

    这篇文章主要介绍了Linux Shell脚本中获取本机ip地址方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-20
  • Shell脚本8种字符串截取方法总结

    这篇文章主要介绍了Shell脚本8种字符串截取方法总结,每个方法给出了实例代码和操作结果,一目了然,需要的朋友可以参考下...2020-07-11
  • mac使用Shell(终端)SSH连接远程服务器的方法

    这篇文章主要介绍了mac使用Shell(终端)SSH连接远程服务器的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-11
  • Shell逐行读取文件的4种方法

    这篇文章主要介绍了Shell逐行读取文件的4种方法,本文介绍了while循环法、重定向法、管道法、文件描述符法等一些方法,需要的朋友可以参考下...2020-07-11
  • shell脚本批量复制及执行命令的示例详解

    这篇文章主要介绍了批量复制及执行命令shell脚本,本文通过列举几个示例给大家详细介绍,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11
  • Shell脚本中执行sql语句操作mysql的5种方法

    这篇文章主要介绍了Shell脚本中执行sql语句操作mysql的5种方法,本文讲解了将SQL语句直接嵌入到shell脚本文件中、命令行调用单独的SQL文件、使用管道符调用SQL文件等方法,需要的朋友可以参考下...2020-07-11