19、呈现数据

  1. 理解输入和输出
    至此你已经知道了两种显示脚本输出的方法:
     在显示器屏幕上显示输出
     将输出重定向到文件中
    1.1、标准文件描述符
    Linux用文件描述符(filedescriptor)来标识每个文件对象。文件描述符是一个非负整数,可以唯一标识会话中打开的文件。每个进程一次最多可以有九个文件描述符。出于特殊目的,bash shell保留了前三个文件描述符(0、1和2)

    1.2、重定向错误
    有几种办法实现方法:
    I、只重定向错误
    STDERR文件描述符被设成2。可以选择只重定向错误消息,将该文件描述符值放在重定向符号前。该值必须紧紧地放在重定向符号前,否则不会工作

    $ ls -al badfile 2> test4
    $ cat test4
    ls: cannot access badfile: No such file or directory
    $
    

    用这种方法,shell会只重定向错误消息,而非普通数据。这里是另一个将STDOUT和STDERR消息混杂在同一输出中的例子。

    $ ls -al test badtest test2 2> test5
    -rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2
    $ cat test5
    ls: cannot access test: No such file or directory
    ls: cannot access badtest: No such file or directory
    $
    

    ls命令的正常STDOUT输出仍然会发送到默认的STDOUT文件描述符,也就是显示器。由于该命令将文件描述符2的输出(STDERR)重定向到了一个输出文件,shell会将生成的所有错误消息直接发送到指定的重定向文件中。

    II、重定向错误和数据
    如果想重定向错误和正常输出,必须用两个重定向符号。需要在符号前面放上待重定向数据所对应的文件描述符,然后指向用于保存数据的输出文件。

    $ ls -al test test2 test3 badtest 2> test6 1> test7
    $ cat test6
    ls: cannot access test: No such file or directory
    ls: cannot access badtest: No such file or directory
    $ cat test7
    -rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2
    -rw-rw-r-- 1 rich rich 0 2014-10-16 11:33 test3
    $
    

    shell利用1>符号将ls命令的正常输出重定向到了test7文件,而这些输出本该是进入STDOUT的。所有本该输出到STDERR的错误消息通过2>符号被重定向到了test6文件。

    另外,如果愿意,也可以将STDERR和STDOUT的输出重定向到同一个输出文件。为此bash shell提供了特殊的重定向符号&>。

    $ ls -al test test2 test3 badtest &> test7
    $ cat test7
    ls: cannot access test: No such file or directory
    ls: cannot access badtest: No such file or directory
    -rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2
    -rw-rw-r-- 1 rich rich 0 2014-10-16 11:33 test3
    $
    
  2. 在脚本中重定向输出
    有两种方法来在脚本中重定向输出:
     临时重定向行输出
     永久重定向脚本中的所有命令
    I、临时重定向
    如果有意在脚本中生成错误消息,可以将单独的一行输出重定向到STDERR。你所需要做的是使用输出重定向符来将输出信息重定向到STDERR文件描述符。在重定向到文件描述符时,你必须在文件描述符数字之前加一个&:

    echo "This is an error message" >&2
    

    这行会在脚本的STDERR文件描述符所指向的位置显示文本,而不是通常的STDOUT。下面这个例子就利用了这项功能。

    $ cat test8
    #!/bin/bash
    # testing STDERR messages
    echo "This is an error" >&2
    echo "This is normal output"
    $
    如果像平常一样运行这个脚本,你可能看不出什么区别。
    $ ./test8
    This is an error
    This is normal output
    $
    

    记住,默认情况下,Linux会将STDERR导向STDOUT。但是,如果你在运行脚本时重定向了STDERR,脚本中所有导向STDERR的文本都会被重定向。

    $ ./test8 2> test9
    This is normal output
    $ cat test9
    This is an error
    $
    

    太好了!通过STDOUT显示的文本显示在了屏幕上,而发送给STDERR的echo语句的文本则被重定向到了输出文件
    II、永久重定向
    如果脚本中有大量数据需要重定向,那重定向每个echo语句就会很烦琐。取而代之,你可以用exec命令告诉shell在脚本执行期间重定向某个特定文件描述符。

    $ cat test10
    #!/bin/bash
    # redirecting all output to a file
    exec 1>testout
    echo "This is a test of redirecting all output"
    echo "from a script to another file."
    echo "without having to redirect every individual line"
    $ ./test10
    $ cat testout
    This is a test of redirecting all output
    from a script to another file.
    without having to redirect every individual line
    $
    

    exec命令会启动一个新shell并将STDOUT文件描述符重定向到文件。脚本中发给STDOUT的所有输出会被重定向到文件。
    可以在脚本执行过程中重定向STDOUT。

    $ cat test11
    #!/bin/bash
    # redirecting output to different locations
    exec 2>testerror
    echo "This is the start of the script"
    echo "now redirecting all output to another location"
    exec 1>testout
    echo "This output should go to the testout file"
    echo "but this should go to the testerror file" >&2
    $
    $ ./test11
    This is the start of the script
    now redirecting all output to another location
    $ cat testout
    This output should go to the testout file
    $ cat testerror
    but this should go to the testerror file
    $
    

    这个脚本用exec命令来将发给STDERR的输出重定向到文件testerror。接下来,脚本用echo语句向STDOUT显示了几行文本。随后再次使用exec命令来将STDOUT重定向到testout文件。注意,尽管STDOUT被重定向了,但你仍然可以将echo语句的输出发给STDERR,在本例中还是重定向到testerror文件。

  3. 在脚本中重定向输入
    你可以使用与脚本中重定向STDOUT和STDERR相同的方法来将STDIN从键盘重定向到其他位置。exec命令允许你将STDIN重定向到Linux系统上的文件中:

    exec 0< testfile
    

    这个命令会告诉shell它应该从文件testfile中获得输入,而不是STDIN。这个重定向只要在脚本需要输入时就会作用。下面是该用法的实例。

    $ cat test12
    #!/bin/bash
    # redirecting file input
    exec 0< testfile
    count=1
    while read line
    do
    echo "Line #$count: $line"
    count=$[ $count + 1 ]
    done
    $ ./test12
    Line #1: This is the first line.
    Line #2: This is the second line.
    Line #3: This is the third line.
    $
    
  4. 实例
    文件重定向常见于脚本需要读入文件和输出文件时。这个样例脚本两件事都做了。它读取.csv格式的数据文件,输出SQL INSERT语句来将数据插入数据库。shell脚本使用命令行参数指定待读取的.csv文件。.csv格式用于从电子表格中导出数据,所以你可以把数据库数据放入电子表格中,把电子表格保存成.csv格式,读取文件,然后创建INSERT语句将数据插入MySQL数据库。
    脚本内容如下。

    $cat test23
    #!/bin/bash
    # read file and create INSERT statements for MySQL
    outfile='members.sql'
    IFS=','
    while read lname fname address city state zip
    do
    cat >> $outfile << EOF
    INSERT INTO members (lname,fname,address,city,state,zip) VALUES
    ('$lname', '$fname', '$address', '$city', '$state', '$zip');
    EOF
    done < ${1}
    $
    

    这个脚本很短小,这都要感谢有了文件重定向!脚本中出现了三处重定向操作。while循环使用read语句(参见第14章)从数据文件中读取文本。注意在done语句中出现的重定向符号:

    done < ${1}
    

    当运行程序test23时,$1代表第一个命令行参数。它指明了待读取数据的文件。read语句会使用IFS字符解析读入的文本,我们在这里将IFS指定为逗号。
    脚本中另外两处重定向操作出现在同一条语句中:

    cat >> $outfile << EOF
    

    这条语句中包含一个输出追加重定向(双大于号)和一个输入追加重定向(双小于号)。输出重定向将cat命令的输出追加到由$outfile变量指定的文件中。cat命令的输入不再取自标准输入,而是被重定向到脚本中存储的数据。EOF符号标记了追加到文件中的数据的起止。

    INSERT INTO members (lname,fname,address,city,state,zip) VALUES
    ('$lname', '$fname', '$address', '$city', '$state', '$zip');
    

    上面的文本生成了一个标准的SQL INSERT语句。注意,其中的数据会由变量来替换,变量中内容则是由read语句存入的。
    所以基本上while循环一次读取一行数据,将这些值放入INSERT语句模板中,然后将结果输出到输出文件中。
    在这个例子中,使用以下输入数据文件。

    $ cat members.csv
    Blum,Richard,123 Main St.,Chicago,IL,60601
    Blum,Barbara,123 Main St.,Chicago,IL,60601
    Bresnahan,Christine,456 Oak Ave.,Columbus,OH,43201
    Bresnahan,Timothy,456 Oak Ave.,Columbus,OH,43201
    $
    

    运行脚本时,显示器上不会出现任何输出:

    $ ./test23 < members.csv
    $
    

    但是在members.sql输出文件中,你会看到如下输出内容。

    $ cat members.sql
    INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Blum',
    'Richard', '123 Main St.', 'Chicago', 'IL', '60601');
    INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Blum',
    'Barbara', '123 Main St.', 'Chicago', 'IL', '60601');
    INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Bresnahan',
    'Christine', '456 Oak Ave.', 'Columbus', 'OH', '43201');
    INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Bresnahan',
    'Timothy', '456 Oak Ave.', 'Columbus', 'OH', '43201');
    $
    

    结果和我们预想的一样!现在可以将members.sql文件导入MySQL数据表中了

