文档章节

Shell控制台IO

如比如比
 如比如比
发布于 2017/04/02 08:37
字数 4255
阅读 136
收藏 0

●控制台IO
前面已经提到输出的命令echo和printf。也有是read获取输入的例子。
read 命令用法详解
1. 简介
  read是一个buildin命令,主要完成对参数的赋值,类似C语言中的scanf。其不仅可以赋值变量,还可以赋值数组;其输入不仅是屏幕,还可以是文件描述符。

2. man中选项说明
    -a aname
           The words are assigned to sequential indices  of  the  array  variable
           aname,  starting  at  0.   aname  is  unset  before any new values are
           assigned.  Other name arguments are ignored.
    -d delim
           The first character of delim is used  to  terminate  the  input  line,
           rather than newline.
    -e     If  the  standard input is coming from a terminal, readline (see READ-
           LINE above) is used to obtain the line.
    -n nchars
           read returns after reading nchars characters rather than waiting for a
           complete line of input.
    -p prompt
           Display  prompt  on standard error, without a trailing newline, before
           attempting to read any input.  The prompt is displayed only  if  input
           is coming from a terminal.
    -r     Backslash  does not act as an escape character.  The backslash is con-
           sidered to be part of the line.  In  particular,  a  backslash-newline
           pair may not be used as a line continuation.
    -s     Silent  mode.   If input is coming from a terminal, characters are not
           echoed.
    -t timeout
           Cause read to time out and return failure if a complete line of  input
           is not read within timeout seconds.  This option has no effect if read
           is not reading input from the terminal or a pipe.
    -u fd  Read input from file descriptor fd.
-a 后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符。
-d 后面跟一个标志符,其实只有其后的第一个字符有用,作为结束的标志,会举例说  明。
-p 后面跟提示信息,即在输入前打印提示信息。
-e 在输入的时候可以时候命令补全功能。
-n 后跟一个数字,定义输入文本的长度,很实用。
-r 屏蔽\,如果没有该选项,则\作为一个转义字符,有的话 \就是个正常的字符了。
-s 安静模式,在输入字符时不再屏幕上显示,例如login时输入密码。
-t 后面跟秒数,定义输入字符的等待时间。
-u 后面跟fd,从文件描述符中读入,该文件描述符可以是exec新开启的。

3. 应用
1、基本读取
read命令接收标准输入(键盘)的输入,或其他文件描述符的输入(后面在说)。得到输入后,read命令将数据放入一个标准变量中。下面是read命令
的最简单形式::
#!/bin/bash
echo -n "Enter your name:"   //参数-n的作用是不换行,echo默认是换行
read  name                   //从键盘输入
echo "hello $name,welcome to my program"     //显示信息
exit 0                       //退出shell程序。
//********************************
由于read命令提供了-p参数,允许在read命令行中直接指定一个提示。
所以上面的脚本可以简写成下面的脚本::
#!/bin/bash
read -p "Enter your name:" name
echo "hello $name, welcome to my program"
exit 0
在上面read后面的变量只有name一个,也可以有多个,这时如果输入多个数据,则第一个数据给第一个变量,第二个数据给第二个变量,如果输入数据个数过多,则最后所有的值都给第一个变量。如果太少输入不会结束。
//*****************************************
在read命令行中也可以不指定变量.如果不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中。
例如::
read -p "Enter a number"
环境变量REPLY中包含输入的所有数据,可以像使用其他变量一样在shell脚本中使用环境变量REPLY.

2、计时输入
使用read命令存在着潜在危险。脚本很可能会停下来一直等待用户的输入。如果无论是否输入数据脚本都必须继续执行,那么可以使用-t选项指定一个计时器。
-t选项指定read命令等待输入的秒数。当计时满时,read命令返回一个非零退出状态;
#!/bin/bash
if read -t 5 -p "please enter your name:" name
then 
    echo "hello $name ,welcome to my script"
else
    echo "sorry,too slow"
fi
exit 0
除了输入时间计时,还可以设置read命令计数输入的字符。当输入的字符数目达到预定数目时,自动退出,并将输入的数据赋值给变量。
#!/bin/bash
read –n 1 -p "Do you want to continue [Y/N]?" answer
case $answer in
Y | y)
      echo "fine ,continue";;
N | n)
      echo "ok,good bye";;
*)
     echo "error choice";;
esac
exit 0
该例子使用了-n选项,后接数值1,指示read命令只要接受到一个字符就退出。只要按下一个字符进行回答,read命令立即接受输入并将其传给变量。无需按回车键。

