shell读书笔记9
19、呈现数据
理解输入和输出
至此你已经知道了两种显示脚本输出的方法:
在显示器屏幕上显示输出
将输出重定向到文件中
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 $
在脚本中重定向输出
有两种方法来在脚本中重定向输出:
临时重定向行输出
永久重定向脚本中的所有命令
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文件。
在脚本中重定向输入
你可以使用与脚本中重定向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. $
实例
文件重定向常见于脚本需要读入文件和输出文件时。这个样例脚本两件事都做了。它读取.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相关推荐
- shell读书笔记8
18.处理用户输入 18.1.命令行参数 18.1.1.读取参数 位置参数变量是标准的数字:$0是程序名,$1是第一个参数,$2是第二个参数,依次类推,直到第九个参数$9 I.下面是在shell脚本中 ...
- 老男孩shell实战读书笔记 (6-10章节)
老男孩shell教程 (6-10章节) shell脚本的条件测试与比较 在bash编程中,条件测试常用的语法形式如下表: 说明⚠️: 语法1中的test命令和语法2中的[]是等价的. 语法3中的[[] ...
- Linux Shell脚本攻略 读书笔记
内容目录: 嗨,Echo一下 给终端来点颜色 shell的控制结构 算术比较 目录操作 网站下载 tar 归档工具 rsync 备份系统快照 ftp自动传输 磁盘管理 故障排查 使用syslog记录日 ...
- 学习Unix,可从事什么样的工作(1)《精通Unix下C语言与项目实践》读书笔记(3)...
<精通Unix下C语言编程与项目实践>读书笔记(new) 文章试读 不拘一个遍程序系列:编程序不能一个脑袋钻到底,有时要学会变通,即所谓的曲线救国.一.二.三.四 职场规划:一些杂七杂八的 ...
- APUE读书笔记 之 进程关系
这一章的内容在读第一遍的时候完全是在"看",当时还以为"看"的挺明白. 现在读第二遍,并准备写这篇读书笔记时,才发现,我第一遍读的时候,什么都没"看& ...
- 程序的加载和执行(五)——《x86汇编语言:从实模式到保护模式》读书笔记25
程序的加载和执行(五)--<x86汇编语言:从实模式到保护模式>读书笔记25 前面几篇博文终于把代码分析完了.这篇就来说说代码的编译.运行和调试. 1.代码的编译及写入镜像文件 之前我们都 ...
- 深入理解计算机系统学后感,深入理解计算机系统(读书笔记)
第一章计算机系统漫游 计算机系统是由硬件和系统软件组成的,它们共同工作l来运行应用程序. 通过hello程序来了解,运行的时候程序会发生什么. #include int main() { printf ...
- 《Linux内核设计与实现》读书笔记(十七)- 设备与模块
本章主要讨论与linux的设备驱动和设备管理的相关的4个内核成分,设备类型,模块,内核对象,sysfs. 主要内容: 设备类型 内核模块 内核对象 sysfs 总结 1. 设备类型 linux中主要由 ...
- 《Linux内核设计与实现》读书笔记(十二)- 内存管理
内核的内存使用不像用户空间那样随意,内核的内存出现错误时也只有靠自己来解决(用户空间的内存错误可以抛给内核来解决). 所有内核的内存管理必须要简洁而且高效. 主要内容: 内存的管理单元 获取内存的方法 ...
最新文章
- JS中NaN、NULL、undefined、详解
- RabbitMQ教程C#版 - 工作队列
- 设计模式--行为型模式
- 为Python终端提供持久性历史记录
- LoadRunner 使用虚拟IP测试流程
- 全新APP软件游戏应用网站源码+支持WAP/Pbootcms内核
- 百战程序员-人工智能从入门到开发教程(60万下载量)
- ip地址聚合后可用地址数 计算机网络技术三级考试 备考
- 【新手必看】C语言开发环境,请查收!
- 易语言.用修改注册表的方式来关闭win10自带的杀毒软件
- P236 练习1 声明另一个类的变量当属性
- python基础知识学习
- k8s rbac 权限管理控制创建过程+理论知识
- CCF模拟题-1~5
- POI 复制 word 表中的行操作 以及样式
- 过滤器和拦截器(SpringMVC实现)
- regsvr32 注册.dll的用法
- 子域名收集 -- Maltego CE
- Windos10双系统之Ubuntu
- 红米note8pro手机电路图