shell读书笔记9相关推荐

  1. shell读书笔记8

    18.处理用户输入 18.1.命令行参数 18.1.1.读取参数 位置参数变量是标准的数字:$0是程序名,$1是第一个参数,$2是第二个参数,依次类推,直到第九个参数$9 I.下面是在shell脚本中 ...

  2. 老男孩shell实战读书笔记 (6-10章节)

    老男孩shell教程 (6-10章节) shell脚本的条件测试与比较 在bash编程中,条件测试常用的语法形式如下表: 说明⚠️: 语法1中的test命令和语法2中的[]是等价的. 语法3中的[[] ...

  3. Linux Shell脚本攻略 读书笔记

    内容目录: 嗨,Echo一下 给终端来点颜色 shell的控制结构 算术比较 目录操作 网站下载 tar 归档工具 rsync 备份系统快照 ftp自动传输 磁盘管理 故障排查 使用syslog记录日 ...

  4. 学习Unix,可从事什么样的工作(1)《精通Unix下C语言与项目实践》读书笔记(3)...

    <精通Unix下C语言编程与项目实践>读书笔记(new) 文章试读 不拘一个遍程序系列:编程序不能一个脑袋钻到底,有时要学会变通,即所谓的曲线救国.一.二.三.四 职场规划:一些杂七杂八的 ...

  5. APUE读书笔记 之 进程关系

    这一章的内容在读第一遍的时候完全是在"看",当时还以为"看"的挺明白. 现在读第二遍,并准备写这篇读书笔记时,才发现,我第一遍读的时候,什么都没"看& ...

  6. 程序的加载和执行(五)——《x86汇编语言:从实模式到保护模式》读书笔记25

    程序的加载和执行(五)--<x86汇编语言:从实模式到保护模式>读书笔记25 前面几篇博文终于把代码分析完了.这篇就来说说代码的编译.运行和调试. 1.代码的编译及写入镜像文件 之前我们都 ...

  7. 深入理解计算机系统学后感,深入理解计算机系统(读书笔记)

    第一章计算机系统漫游 计算机系统是由硬件和系统软件组成的,它们共同工作l来运行应用程序. 通过hello程序来了解,运行的时候程序会发生什么. #include int main() { printf ...

  8. 《Linux内核设计与实现》读书笔记(十七)- 设备与模块

    本章主要讨论与linux的设备驱动和设备管理的相关的4个内核成分,设备类型,模块,内核对象,sysfs. 主要内容: 设备类型 内核模块 内核对象 sysfs 总结 1. 设备类型 linux中主要由 ...

  9. 《Linux内核设计与实现》读书笔记(十二)- 内存管理

    内核的内存使用不像用户空间那样随意,内核的内存出现错误时也只有靠自己来解决(用户空间的内存错误可以抛给内核来解决). 所有内核的内存管理必须要简洁而且高效. 主要内容: 内存的管理单元 获取内存的方法 ...

最新文章

  1. JS中NaN、NULL、undefined、详解
  2. RabbitMQ教程C#版 - 工作队列
  3. 设计模式--行为型模式
  4. 为Python终端提供持久性历史记录
  5. LoadRunner 使用虚拟IP测试流程
  6. 全新APP软件游戏应用网站源码+支持WAP/Pbootcms内核
  7. 百战程序员-人工智能从入门到开发教程(60万下载量)
  8. ip地址聚合后可用地址数 计算机网络技术三级考试 备考
  9. 【新手必看】C语言开发环境,请查收!
  10. 易语言.用修改注册表的方式来关闭win10自带的杀毒软件
  11. P236 练习1 声明另一个类的变量当属性
  12. python基础知识学习
  13. k8s rbac 权限管理控制创建过程+理论知识
  14. CCF模拟题-1~5
  15. POI 复制 word 表中的行操作 以及样式
  16. 过滤器和拦截器(SpringMVC实现)
  17. regsvr32 注册.dll的用法
  18. 子域名收集 -- Maltego CE
  19. Windos10双系统之Ubuntu
  20. 红米note8pro手机电路图

热门文章

  1. HTML5适合的情人节礼物,学生送什么情人节礼物?适合学生的情人节礼物有哪些?...
  2. Linux中文件传输方式
  3. 好用的CAD看图软件功能详解分析
  4. 新的算法提高了早期量子计算机的计算能力;Q-CTRL以黑色星期五的价格提供量子知识 | 全球量子科技与工业快讯第四十四期
  5. 小学计算机管理员竞选,小学生图书管理员竞选演讲稿范文(通用5篇)
  6. 朋友牛仔的72时间线
  7. 电话号码标记查询服务搭建
  8. 高通SDM845平台Sensor学习——2.Hal层
  9. 三脚水位开关怎么接线
  10. JAVA学习生涯开始