时间:2017-09-25周一注:本文部分内容摘自《Linux命令行与shell脚本编程大全》一书,版权归原作者所有。《Linux命令行与shell脚本编程大全》(第三版)第15章学习总结第15章:呈现数据重温本章内容重定向标准输入和输出报告错误丢弃错误丢弃数据创建日志文件15.1理解输入和输出在监视器屏幕上显示输出的方法并将输出重定向到文件15.1.1标准文件描述符Linux系统将每个对象视为一个文件,包括输入和输出过程。Linux使用文件描述符(filedescriptor)来标识每一个文件对象文件描述符是一个非负整数,可以唯一标识一个在session中打开的文件。每个进程一次最多可以有九个文件描述符。出于特殊目的,bashshell将前三个文件描述符保留为Linux中的标准。文件描述符文件描述符:缩写:描述0:STDIN:标准输入1:STDOUT:标准输出2:STDERR:标准错误1.STDINSTDIN文件描述符代表shell的标准输入对于终端接口,标准输入是键盘shell从与STDIN文件描述符对应的键盘获取输入,在用户键入时处理每个字符,它使用输入重定向符号(<),读取文件并能够提取数据,将测试文件中的行作为输入写入测试文件使用cat命令这是第一行。这是一条测试线这是第三条线。执行命令cat)来更改ls-l>test2cattest2who>>test2cattest2ls-albadfile>test3cattest3当执行错误命令时,shell不会将错误消息重定向到文件3。STDERRshell通过特殊字符的STDERR文件描述符来处理错误信息STDERR文件描述符表示shell或在shell中运行的程序的标准错误输出脚本失败时产生的错误信息,错误信息将被发送到这个位置。默认情况下,错误消息也会输出到监视器输出。STDERR不会随着STDOUT的重定向而改变15.1.2重定向错误1.只有重定向错误STDERR文件描述符为2,可以选择只重定向错误信息。将文件描述符放在重定向符号之前。该值必须紧接在重定向符号之前,否则不会生效。执行命令ls-albadfile2>test4cattest4也可以结合使用STDOUT和STDERR来执行命令ls-latestbadtesttest22>test5cattest52。重定向错误和数据如果要重定向错误和正常输出,必须使用两个重定向符号,并在符号前加一个权重被定向数据对应的文件描述符,然后指向用于保存数据的输出文件执行命令ls-altesttest2test3badtest2>test61>test7cattest6cattest7使用特殊符号(&>)将STDOUT和STDERR的输出重定向到执行命令ls-altesttest2test3badtest&>test7cattest715.2on同样的输出文件重定向脚本中的输出重定向信息并输出到STDERR写test8.sh脚本#!/bin/bashecho"Thisisanerror">&2echo"Thisisnormaloutput"执行命令./test8.sh。/test8.sh2>test9cattest915.2.2永久重定向使用exec命令告诉shell在脚本执行过程中重定向特定的文件描述符编写test10.sh脚本#!/bin/bashexec1>testoutecho"这是一个测试将所有输出“echo”从脚本重定向到另一个文件“echo”而不必重定向每一行“执行命令。/test10.shcattestout也可以在脚本执行期间重定向STDOUT并编写test11.sh脚本#!/bin/bashexec2>测试terrorecho"这是脚本的开始"echo"现在将所有输出重定向到另一个位置"exec1>testoutecho"Theisout应该转到testout文件"echo"但这应该转到testerror文件">&2执行命令。/test11.shcattestoutcattesterror15.3在脚本中重定向输入命令演示:exec0test13outecho"Thisshoulddisplayonthemonitor"echo"andthisshouldbestoredinthefile">&3echo"然后这应该会回到监视器上"执行命令./test13.shcattest13out命令演示:exec3>>test13out命令描述:使用exec命令将输出附加到现有文件15.4.2重定向文件描述符在脚本输出中临时重定向,然后恢复默认输出设置写入test14.sh脚本#!/bin/bashexec3>&1exec1>test14outecho"T他应该存储在输出文件中“echo”连同whis行“exec1>&3echo”现在应该恢复正常“执行命令./test14.shcattest14out15.4.3创建输入文件描述符可以将STDIN文件描述符保存到另一个文件描述符,然后读取文件后将STDIN恢复到原来的位置Writetest15.shscript#!/bin/bashexec6<&0exec0testfilereadline<&3echo"Read:$line"echo"Thisisatestline">&3执行命令cattestfile./test16.shcattestfile15.4.5关闭文件描述符命令格式:exec3>&-命令说明:在脚本结束前手动关闭文件描述符,重定向到特殊符号&-关闭文件描述符时,如果脚本后面有if在中打开相同的输出文件,现有文件将被覆盖。编写test17.sh脚本#!/bin/bashexec3>test17fileecho"Thisisatestlineofdata">&3exec3>&-cattest17fileexec3>test17fileecho"This'llbebad">&3执行命令./test17.shcattest17file15.5列出打开的文件描述符使用lsof命令显示打开的文件描述符writetest18.shscript#!/bin/bashexec3>test18file1exec6>test18file2exec7testfile命令描述:清除testfile文件中的数据15.7创建临时文件15.7.1创建本地临时文件命令演示:mktemptesting.XXXXXX命令说明:mktemp命令创建一个临时文件,会自动将6个X替换为6个字符编码,以保证文件名在目录中唯一且多个文件可以创建临时文件,每个文件都是唯一的。写test19.sh脚本#!/bin/bashtempfile=$(mktemptest19.XXXXXX)exec3>$tempfileecho"这个脚本写入临时文件$tempfile"echo"这是第一行">&3echo"这是第二行">&3echo"Thisisthelastline">&3exec3>&-echo"Donecreatingtempfile.Thecontentsare:"cat$tempfilerm-f$tempfile2>/dev/null执行命令./test19.shls-altest19*15.7.2在/tmp目录中创建一个临时文件使用-t选项强制mktemp命令在系统的临时目录中创建该文件。mktemp命令将返回临时文件的完整路径。编写test20.sh脚本#!/bin/bashtempfile=$(mktemp-ttmp.XXXXXX)echo"Thisisatestfile.">$tempfileecho"这是测试的第二行。">>$tempfileecho"Thetempfileislocatedat:$tempfile"cat$tempfilerm-f$tempfile15.7.3创建一个临时目录使用-d选项告诉mktemp命令创建一个临时目录编写test21.sh脚本#!/bin/bashtempdir=$(mktemp-ddir.XXXXXX)cd$tempdirtempfile1=$(mktemptemp.XXXXXX)tempfile2=$(mktemptemp.XXXXXX)exec7>$tempfile1exec8>$tempfile2echo"发送数据到目录$tempdir"echo"这是一个测试行datafor$tempfile1">&7echo"Thisisatestlineofdatafor$tempfile2">&8执行命令./test21.shls-alls-aldir.zKQTCL/catdir.zKQTCL/temp.EZBifQcatdir.zKQTCL/temp。sO4oa415.8记录消息,同时将输出发送到监视器和日志文件使用tee命令,相当于管道的一个丁字接头,将数据从STDIN同时发送到两个地方,一个一个是STDOUT,另一个是tee命令指定的文件名:teefilename使用-a选项给文件追加数据,数据会显示在屏幕上,然后永久保存在文件中。写test22。shscript#!/bin/bashtempfile=test22fileecho"这是测试的开始"|tee$tempfileecho"这是测试的第二行"|tee-a$tempfileecho"这是测试的结束"|tee-a$tempfile执行命令./test22.shcattest22file15.9实例说明:文件重定向常见于脚本需要读入和输出文件时通过读取.csv格式的数据文件并输出SQLINSERT语句将数据插入数据库写入members.csv文本Blum,Richard,123Mainst.,Chicago,IL,60601Blum,Barbara,123Mainst.,Chicago,IL,60601Bresnahan,Christine,456OakAve.,Columbus,OH,43201Bresnahan,Timothy,456OakAve.,Columbus,OH,43201写test23.sh脚本#!/bin/bashoutfile='members.sql'IFS=','whilereadlnamefnameaddresscitystatezipin${1}docat>>$outfile<