数据的处理
2015-08-07 12:41
148 查看
理解Linux输入和输出
Linux中将每个对象都看作文件来处理,包括输入和输出过程,其用文件描述符来标识每个文件对象。文件描述符是一个非负整数,每个过程中一次最多可以有9个文件描述符。bash shell保留了3个文件描述符如下:文件描述符 | 缩 写 | 描 述 |
0 | STDIN | 标准输入 |
1 | STDOUT | 标准输出 |
2 | STDERR | 标准错误 |
STDIN的默认设备是键盘,STDOUT和STDERR的默认设备是显示器。重定向输出时,有3种情况:
1 仅重定向错误或输出,此时将文件描述符紧挨着放到重定向符号前边,中间不能有空格:
2 重定向错误和输出到不同的文件中,此时使用两个重定向符号:
3 重定向错误和输出到同一文件中,使用特殊的重定向符号:
对脚本中的数据进行重定向
1 临时重定向输出
想在脚本中重定向自定义的错误消息到STDERR中,如下操作: echo “This is an error message” >&2 在运行包含该行语句的脚本时,消息输出到STDERR指向的任何位置中。
2 永久重定向输出
如果脚本中包含大量需要重定向的输出信息,可以使用exec命令告诉shell在执行脚本期间将某个文件描述符重定向到固定的位置:#! /bin/bash # redirecting output to different locations exec 2> testerror exec 1> testop echo "This section should go to the testop file" echo "but this should go to the testerror file" >&2
3 重定向输入
exec 0< inputfile4 自定义的重定向
shell中的9个文件描述符之前介绍了3个,其余6个当作输入或者输出均可。重定向为输出文件描述符:
exec 3> outfile echo "This should display on the monitor" echo "This should be stored in the outfile" >&3
但是如何从已重定向的文件描述符中进行恢复呢?其实很简单,只需要重定向回STDOUT中即可:
exec 3>&1 echo "This should display on the monitor" echo "This should be stored in the outfile" >&3
重定向为输入文件描述符:
exec 6<&0 exec 0<output.txt count=1 while read line do echo "Line $count: $line" count=$[ $count + 1 ] done exec 0<&6 read -p "Are you done now? " answer case $answer in Y | y) echo "Goodbye";; N | n) echo "Sorry. This is the end";; esac
重定向为输入输出文件描述符:
将一个文件描述符同时重定向为具有输入和输出功能时,由于shell维护一个内部指针,指向当前文件中的位置,任何读写操作都是从上次保存的文件指针处开始的,此时必须小心处理,否则会产生覆盖现象,如下所示:
exec 3<> output.txt read line <&3 echo "Read: $line" echo "This is a test line" >&3
说明:
read命令读取第一行数据后,文件指针移动到第二行开始,因此执行写操作时会覆盖文件output.txt中的第二行数据。
关闭文件描述符:
如果自定义了新的输入或者输出文件描述符,shell会在脚本退出时自动关闭它们。但是如果想在脚本结束之前手动关闭文件描述符,需要将其重定向到特殊符号&-,如下所示: exec 3>&-,该语句关闭文件描述符3,从而阻止在脚本中再次使用它。如果不小心再次使用了该文件描述符,那么会得到bad file descriptor错误提示。
列出打开的文件描述符
9个文件描述符中,很难记住哪个文件描述符被重定向到哪,bash shell提供了lsof命令。lsof命令列出了整个Linux系统中打开的所有文件描述符。由于该命令向非系统管理员提供了Linux相关的信息,因此,很多Linux系统隐藏了该功能,在centos中,通过which lsof,可以得到其被存放在/usr/sbin/lsof中,以全路径运行该命令,会产生大量的输出。可以使用-p指定具体的PID,也可以使用-d来指定具体的文件描述符,-a选项对任何两个选项执行布尔AND运算。要想知道当前进程的PID,可以使用环境变量"$$"。lsof命令结果描述:
COMMAND | 正在运行的命令名的前9个字符 |
PID | 进程ID |
USER | 进程属主的登录名 |
FD | 文件描述符[r表示可读,w表示可写,u表示可读写] |
TYPE | 文件类型[CHR表示字符型,BLK表示块型,DIR表示目录,REG表示常规文件] |
DEVICE | 设备号[主设备号和从设备号] |
SIZE | 文件大小 |
NODE | 本地文件节点数 |
NAME | 文件名 |
阻止命令输出
可以将STDERR重定义到一个称为null的特殊文件,Linux中,null文件的位置是/dev/null,任何重定向到该位置的文件都会被丢弃而不进行显示。当然,也可以将/dev/null作为输入文件,这样由于/dev/null文件中不包含任何内容,其作用是可以快速删除现有文件中的数据而不用删除文件本身:这是清除日志文件的一个通用方法,既可以清除文件内容,又可以保留文件存在。
创建临时文件
Linux使用/tmp目录来存放临时文件,多数Linux系统在启动时会自动删除/tmp目录中的文件。系统中的任何用户都有权限对/tmp目录进行读和写。mktemp命令用于在当前目录中创建临时文件。默认情况下,使用mktemp命令时只需要指定一个文件名模板就可以了。模板可以包含任意文本,在文件名末尾加上6个X就可以了,如下:
mktemp命令使用6个字符代替6个X,从而确保文件名在本地目录中的唯一性。
如果在使用mktemp命令时加上-t选项,那么该命令会在/tmp目录下创建临时文件,并返回临时文件的全路径名,如下所示:
mktemp加上-d选项表示在当前目录下创建临时目录。
记录消息
如果需要想输出发送到显示器的同时又记录到日志文件中,一种方式是使用两次重定向,另一种方式时使用tee命令。tee命令相当于管道的一个T型接口,其将STDIN接受过来的数据同时发送给两个目的地:一个是STDOUT,另一个是tee指定的文件名:tee filename如果使用tee命令时加上了-a选项,表示在testfile文件中追加数据而不是覆盖,如下所示:
相关文章推荐
- HTML学习笔记(2)——其他标签
- poj 3069 Saruman's Army (贪心)
- windows下python文件与文件夹操作
- OC学习笔记之单例模式
- Tog Cat 打印日志过滤
- underscore template的应用
- Java窗体加载时组件不显示的解决方法
- 认识 Android 中的 Activity 组件 总结
- Ubuntu14.04修改开机动画
- 使用Mysql修改密码命令更改root的密码
- 19.2 Partitioning Types--range 分区
- Android 存储:Internal Storage的用法以及与External storage 的区别
- 判断agent(是电脑还是手机,是Android还是IOS)
- Codeforces 551D GukiZ and Binary Operations(矩阵快速幂)
- 【暑假】[实用数据结构]UVAlive 3027 Corporative Network
- leetcode--Word Ladder II
- Jquery 异步提交表单(post)
- WCF异常信息:由于内部错误,服务器无法处理该请求...
- 【黑马程序员】Java笔记--内部类
- 理解Quartz原理