Linux重定向详解编辑转载.docx
- 文档编号:5877640
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:7
- 大小:19.50KB
Linux重定向详解编辑转载.docx
《Linux重定向详解编辑转载.docx》由会员分享,可在线阅读,更多相关《Linux重定向详解编辑转载.docx(7页珍藏版)》请在冰点文库上搜索。
Linux重定向详解编辑转载
Linux重定向详解
1、I/O重定向详解及应用实例
1.1基本概念
(这是理解后面的知识的前提,请务必理解)
a、I/O重定向通常与FD有关,shell的FD通常为10个,即0~9;
b、常用FD有3个,为0(stdin,标准输入)、1(stdout,标准输出)、2(stderr,标准错误输出),默认与keyboard、monitor、monitor有关;
c、用<来改变读进的数据信道(stdin),使之从指定的档案读进;
d、用>来改变送出的数据信道(stdout,stderr),使之输出到指定的档案;
e、0是<的默认值,因此<与0<是一样的;同理,>与1>是一样的;
f、在IO重定向中,stdout与stderr的管道会先准备好,才会从stdin读进资料;
g、管道“|”(pipeline):
上一个命令的stdout接到下一个命令的stdin;
h、tee命令是在不影响原本I/O的情况下,将stdout复制一份到档案去;
i、bash(ksh)执行命令的过程:
分析命令-变量求值-命令替代(``和$())-重定向-通配符展开-确定路径-执行命令;
j、()将commandgroup置于sub-shell去执行,也称nestedsub-shell,它有一点非常重要的特性是:
继承父shell的Standardinput,output,anderrorplusanyotheropenfiledescriptors。
k、exec命令:
常用来替代当前shell并重新启动一个shell,换句话说,并没有启动子shell。
使用这一命令时任何现有环境都将会被清除。
exec在对文件描述符进行操作的时候,也只有在这时,exec不会覆盖你当前的shell环境。
2、基本IO
cmd>file把stdout重定向到file文件中;
cmd>>file把stdout重定向到file文件中(追加);
cmd1>fiel把stdout重定向到file文件中;
cmd>file2>&1把stdout和stderr一起重定向到file文件中;
cmd2>file把stderr重定向到file文件中;
cmd2>>file把stderr重定向到file文件中(追加);
cmd>>file2>&1把stderr和stderr一起重定向到file文件中(追加);
cmd
cat<>file以读写的方式打开file;
cmd cmd< 3、进阶IO >&n使用系统调用dup (2)复制文件描述符n并把结果用作标准输出; <&n标准输入复制自文件描述符n; <&-关闭标准输入(键盘); >&-关闭标准输出; n<&-表示将n号输入关闭; n>&-表示将n号输出关闭; 上述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的0或1。 如: ...2>file运行一个命令并把错误输出(文件描述符2)定向到file。 ...2>&1运行一个命令并把它的标准输出和输出合并。 (严格的说是通过复制文件描述符1来建立文件描述符2,但效果通常是合并了两个流。 ) 我们对2>&1详细说明一下: 2>&1也就是FD2=FD1,这里并不是说FD2的值等于FD1的值,因为>是改变送出的数据信道,也就是说把FD2的“数据输出通道”改为FD1的“数据输出通道”。 如果仅仅这样,这个改变好像没有什么作用,因为FD2的默认输出和FD1的默认输出本来都是monitor,一样的! 但是,当FD1是其他文件,甚至是其他FD时,这个就具有特殊的用途了。 请大家务必理解这一点。 exec0exec1>outfilename#打开文件outfilename作为stdout。 exec2>errfilename#打开文件errfilename作为stderr。 exec0<&-#关闭FD0。 exec1>&-#关闭FD1。 exec5>&-#关闭FD5。 问: 如果关闭了FD0、FD1、FD2,其后果是什么? 恢复FD0、FD1、FD2与关闭FD0、FD1、FD2有什么区别? 代码分别是什么? 打开了FD3~FD9,我们用完之后,你觉得是将他们关闭还是恢复? 下面是提示(例子来源于CU一帖子,忘记出处,来日再补上): exec6>&22>ver command>>dev/null& exec2>&6#恢复FD2 4、简单举例 a、stdout和stderr都通过管道送给egrep了: (lsyouno2>&1;lsyes2>&1)2>&1|egrep\*>file (lsyouno2>&1;lsyes2>&1)|egrep\*>file (lsyouno;lsyes)2>&1|egrep\*>file 这个例子要注意的就是: 理解命令执行顺序和管道“|”: 在命令执行前,先要进行重定向的处理,并将把nestedsub-shell的stdout接到egrep命令的stdin。 nestedsub-shell,在()中的两个命令加上(),可以看作一个命令。 其FD1已经连接到“|”往egrep送了,当遇到2>&1时,也就是FD2=FD1,即FD2同FD1一样,往管道“|”那边送。 b、没有任何东西通过管道送给egrep,全部送往monitor。 (lsyouno2>&1;lsyes2>&1)>&2|egrep\*>file。 虽然在()里面将FD2转往FD1,但在()外,遇到>&2,结果所有的都送到monitor。 请理解: (lsyouno2>&1)1>&2|egrep\*>file##送到monitor lsyouno2>&11>&2|egrep\*>file##送给管道“|” lsyouno1>&22>&1|egrep\*>file##送到monitor 5、中阶例子 条件: stderr通过管道送给egrep,正确消息仍然送给monitor(不变) exec4>&1;(lsyouno2>&11>&44>&-;lsyes2>&11> &44>&-)|egrep\*>file;exec4>&- 或者 exec4>&1;(lsyouno;lsyes)2>&11> &44>&-|egrep\*>file;exec4>&- 如果加两个条件: (1)要求cmd1和cmd2并行运行; (2)将cmd1的返回值赋给变量ss。 则为: exec3>&1;exec4>&1 ss=$(((lsyouno2>&11>&33>&-;echo$? >&4)|egrep\*>file)4>&1) exec3>&-;exec4>&- 说明: exec3>&1;4>&1建立FD3,是用来将下面ls那条语句(子shell)中的FD1恢复到正常FD1,即输出到monitor,你可以把FD3看作最初始的FD1的硬盘备份(即输出到monitor);建立FD4,到时用作保存ls的返回值(echo$? ),你可以将FD4看作你考试时用于存放计算“echo$? ”的草稿纸; (lsyouno2>&11>&33>&-;echo$? >&4)大家还记得前面说的子shell和管道吧。 这条命令首先会继承FD0、FD1、FD2、FD3、FD4,它位于管道前,所以在运行命令前会先把子shell自己的FD1和管道“|”相连。 但是我们的条件是stderr通过管道送往egrep,stdout仍然输出到monitor。 于是通过2>&1,先把子shell的FD1的管道“送给”FD2,于是子shell中的stderr送往管道“|”;再通过1>&3,把以前的“硬盘备份”恢复给子shell的FD1,于是子shell中的FD1变成送到monitor了。 再通过3>&-,将3关闭;接着运行echo$? ,本来其输出值应该送往管道的,通过>&4,将输出送往“草稿纸”FD4,留以备用。 ((lsyouno2>&11>&33>&-;echo$? >&4)|egrep\*>file)于是,stderr通过管道送给egrep,stdout送给monitor,但是,还有FD4,它送到哪去了? $(((lsyouno2>&11>&33>&-;echo$? >&4)|egrep\*>file)4>&1)最后的4>&1,就是把FD4重定向到FD1。 但由于其输出在$()中,其值就赋给变量ss了。 最后一行关闭FD3、FD4。 6、高阶例子 命令cmd1,cmd2,cmd3,cmd4.如何利用单向管道完成下列功能: 1.所有命令并行执行。 2.cmd1和cmd2不需要stdin。 3.cmd1和cmd2的stdout定向到cmd3的stdin。 4.cmd1和cmd2的stderr定向到cmd4的stdin。 5.cmd3的stdout定向到文件a,stderr定向到屏幕。 6.cmd4的stdout定向到文件b,stderr定向到屏幕。 7.cmd1的返回码赋给变量s。 8.不能利用临时文件。 解决方法: exec3>&1;exec4>&1 s=$(((((cmd11>&3;echo$? >&4)|cmd2)3> &1|cmd3>a2>&3)2>&1|cmd4>b)4>&1) exec3>&-;exec4>&- 这个我一步步解释(好复杂,自己感觉看明白了,过一会再看,大脑仍然有几分钟空白~~~,没想到我也能看明白。 exec3>&1;exec4>&1前面的例子都有说明了,就是建立FD3,给cmd1恢复其FD1用和给cmd3恢复其FD2用,建立FD4,保存“echo$? ”输出值的“草稿纸”。 第一对括号: (cmd11>&3;echo$? >&4)和其后(第一个)管道。 在第一个括号(子shell)中,其FD1已经连到管道中了,所以用FD3将FD1恢复正常,不让他往管道跑;这里的cmd1没有stdin,接着将cmd1运行的返回码保存到FD4中。 第二对括号: ((cmd11>&3;echo$? >&4)|cmd2)3>&1和其后(第二个)管道。 前面的FD1已经不送给cmd2了,FD2默认也不送过来,所以cmd2也没有stdin,所以在第二对括号里面: cmd1和cmd2的stdout、stderr为默认输出,一直遇到“3>&1”为止。 请注意: “3>&1”,先将第二对括号看出一个命令,他们遇到第二个管道时,其FD1连到管道“|”,由于“3>&1”的作用,子shell的FD1送给FD3使用,所以所有FD3的输出都“流往”cmd3,又由于继承关系(继承第一行的命令),FD3实际上就是cmd1和cmd2的stdout,于是“cmd1和cmd2的stdout定向到cmd3的stdin” 第三对括号: (((cmd11>&3;echo$? >&4)|cmd2)3>&1|cmd3>a2>&3)2>&1和其后的第三个管道。 cmd1和cmd2的stdout已经定向到cmd3的stdin,处理之后,cmd3>a意味着将其stdout送给a文件。 而2>&3的意思是: 恢复cmd3的错误输出为FD3,即送往monitor。 于是“cmd3的stdout定向到文件a,stderr定向到屏幕”。 如果没有“2>&3”,那么cmd3的错误输出就会干扰cmd1和cmd2的错误输出,所以它是必须的! 请注意第三对括号后的“2>&1”|,其子shell的FD1本来连接着管道“|”,但子shellFD1慷慨大方,送给了FD2,于是FD2连接着管道。 还记得前面的cmd1和cmd2吗? 他们的stderr一直没动了。 于是在这里,通过管道送给了第四个命令cmd4了。 即“cmd1和cmd2的stderr定向到cmd4的stdin”。 后面就比较简单了。 cmd4>b表示“cmd4的stdout定向到文件b,stderr定向到屏幕(默认)” 第四对括号: ((((cmd11>&3;echo$? >&4)|cmd2)3>&1|cmd3>a2>&3)2>&1|cmd4>b)与其后的4>&1。 四对括号里面的FD1、FD2都处理完了。 但是还记得前面“echo$? >&4”那块“草稿纸”吗? “4>&1”的作用就是“将草稿纸上的内容送给monitor”,但是由于最外面还有$()将其“包着”。 于是其值赋给变量“s”。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 定向 详解 编辑 转载