3、默读(输入不显示在监视器上)
有时会需要脚本用户输入,但不希望输入的数据显示在监视器上。典型的例子就是输入密码,当然还有很多其他需要隐藏的数据。
-s选项能够使read命令中输入的数据不显示在监视器上(实际上,数据是显示的,只是 read命令将文本颜色设置成与背景相同的颜色)。
#!/bin/bash
read  -s  -p "Enter your password:" pass
echo "your password is $pass"
exit 0 

4、读文件
最后,还可以使用read命令读取Linux系统上的文件。
每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出。
读取文件的关键是如何将文本中的数据传送给read命令。
最常用的方法是对文件使用cat命令并通过管道将结果直接传送给包含read命令的 while命令
例子::
#!/bin/bash
count=1    //赋值语句,不加空格
cat test | while read line        //cat 命令的输出作为read命令的输入,read读到的值放在line中
do
   echo "Line $count:$line"
   count=$[ $count + 1 ]          //注意中括号中的空格。
done
echo "finish"
exit 0

4. 举例
 -a举例:
root@localhost:~/test#read -a tao
qq ww ee rr
root@localhost:~/test#echo ${tao[1]}
Ww
-b举例:
root@localhost:~/test#read -d eof -a tao
ww
dd
gg
hh  (输入一个e)
root@localhost:~/test#echo ${tao[3]}
Hh
-n举例:
root@localhost:~/test#read -n3 -p "you can input 3 word:"
you can input 3 word:xxx
(输入3个字符后自动退出!)
-s举例:
root@localhost:~/test#read -p password: -s passwd
password:
(这时候输入就不再显示在屏幕上了!)
-e举例:
root@localhost:~/test#read -e file
(tab键补全)
exp1               file               ngis_post.sh       text              
exp5               linux-2.6.27.54/   test               xen-3.0.1-install/

-u举例:
root@localhost:~/test#exec 3<file
root@localhost:~/test#read -u 3 tao
root@localhost:~/test#echo $tao
hello world!
root@localhost:~/test#
注意看下读入的次序:
root@localhost:~/test#cat file
hello world!
i am good
root@localhost:~/test#exec 3<file
root@localhost:~/test#read -u 3 tao
root@localhost:~/test#echo $tao
hello world!
root@localhost:~/test#read -u 3 tao
root@localhost:~/test#echo $tao
i am good
root@localhost:~/test#
这个选项很有用的,特别是自循环读入的时候。 
 

 


■Shell输入输出重定向
Shell Here Document,/dev/null文件
Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器。

输出重定向
命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向。

命令输出重定向的语法为:
$ command > file
这样,输出到显示器的内容就可以被重定向到文件。

例如,下面的命令在显示器上不会看到任何输出:
$ who > users
打开 users 文件,可以看到下面的内容:
$ cat users
oko         tty01   Sep 12 07:30
ai          tty15   Sep 12 13:32
ruth        tty21   Sep 12 10:10
pat         tty24   Sep 12 13:07
steve       tty25   Sep 12 13:03
$
输出重定向会覆盖文件内容,请看下面的例子:
$ echo line 1 > users
$ cat users
line 1
$
如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,例如:
$ echo line 2 >> users
$ cat users
line 1
line 2
$

输入重定向
和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:
command < file
这样,本来需要从键盘获取输入的命令会转移到文件读取内容。

注意:输出重定向是大于号(>),输入重定向是小于号(<)。

例如,计算 users 文件中的行数,可以使用下面的命令:
$ wc -l users
2 users
$
也可以将输入重定向到 users 文件:
$ wc -l < users
2
$
注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。

重定向深入讲解
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

如果希望 stderr 重定向到 file,可以这样写:
$command 2 > file
如果希望 stderr 追加到 file 文件末尾,可以这样写:
$command 2 >> file

2 表示标准错误文件(stderr)。
如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
$command > file 2>&1

$command >> file 2>&1
如果希望对 stdin 和 stdout 都重定向,可以这样写:
$command < file1 >file2
command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。 

全部可用的重定向命令列表
命令    说明
command > file    将输出重定向到 file。
command < file    将输入重定向到 file。
command >> file    将输出以追加的方式重定向到 file。
n > file    将文件描述符为 n 的文件重定向到 file。
n >> file    将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m    将输出文件 m 和 n 合并。
n <& m    将输入文件 m 和 n 合并。
<< tag    将开始标记 tag 和结束标记 tag 之间的内容作为输入。

