IO Redirect 与 Pipe

  对于任何一个进程,在启动时,都会打开三个流:stdin(标准输入), stdout(标准输出), stderr(标准错误输出)。Stdout,stderr是process与Display之间,stdin是process与keyboard之间。也就是说系统的标准输入输出,是进程与设备间交流的桥梁。linux

  可是在不少状况下,咱们的程序数据并不来自于标准输入,咱们在使用标准输出时,也不但愿写到显示器上,多是文件,网络,打印机等。这时候就须要IO Redirect来做用了。还有,为了方便使用等,咱们但愿将写到Stdout的数据做为另一个进程的输入,其实这也是IO redirect的一种,不过它有个特殊的名字——pipe。网络

 

         

 

一、IO Redirect

1.1 File handle (File Description)

       操做系统内核会为每个进程分配不少file handler(也叫 File Description),其中初始时会分配3个handle,用数字0,1,2来表示,分别分配给了stdin, stdout, stderr。其余的则是随着须要分配的。app

       这样一来,就能够直接使用0,1,2来表示Stdio了。操作系统

 

在linux上使用lsof -p pid查看一个进程打开了哪些文件。下面是一个查看运行中的top命令的状况:code

 

 

 

1.2 基本的重定向操做符:>与<

  < 将标准输入(stdin, 0)重定向,也就是说数据来源不是键盘,而是其余,例如文件等。blog

  > 将标准输出(stdout, 1)重定向,也就是说数据再也不写到显示器,而是其余地方。进程

  其中在 >,< 操做符的左边,只能是FD,右边多是file,也能够是FD等。此外, <等价于 <1, >等价于1>,因此2> 就是将标准错误输出(stderr, 2)重定向。ip

 

  IO redirect的本质是什么呢?在我看来本质是FD的赋值。怎么理解呢?pip

  默认状况下一个,一个进程(例如:ls)是这样的:io

 

对于一个进程而言:
#0 = keyboard
#1 = display
#2 = display

 

1.2.1 操做符右边是文件

ls >a:表明了 fd1=a
#0 = keyboard
#1 = a
#2 = display

Ls 3>a :表明了fd3=a

sort<file.txt :表明了fd0=file.txt

 

1.2.2 操做符右边是FD

若是但愿在多个FD之间进行赋值运算,那么就用>&或者<&。

那么理解上仍是 >时赋值运算符,&则是dup2系统调用了。

2>&1的意思就是 对 FD1执行dup2,获得FD1的拷贝,而后赋值给FD2,也就是说FD1指向了谁,FD2也去指向谁。

 

例如:

3>file.txt 2>&3 表明了:FD3-->file.txt,那么FD2--->file.txt

须要注意的是:>自己不要求文件必须是存在的,可是通过了上述复制并赋值操做和后,启动进程之初就要准备好相应的流,此时就须要文件file.txt必须是存在的。

 

 

1.3 变体操做符 >>

 

若是将stdout或者stderr 重定向到一个文件,但文件里已经有内容,会是什么结果呢?使用 > file时,文件中已有的内容会被truncate掉,也就是文件内容被清除了。

若是想要保留文件内容怎么办呢?

有一个变体操做符:>> 以append的方式重定向。

 

 

二、Pipe

       若是但愿将输出内容,直接做为另一个程序的输入,这种技术成为Pipe,可以进行Pipe的进程,必须是父子进程。用“|” 来表示管道。Pipe也是进程间通讯的一种技术。

例如:lsof -p pid | grep xxx ,父进程是 lsof, 子进程是grep。

 

本篇内容适用于 Windows,Linux,Unix等操做系统。

相关文章
相关标签/搜索