15.1 理解输入和输出

现在知道两种显示脚本输出的方法

1)在显示器屏幕上显示

2)将输出文件重定向到文件中

15.1.1 标准文件描述符

Linux系统将每个对象当做文件处理。这包括输入和数出进程。

Linux用文件描述符来标识每个文件对象。

它是一个非负整数,可以唯一标识会话中打开的文件。

每个进程一次最多可以有九个文件描述符

bash shell保留的前3个文件描述符(0、 1、 2)

1.STDIN 标准输入(0)

STDIN文件代表shell的标准输入。

对终端界面来说,标准输入是键盘。

shell从STDIN文件描述符对应的键盘获得输入,在用户输入时处理每个字符

在使用输入重定向符号( < )时,Linux会用重定向指定的文件来替换标准输入文件描述符。它会读取文件并提取数据,就如同它是键盘上键入的。

2.STDOUT 标准输出(1)

STDOUT文件描述符代表shell的标准输出。

对终端界面来说,标准输出是终端显示器。shell的所有输出会被定向到标准输出中。

也可以通过输出重定向( > )来改变输出。通过输出重定向符号,可以将本来显示在显示器上的输出重定向到指定的文件。

>>  表示追加到文件

注意:用了输出重定向,shell并未将错误消息重定向到输出重定向文件中。错误消息仍会显示在显示器中。

3.STDERR 标准错误(2)

STDERR文件描述符来处理错误消息。

shell或shell中运行的程序和脚本出错时生成的错误消息都会发送到这个位置。

默认情况下STROUT和STDERR指向同样的地方(显示器)。但是STDERR不会随着STDOUT重定向而发生改变。

15.1.2 重定向错误

1.只重定向错误

将该文件描述符值(2)放在重定向符号(>)前面,必须挨着,不能有空格。

比如,查看一个不存在的文件:

$ls –al 2> log.txt

这种方法只会重定向错误消息,普通输出不会被重定向。

2. 重定向错误和数据

需要用两个重定向符号,需要在符号前面放上待重定向数据所对应的文件描述符,然后指定用于保存数据的输出文件。

例如:

$ls -al test1 test2 test3 badfile 2> ErrLog.txt 1> DataLog.txt

表示将错误信息重定向到ErrLog.txt,正常输出重定向到DataLog.txt。

这样错误信息和正常输出就分开在两文件了。

$ls -al test1 test2 test3 badfile &> AllLog.txt

这样表示将STDOUT和STDERR重定向到同一个文件AllLog.txt中了。

bash shell自动赋予了错误消息更高的优先级,这样可以集中浏览错误信息了。

15.2 在脚本中重定向输出

有两种方法:

1)临时重定向行输出

2)永久重定向脚本中的所有命令

15.2.1 临时重定向

可以单独将一行重定向到STDERR。

比如:

echo “this is error msg” >&2

echo “this is normal msg”

正常运行不会看出什么,但是假如运行时重定向了STDERR就有意思了。

$./test 2> Error.txt

就可以看到第一行输出到了 Error.txt。而正常输出还是在屏幕上。

15.2.2 永久重定向

如果有大量数据需要重定向,那么就会比较麻烦。

新方法:用exec命令告诉shell在脚本执行期间重定向某个特定文件描述符

直接上例子:

1 #!/bin/bash

  2 echo "this is error msg step1" >&2

  3 echo "this is normal msg step1"

  4 # 上面没有重定向,所以还是在屏幕输出。下面才开始重定向到需要的文件中

  5 exec 1>test2log.txt

  6 exec 2>test2Error.txt

  7 echo "this is error msg step2" >&2

  8 echo "this is normal msg step2"

这样一旦重定向了就很难改回去了。

15.3 在脚本中重定向输入

exec 命令允许你将STDIN重定向到Linux系统上的文件中。

例子:查看test2中的数据

  1 #!/bin/bash

  2 exec 0< test2 # 输入重定向到test2

  3 echo "test2:"

  4 count=1

  5 while read line

  6 do

  7         echo "  $line"

  8         count=$[ $count + 1 ]

  9 done

15.4 创建自己的重定向

之前说一个进程最多可以与9个打开的文件描述符。其他6个(3 ~ 8)的文件描述符均可用作输入或输出重定向。

