Chinaunix首页 | 论坛 | 博客
  • 博客访问: 106444
  • 博文数量: 40
  • 博客积分: 1650
  • 博客等级: 上尉
  • 技术积分: 420
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-20 13:05
文章分类
文章存档

2011年(1)

2009年(1)

2008年(1)

2007年(37)

我的朋友

分类: LINUX

2007-07-24 09:13:27

I/O重定向

1、 基本概念(这是理解后面的知识的前提,请务必理解)

a、 I/O重定向通常与 FD有关,常用FD有3个,为0(stdin,标准输入)、1(stdout,标准输出)、2(stderr,标准错误输出);
b、 用 < 来改变读进的数据信道(stdin),使之从指定的档案读进;
c、 用 > 来改变送出的数据信道(stdout, stderr),使之输出到指定的档案;
d、 0 是 < 的默认值,因此 < 与 0<是一样的;同理,> 与 1> 是一样的;
e、 在IO重定向中,stdout 与 stderr 的管道会先准备好,才会从 stdin 读进资料;
f、 管道“|”(pipe line):上一个命令的 stdout 接到下一个命令的 stdin;
g、 exec 命令:常用来替代当前 shell 并重新启动一个 shell,换句话说,并没有启动子 shell。使用这一命令时任何现有环境都将会被清除。exec 在对文件描述符进行操作的时候,也只有在这时,exec 不会覆盖你当前的 shell 环境。

2、 基本I/O重定向

cmd > file 把 stdout 重定向到 file 文件中;
cmd >> file 把 stdout 重定向到 file 文件中(追加);
cmd 1> fiel 把 stdout 重定向到 file 文件中;
cmd > file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中;
cmd 2> file 把 stderr 重定向到 file 文件中;
cmd 2>> file 把 stderr 重定向到 file 文件中(追加);
cmd >> file 2>&1 把 stderr 和 stderr 一起重定向到 file 文件中(追加);
cmd < file >file2 cmd命令以 file 文件作为 stdin,以 file2 文件作为 stdout;
cat <>file 以读写的方式打开 file;
cmd < file cmd命令以 file 文件作为 stdin;

3、 进阶I/O重定向

>&n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出;
<&n 标准输入复制自文件描述符 n;
<&- 关闭标准输入(键盘);
>&- 关闭标准输出;
n<&- 表示将 n 号输入关闭;
n>&- 表示将 n 号输出关闭;
    上述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的 0 或 1。如:
command 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。
command 2>&1 运行一个命令并把它的标准输出和输出合并。(严格的说是通过复制文件描述符 1 来建立文件描述符 2 ,但效果通常是合并了两个流。)

4、 I/O重定向分析
    当执行“echo helloworld > example”时,输出将会被重定向到磁盘文件example中。这是怎么被执行的呢? 我们假定在此之前该shell进程只有三个标准文件打开,文件号分别为0、1、2,以上命令行将按如下序列执行:
    (1) 打开或创建磁盘文件example,如果example中原来有内容,则清除原来内容,其文件号为3。
    (2) 通过dup()复制文件stdout,即将文件号1出的file结构指针复制到文件号4处,目的是将stdout的file指针暂时保存一下
    (3) 关闭stdout,即1号文件,但是由于4号文件对stdout也同时有个引用,所以stdout文件并未真正关闭,只是腾出1号文件号位置。
    (4) 通过dup(),复制3号文件(即磁盘文件example),由于1号文件关闭,其位置空缺,故3号文件被复制到1号,即进程中原来指向stdout的指针指向了example。
    (5) 通过系统调用fork()和exec()创建子进程并执行echo,子进程在执行echo前已关闭3号和4号文件,只留下0、1、2三个文件,这时的1号文件已经不是stdout而是磁盘文件example了。当echo向stdout文件写入“helloworld”时就写入到了example中。
    (6) 回到shell后,再用dup()将1号恢复至stdout,这样shell就恢复了0、1、2三个标准输入/输出文件。

    可见,当echo程序(或其他)在运行的时候并不知道stdout(对于stdin和stderr同样)指向什么,进程与实际输出文件或设备的结合是在运行时由其父进程完成的,从而简化了子进程的设计。
阅读(721) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~