一、引言

前几天使用一个linux下的内存检测工具valgrind,想要把检测的结果重定向到文件,结果总是没有任何内容,最后才发现是重定向的原因,它输出的信息是输出到stderr的,所以我使用 > file 这个命令显然是无法达到目的的。

二、学习

于是决定好好回顾一下IO重定向的知识,找到了下面这篇文章。

IO Redirection

UNIX had the concept of IO redirection long before DOS copied and bastardised the concept. The UNIX IO redirection concept is fundamental to many of the things that you can do with UNIX, and it is quite a well-developed idea, so we will explore this concept here.

Why do I mention UNIX at all? Well, Linux is a UNIX operating system!

Under UNIX, all programs that run are given three open files when they are started by a shell:

0.

Standard in, or STDIN.

This is where input comes from, and it normally points at your terminal device.

To find out what device is your terminal, use the tty(1) command. Note, the (1) after command names in UNIX refers to the section of the man pages that the documentation for the command exists in.

You can arrange to run any command and pass it input from a file in the following way:

$ some-command < /path/to/some/file

Note, the '$' is your prompt. Note also, you can always specify a complete path name for a file.

For example:

$ grep -i Fred < /etc/passwd

Would search for the string 'fred' in /etc/passwd, regardless of the case of the characters.

But wait a minute, you object, I always use:

$ grep -i Fred /etc/passwd

This is true, but you can also pass the file in on STDIN, and you will get different results if you do. Can you see what the difference is?

1.

Standard out, or STDOUT.

This is where the normal output from a program goes. It normally points at your terminal as well, but you can redirect it.

You can redirect output in the following way:

$ some-program > /path/to/some/file

For example:

$ grep -i Fred /etc/passwd > /tmp/results
2.

Standard error, or STDERR.

This is where error output from your program goes. This normally points at your terminal as well, but you can redirect it.

Why have different output places for standard out and standard error?

Well, as you will see when you come to writing shell scripts, you often do not want error messages cluttering up the normal output from a program.

You will forgive me for starting the above list at 0, I am sure, when you learn that each of these IO 'channels' are represented by small numbers, called file descripters (FDs), that have exactly those numbers. That is, STDIN is FD 0, while STDOUT is FD 1, and STDERR is FD 2.

When the shell runs a program for you, it opens STDIN as FD 0, STDOUT as FD 1, and STDERR as FD 2, and then runs the program (technically, it almost always does afork(2) and then an exec(3) or one of the exec?? calls). If you have redirected one of STDIN, STDOUT or STDERR, your shell opens that file as the appropriate FD before running the program.

Now, what does this all have to do with you, I hear you ask?

Well, there are lots of neat things you can do, but some things to watch out for as well.

A lot of inexperienced UNIX users assume that they can redirect a file into a program and use the same name for redirecting the output:

$ some-program < mega-important-data-file > mega-important-data-file

They become very upset after doing the above, especially if that mega-important data file has never been backed up anywhere. Why is this?

The shell opens the mega-important-data-file for reading and associates it with FD 0 (or STDIN), and then opens it for writing, but truncates it to zero length, and associates it with FD 1 (or STDOUT) as well.

So, if you want to do something like the above, use a different file name for the output file. Oh, you should also back up files as well :-).

Now, there are lots of redirection symbols that you can use, and here are some of them:

file means open a file for reading and associate with STDIN.
<< token Means use the current input stream as STDIN for the program until token is seen. We will ignore this one until we get to scripting.
file means open a file for writing and truncate it and associate it with STDOUT.
>> file means open a file for writing and seek to the end and associate it with STDOUT. This is how you append to a file using a redirect.
n>&m means redirect FD n to the same places as FD m. Eg, 2>&1 means send STDERR to the same place that STDOUT is going to.

OK, here are some tricks that you might want to use in various places.

If you are gathering evidence for a bug report, you might want to redirect the output from a series of programs to a text file (never mind that you can use the script command to do the same :-). So you might do the following:

$ some-buggy-program > important-evidence.txt
$ echo '---------MARKER-------' >> important-evidence.txt
$ some-buggy-program some-params >> important-evidence.txt

The second and subsequent lines append the output from the commands issues to the evidence file rather than overwriting them. Try the following:

$ echo This is a line of text > /tmp/file.txt
$ echo This is another line > /tmp/file.txt

What do you get?

Now try:

$ echo This is a line of text > /tmp/file.txt
$ echo This is another line >> /tmp/file.txt

What do you get this time?

OK, for the last few tricks here. Sometimes you want to append STDOUT and STDERR to a file. How do you do it?

$ some-command >> /tmp/log.log 2>&1

The 2>&1 says make STDERR point to the same places as STDOUT. Since STDOUT is open already, and the shell has done a seek to the end, STDERR will also be appended to STDOUT.

If you want to append a line to a file, you can echo the line you want with a redirect, rather than firing up an editor:

$ echo Some text >> /path/to/some/file

It turns out that you can cause the shell to redirect to other file descriptors as well, and if you look in the configure scripts that come with many UNIX software packages, you will see examples of this.