可以将这些文件描述符中的任意一个分配给文件。

15.4.1 创建输出文件描述符

用exec命令给输出分配文件描述符。

和标准的文件描述符一样,一旦将另一个文件描述符分配给了一个文件,这个重定向就会一直有效,直到你重新分配。

例子:

  1 #!/bin/bash

  2 exec 3>test4log.txt # exec 3>>test4log.txt 这个是将输出追加到现有文件

  3 echo "This is Normal msg"

  4 echo "This is fd:3 msg" >&3

15.4.2 重定向文件描述符

现在介绍怎么恢复已重定向的文件描述符。

可以分配另外一个文件描述符给标准文件描述符,反之亦然。

可以将STDOUT重定向到另外一个文件描述符,然后再利用该文件描述符重定向回STDOUT

例子:

  1 #!/bin/bash

  2 # storing STDOUT, then coming back to it

  3 exec 3>&1 # 3重定向到STDOUT。意味着给3的数据都将出现再显示器上

  4 exec 1>test5log.txt # 将STDOUT重定向到文件。但是3仍然指向STDOUT原来的位置,也就是显示器。这时给3发会显示在显示器中。给STDOUT发会显示在文件中

  5 echo "This should store in the output file"

  6 echo "alone with this line."

  7

  8 exec 1>&3 # 将STDOUT重定向到3的当前位置(也就是显示器)

  9 echo "now things should be back to normal"

15.4.3 创建输入文件描述符

跟上面类似,先将STDIN保存到另外一个文件描述符,然后读取完文件在将STDIN恢复

例子:

  1 #!/bin/bash

  2 exec 6<&0 # 6先保存STDIN的位置

  3 exec 0<test5 # 将STDIN重定向到 test5

  4 count=1

  5 while read line

  6 do

  7         echo "  $line"

  8         count=$[ $count +1 ]

  9 done

 10

 11 exec 0<&6 # 读取完成后将STDIN重定向到文件描述符6,从而恢复之前的位置

 12 read -p "Are you done now?" answer

 13 case $answer in

 14 Y|y) echo "GoodBye!!!";;

 15 N|n) echo "Sorry, this is the end";;

 16 *) echo "Error End";;

 17 esac

15.4.4 创建读写文件描述符

可以打开单个文件描述符作为输入和输出。可以利用同一个文件描述符对同一个文件进行读写。

用起来要小心:由于是对同一个文件进行数据读写,shell会维护一个内部指针,指明在文件中的当前位置。任何读或写都是从文件指针上次的位置开始。

例子:

1 #!/bin/bash

  2 exec 3<> testfile

  3 read line <&3

  4 echo "Read:$line" #注意这里写是从文件指针上次的位置开始,也就是读了一行之后的位置

  5 echo "Write: This is test line" >&3

15.4.5 关闭文件描述符

如果你创建了新的输入或输出文件描述符,shell会在脚本退出时自动关闭它们。

但是某些时候还是要自己去关闭。

如何关闭: 将要关闭的文件描述符重定向到特殊符号 &-

一旦关闭后,就不能在脚本中向他写入数据,否则shell会产生错误信息。

例子:

  1 #!/bin/bash

  2 # close fd test

  3 exec 3>test8log.txt

  4 echo "This is normal to fd:3" >&3

  5 exec 3>&-

  6 echo "after close write:his is normal to fd:3" >&3 # 关闭后再往里面写会出错

  7

  8 exec 3>test8log.txt # 这里相当于重新打开了

  9 echo "This is bad normal to fd:3" >&3 # 会覆盖原来的

15.5 列出打开的文件描述符

lsof命令会列出整个linux系统打开的所有的文件描述符。会产生大量输出。

还可以接选项和参数:

-p 后面接要查看的进程。  $$ 表示当前进程

-d 后面指定要显示的文件描述符编号。

例子:

  1 #!/bin/bash

  2 exec 3> testfile

  3 lsof -a -p $$ -d 0,1,2,3,4

15.6 阻止命令输出

有时不想显示脚本的输出。可以将输出重定向到一个叫做null文件的特殊文件中去。

比如:

$ls –al > /dev/null

还可以这样清空日志文件

$ cat /dev/null > TestLog.txt

15.7 创建临时文件