Here Document
Here Document 目前没有统一的翻译,这里暂译为”嵌入文档“。Here Document 是 Shell 中的一种特殊的重定向方式,它的基本的形式如下:
command << delimiter
    document
delimiter
它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。

注意:
结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
开始的delimiter前后的空格会被忽略掉。

下面的例子,通过 wc -l 命令计算 document 的行数:
$wc -l << EOF
    This is a simple lookup program
    for good (and bad) restaurants
    in Cape Town.
EOF
3
$
也可以 将 Here Document 用在脚本中,例如:
#!/bin/bash
cat << EOF
This is a simple lookup program
for good (and bad) restaurants
in Cape Town.
EOF
运行结果:
This is a simple lookup program
for good (and bad) restaurants
in Cape Town.

下面的脚本通过 vi 编辑器将 document 保存到 test.txt 文件:
#!/bin/sh
filename=test.txt
vi $filename <<EndOfCommands
i
This file was created automatically from
a shell script
^[
ZZ
EndOfCommands
运行脚本:
$ sh test.sh
Vim: Warning: Input is not from a terminal
$
打开 test.txt,可以看到下面的内容:
$ cat test.txt
This file was created automatically from
a shell script
$
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
$ command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到”禁止输出“的效果。

如果希望屏蔽 stdout 和 stderr,可以这样写:
$ command > /dev/null 2>&1

I/O重定向
I/O重定向简单来说就是一个过程,这个过程捕捉一个文件,或者命令,程序,脚本,甚至脚本中的代码块(code block)的输出,然后把捕捉到的输出,作为输入发送给另外一个文件,命令,程序,或者脚本。
如果谈到I/O重定向,就涉及到文件标识符(File Descriptor)的概念, 在Linux系统中,系统为每一个打开的文件指定一个文件标识符以便系统对文件进行跟踪,这里有些和C语言编程里的文件句柄相似,文件标识符是一个数字,不同数字代表不同的含义,默认情况下,系统占用了3个,分别是0标准输入(stdin),1标准输出(stdout), 2标准错误(stderr), 另外3-9是保留的标识符,可以把这些标识符指定成标准输入,输出或者错误作为临时连接。通常这样可以解决很多复杂的重定向请求。
标准输入通常指键盘的输入 
标准输出通常指显示器的输出 
标准错误通常也是定向到显示器

请看以下例子,来描述一下他们的关系
#ls /dev
这个命令列出/dev目录下的所有文件,在屏幕上输出结果。
这里 /dev 就是作为命令ls的标准输入(从键盘输入),而打印在屏幕的结果就是标准输出(/dev目录中的内容)
还是回到标题,重定向就是把标准的输入或者输出更改成其他的方式,请参看如下例子 
或者等同于
#ls /dev 1>filename                                  #注意:"1"和">"中间没有空格
以上命令会把命令的标准输出重新定向到一个文件filename,而不是显示到屏幕上,如果不指明文件标识符,系统默认的就是1, 因此1可以省略
如果把上面例子重的">"改成">>"则表示把输出追加到filename文件的末尾,如果文件不存在则创建它。如下
#ls /dev >>filename
也可以把标准错误重新定向到文件
#ls -qw  /dev  2>filename
显然 -qw是一个错误参数,通常会在显示器上报告一个错误信息,但由于把2标准错误(stderr)重新定向到了文件filename,因此显示器没有错误信息,而信息写到了文件里面
以下命令是把标准输出和错误都定向到文件
#ls /dev &>filename
"&"在这里代表标准输出和标准错误,这里无论是正常输出还是错误信息都写到filename中了。
重新定义标准输入,输出,和错误的文件标识符
重新定义文件标识符可以用i>&j命令,表示把文件标识符i重新定向到j,你可以把"&"理解为"取地址"
请看以下例子
#exec 5>&1
表示把文件标识符5定向到标准输出,这个命令通常用来临时保存标准输入。
同样标准输入也是可以重新定向的,请参考下面例子
# grep search-word <filename或者grep search-word 0<filename
一般来说grep命令在给定文件中搜索字符串,以上命令把文件filename作为grep命令的标准输入,而不是从键盘输入。
前面曾经提到,系统为每一个打开的文件指定一个文件标识符以便系统对文件进行跟踪,那么默认的文件标识符是什么呢?答案是0,也就是标准输入,或者可以说从键盘输入。当然这个文件标识符也可以自己指定,请参考下面例子
#echo 123456789 >filename   把字符串写到文件filename中
#exec 3<>filename           把文件filename打开,并指定文件标识符为3
#read -n 4 <&3              从文件中读4个字符,句柄已经指到第四个字符末尾
#echo -n . >&3              在第5个字符处写一个点,覆盖第5个字符,-n表示不换行
#exec 3>&-          关闭文件标识符3
现在cat filename文件的结果就成了1234.6789
命令j<>filename表示把文件打开,并指明文件标识符为j 
"&-"表示关闭文件标识符
有关关闭文件标识符的操作请参考下面
n<&- 关闭输入文件标识符n
0<&-或<&- 关闭标准输入stdin
n>&- 关闭输出文件标识符n
1>&-或>&-关闭标准输出stdout
另外还有一些其他命令,如下参考
2.:> filename 或者 > filename
表示把文件filename设置成空,也就是清空文件内容,如果文件不存在,则创建一个空文件,(等同于touch命令) :表示一个空输出,两个命令的唯一区别就是>filename不是在所有shell都可以正常工作的。

 

© 著作权归作者所有

上一篇: Shell文件包含
下一篇: Shell函数
如比如比
粉丝 126
博文 178
码字总数 286951
作品 0
日本
程序员
私信 提问
使用xconsole调试和上载nodemcu的lua文件

简介 xconsole是基于控制台的工具,将串口交互、远程访问和本地调用融为一个工具。 该工具使用python开发,而且全部开源,以便可以直接整合到你的工具集之中。 项目地址:https://git.oschi...

openthings
2015/01/17
264
0
无名小卒/VShell

#虚拟控制台(Virtual Shell) ##什么是虚拟控制台? 虚拟控制台(VShell)是一个基于Web的控制台终端模拟程序,它像windows的命令行,linux的shell一样提供一个命令行接口,你可以在这里执行任...

无名小卒
2015/04/02
0
0
在UNIX上后台运行任务(Shell),bg还是nohup

有时候一个任务运行的时间很长,需要将其放在后台运行,否则推出控制台后任务就会被终止,本文讲解一下怎么让任务在后台运行。 比如一个shell脚本,longjobs.sh运行要很长时间,并且运行中有...

晨曦之光
2012/04/25
1K
0
关键七步,用Apache Spark构建实时分析Dashboard

问题描述 电子商务门户希望构建一个实时分析仪表盘,对每分钟发货的订单数量做到可视化,从而优化物流的效率。 解决方案 解决方案之前,先快速看看我们将使用的工具: Apache Spark – 一个通...

勿忘初心321
2016/11/23
26
0
解决windows的控制台和shell比较KUSO的问题(ConEmu&&Pycmd)

控制台用ConEmu shell用 pycmd =================================================================== 把pycmd加到ConEmu控制台作为控制台的默认shell 也可以添加pytty vim ipython。。。。......

0mdzz
2014/04/12
133
0

没有更多内容

加载失败,请刷新页面

加载更多

kibana汉化

kibana5 / 6 需要下载补丁包,https://github.com/anbai-inc/Kibana_Hanization 其中 v6 版本原生支持国际化,只需要添加资源文件并且配置即可 kibana7 v7版本官方内置汉化资源,在配置文件 ...

细肉云吞
21分钟前
5
0
spring boot 自定义日志 log4j2

使用默认的日志在实际开发中会存在很多问题,比如备份文件名称无法自动重命名、各个等级的日志被放在一个文件中等,所以实际开发中为了更好满足我们的需求,我们一般都会自定义采用配置的方式...

雷开你的门
26分钟前
7
0
PCB设计-Allegro软件入门系列-设计参数配置(上)

前言 经历了导入网表,和放置器件后,我们就要画板子了,但是必要的设计参数也要先准备好,磨刀不误砍柴工。 《一》显示参数 这里主要设置DRC报错标志大小和飞线显示类型 (1)DRC标志可以适当...

demyar
27分钟前
6
0
js实现微博、微信分享

html <!-- 分享 --><div class="share-box"> <b style="vertical-align: middle;">分享到:</b> <a title="分享到新浪微博" class="shareSina"><span class="share-icon"></span><......

张兴华ZHero
42分钟前
7
0
创龙TMS320DM8168浮点DSP C674x + ARM Cortex-A8的CPU、NAND FLASH、NOR FLASH

TL6678-EasyEVM是广州创龙基于SOM-TL6678核心板而研发的一款多核高性能DSP开发板。开发板采用核心板+底板方式,底板采用沉金无铅工艺的四层板设计,尺寸为200mm*106.65mm,它为用户提供了SOM...

Tronlong创龙
46分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部