Why is redirecting so important? Well, it is used in many shell scripts, it is a simple and conventient mechanism to sending output to any file without the programmer having to add code for handling command line instructions, and it is the UNIX way of doing things :-).

It is also the same as piping, where you redirect output to, or input from, a pipe device. The pipe device has a process living on the other side, but we will look at this later.

Linux之IO Redirection的更多相关文章

  1. Linux硬件IO的优化简介

    Linux硬件IO的优化简介 首先简单介绍下有哪些硬件设备如下(由于硬件种类厂家等各种因素我就不在此多做介绍有兴趣的可以自行学习): 1.CPU:中央处理器,是计算机运算控制的核心部件之一,相当于人的 ...

  2. linux标准io的copy

    ---恢复内容开始--- 1.linux标准io的copy #include<stdio.h> int main(int argc,char **argv) { if(argc<3) ...

  3. MySQL 调优基础(四) Linux 磁盘IO

    1. IO处理过程 磁盘IO经常会成为系统的一个瓶颈,特别是对于运行数据库的系统而言.数据从磁盘读取到内存,在到CPU缓存和寄存器,然后进行处理,最后写回磁盘,中间要经过很多的过程,下图是一个以wri ...

  4. Linux的io机制

    Linux的io机制 Buffered-IO 和Direct-IO Linux磁盘I/O分为Buffered IO和Direct IO,这两者有何区别呢? 对于Buffered IO: 当应用程序尝试 ...

  5. Linux Network IO Model、Socket IO Model - select、poll、epoll

    目录 . 引言 . IO机制简介 . 阻塞式IO模型(blocking IO model) . 非阻塞式IO模型(noblocking IO model) . IO复用式IO模型(IO multipl ...

  6. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

  7. 转:Linux网络IO并行化技术概览

    转:http://codinginet.com/articles/view/201605-linux_net_parallel?simple=1&from=timeline&isapp ...

  8. Linux的IO调度

    Linux的IO调度 IO调度发生在Linux内核的IO调度层.这个层次是针对Linux的整体IO层次体系来说的.从read()或者write()系统调用的角度来说,Linux整体IO体系可以分为七层 ...

  9. Linux系统IO分析工具之iotstat常用参数介绍

    Linux系统IO分析工具之iotstat常用参数介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 1>.安装iostat [root@flume115 ~]# yum - ...

随机推荐

  1. Openshift 3.6 安装

    因为有客户需求,所以必须尝试一下,可悲的是手里只有3.7的离线安装文档,加上之前3.11安装因为同事文档写得太好,基本没遇到什么坑,所以就没仔细研究就开始搞了. 结果果然是因为/etc/ansible ...

  2. 关于TagHelper的那些事情——如何自定义TagHelper(TagHelper基类)

    写在开头 前面介绍了TagHelper的基本概念和内嵌的TagHelpers,想必大家对TagHelper都有一定的了解.TagHelper看上去有点像WebControl,但它不同于WebContr ...

  3. iOS:图片上传时两种图片压缩方式的比较

    上传图片不全面的想法:把图片保存到本地,然后把图片的路径上传到服务器,最后又由服务器把路径返回,这种方式不具有扩展性,如果用户换了手机,那么新手机的沙盒中就没有服务器返回的图片路径了,此时就无法获取之 ...

  4. 贯通Spark Streaming JobScheduler内幕实现和深入思考

    本节主要内容: 一.SparkStreaming Job生成深度思考 二.SparkStreaming Job生成源码解析 JobScheduler的地位非常的重要,所有的关键都在JobSchedul ...

  5. 【Shell】linux中shell变量$#,$@,$0,$1,$2的含义解释 && set 关键字使用

    linux中shell变量$#,$@,$0,$1,$2的含义解释   摘抄自:ABS_GUIDE 下载地址:http://www.tldp.org/LDP/abs/abs-guide.pdf linu ...

  6. Node.js umei图片批量下载Node.js爬虫1.00

    这个爬虫在abaike爬虫的基础上改改图片路径和下一页路径就出来了,代码如下: //====================================================== // ...

  7. 关于web项目中的图片上传、并在前端显示问题(tomcat中配置文件上传虚拟路径)

    一.数据库存储 直接把图片的二进制码存到数据库,可参考blog:http://blog.csdn.net/hope2jiang/article/details/590733 直接存图片在mysql上面 ...

  8. webDriver API——第9部分Firefox WebDriver

    class selenium.webdriver.firefox.webdriver.WebDriver(firefox_profile=None, firefox_binary=None, time ...

  9. HTTP缓存策略 304

    1.图解缓存 示例: 200 (from disk cache): 200 (from memory cache) MemoryCache顾名思义,就是将资源缓存到内存中,等待下次访问时不需要重新下载 ...

  10. sqlserver远程备份到其他服务器

    直接将数据库备份到其他机器上 --如果xp_cmdshell没有启用,请先启用 sp_configure reconfigure go sp_configure reconfigure go --1. ...