linux使用/tmp目录来存放不需要永久保留的文件。大部分linux发行版配置了系统在启动时自动删除/tmp目录下的所有文件。

系统上的任何用户账户都有权限在读写/tmp目录中的文件。

mktemp可以在/tmp目录中创建一个唯一的临时文件。一旦创建了文件,你就在脚本中有了完整的读写权限,别人无法访问它。

15.7.1 创建本地临时文件

只需要指定一个文件名模板就行了,在文件末尾加上6个X。

$mktemp testing.XXXXXX

注意:这里一定要有大写的X。这里的X有点通配符的意思。还可以写不是X的

mktemp命令的输出是它所创建的文件的名字。在脚本中保存起来,就能在后面的脚本里引用了。

例子:

  1 #!/bin/bash

  2 # create and using temp file

  3 tempfile=$(mktemp test10.XXXXXX)

  4 echo "tempfile = $tempfile"

  5 exec 3>$tempfile

  6 echo "This script writes to tmp file $tempfile"

  7 echo "this is first line" >&3

  8 echo "this is second line" >&3

  9 echo "this is third line" >&3

 10 exec 3>&-

 11

 12 echo  "Now delete file $tempfile"

 13 rm -f $tempfile > /dev/null

15.7.2 在/tmp目录创建临时文件

-t 选项会强制mktemp在系统的临时目录来创建该文件。

这个时候返回用来创建临时文件的全路径,而不是只有文件名。

就上面的例子加上 –t就好了。

。。。

tempfile=$(mktemp -t test10.XXXXXX)

。。。

15.7.3 创建临时目录

-d选项用来创建临时目录。这样就能用改目录进行任何需要的操作了。

例子:

  1 #!/bin/bash

  2 # create and using temp dir

  3 tempdir=$(mktemp -d test12dir.12XXXX)

  4 cd $tempdir

  5 echo This in Dir:$(pwd)

  6 tempfile=$(mktemp test12.XXXXXX)

  7 echo "tempfile = $tempfile"

  8 exec 3>$tempfile

  9 echo "This script writes to tmp file $tempfile"

 10 echo "this is first line" >&3

 11 echo "this is second line" >&3

 12 echo "this is third line" >&3

15.8 记录消息

输出同时发送到显示器和日志文件,需要特殊命令tee就可以了。

tee命令相当于管道第一个T型接头。它将STDIN过来的数据同时发往两处,一处是STDOUT,一处是指定的文件。

比如:

$date | tee log.txt

$date | tee –a log.txt   # 这个是将数据追加到文件中

例子:

  1 #!/bin/bash

  2 # tee test

  3 echo "This is 1 msg" | tee test13log.txt

  4 echo "This is 2 msg" | tee -a test13log.txt

  5 echo "This is 3 msg" | tee -a test13log.txt

15.9 实例

文件重定向常见于脚本需要读入文件和输出文件时。

需求:把数据数据放入电子表格中(.csv文件),读取文件,创建INSERT语句。

例子:

  1 #!/bin/bash

  2 outfile='members.sql'

  3 IFS=,

  4 while read name age sex num

  5 do

  6         cat >> $outfile << EOF

  7         insert into members (name, age, sex, num) values('$name', '$age', '$sex', '$num');

  8 EOF

  9 done <${1}

1)${1}代表第一个命令行参数。它指明了待读取数据的文件

2)read会用IFS字符解析读入的文本,我们在这里将IFS指定为逗号。

cat >> $outfile << EOF  // 这一段还是不大理解

这个包含一个输出追加重定向(>>)和一个输入追加重定向(<<)。

>> 将cat命令的输出追加到由$outfile变量指定的文件中。

cat命令的输入不在取自标准输入,而是被重定向到脚本中存储的数据。

EOF符号标记了追加到文件中的数据的起止。

输入文件 + 运行 + 结果:

说明:

特殊重定向(here document):

command << delimiter

         document

delimiter

作用是将两个delimiter之间的内容(document)作为输入传给command

注意:结尾的delimiter一定要顶格写,不能有空格

(1)

  6         cat >> $outfile << EOF

  7         insert into members (name, age, sex, num) values('$name', '$age', '$sex', '$num');

  8 EOF

(2)

  6         cat << EOF

  7         insert into members (name, age, sex, num) values('$name', '$age', '$sex', '$num');

  8 EOF

黄色高亮部分作为输入传给cat。(1)重定向到outfile去了,(2)仍然是标准输出(屏幕)

转载于:https://www.cnblogs.com/xcywt/p/7912037.html

《Linux命令行与shell脚本编程大全》第十五章 呈现数据相关推荐

  1. 《Linux命令行与shell脚本编程大全》第三章

    3.1 启动 shell GNU bash shell能提供对Linux系统的交互式访问.它是作为普通程序运行的,通常是在用户登录终端时启动.登录时系统启动的shell依赖于用户账户的配置. /etc ...

  2. 《Linux命令行与shell脚本编程大全》第十三章 学习笔记

    1.for命令 for命令的基本格式如下: for var in list do commands done 在每次迭代中,变量var会包含列表中的当前值.第一次迭代会使用列表中的第一个值,第 二次迭 ...

  3. 《Linux 命令行与 shell 脚本编程大全》第2章

    第二章:走进shell 哑终端(dumb terminal):通常是由通信电缆连接到Unix系统上的显示器和键盘(后来出现鼠标).这个简单的组合提供了向Unix系统输入文本数据和显示文本结果的一条捷径 ...

  4. Linux命令行与shell脚本编程大全:第2版

    <Linux命令行与shell脚本编程大全:第2版> 基本信息 作者: (美)布卢姆(Blum,R.) 布雷斯纳汉(Bresnahan.C.) [作译者介绍] 译者: 武海峰 丛书名: 图 ...

  5. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---34

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  6. Linux命令行与shell脚本编程大全(第3版)

    作者:[美] 布鲁姆(Richard Blum),布雷斯纳汉(Christine Bresnahan) 著,门佳,武海峰 译 出版社:人民邮电出版社 品牌:iTuring 出版时间:2016-08-0 ...

  7. Linux_《Linux命令行与shell脚本编程大全》第十八章学习总结

    时间:2017年12月04日星期一 说明:本文部分内容均摘取自书籍<Linux命令行与shell脚本编程大全>,版权归原作者所有.<Linux命令行与shell脚本编程大全>( ...

  8. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---02

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  9. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---20

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  10. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---43

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

最新文章

  1. java调用c dll,指针参数和结构体参数搞定
  2. Ehcache BigMemory: 摆脱GC困扰(转)
  3. leetcode733. 图像渲染(bfs)
  4. [Android疑难杂症]Gallery默认和横竖屏切换选中状态问题(2.3、2.3系统存在)
  5. 路径-真机和虚拟机共享
  6. [转]关于Linux下时间片分配给进程还是线程的问题
  7. 纬地道路纵断面设计教程_市政道路从识图算量到施工工艺,一篇全搞定
  8. 三菱FX5U,机床X轴Y轴工作台定位控制程序 使用三菱J4-A系列伺服驱动器绝对位置系统,程序大小27000多步
  9. 一次完整的http请求过程
  10. 陶瓷PCB电路板生产工艺
  11. python 杨辉三角居中打印_利用python打印杨辉三角
  12. MySql 查询比其中某一位讲师工资少的教师姓名、工资和职称
  13. java用户登录注册
  14. 视频资源网站采集-视频资源API采集教程
  15. 图解LeetCode——854. 相似度为 K 的字符串(难度:困难)
  16. Python 数据分析之双色球高频数据统计
  17. TOJ 5238: C实验:变量交换函数
  18. 使用WinCE CAB Manager制作CAB安装文件
  19. 最优传输论文(十二):Extracting Relationships by Multi-Domain Matching论文原理
  20. esp8266网络自动对时 串口字符连接 病显示 12864i2c u8g2库

热门文章

  1. python初学代码留个纪念
  2. 安装python的第一个曲折
  3. android universal-image-loader的使用
  4. 软件项目风险管理介绍
  5. 央行“意外“降息 专家称贷款买房者首先受益
  6. C#操作数据库,DataSet,DataGridView,更新数据库 [一] - ADO.NET入门之中
  7. Cookies揭秘 [Asp.Net, Javascript]
  8. SecureCRT退出全屏的方法
  9. 03 | SRE切入点:选择SLI,设定SLO
  10. mysql 创建用户权限_10.创建 MySQL 用户及赋予用户权限