有关I/O重定向的详细教程
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、管道“|”(pipe line):上一个命令的 stdout 接到下一个命令的 stdin;
h、tee 命令是在不影响原本 I/O 的情况下,将 stdout 复制一份到档案去;
i、bash(ksh)执行命令的过程:分析命令-变量求值-命令替代(``和$( ))-重定向-通配符展开-确定路径-执行命令;
j、( ) 将 command group 置于 sub-shell 去执行,也称 nested sub-shell,它有一点非常重要的特性是:继承父shell的Standard input, output, and error plus any
other open file descrīptors。
k、exec 命令:常用来替代当前 shell 并重新启动一个 shell,换句话说,并没有启动子 shell。使用这一命令时任何现有环境都将会被清除,。exec 在对文件描述符进行操作的时候,也只有在这时,exec 不会覆盖你当前的 shell 环境。
2、基本IO
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
cmd << delimiter Here document,从 stdin 中读入,直至遇到delimiter 分界符
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的值,因为 > 是改变送出的数据信道,通俗的说是:把stderr并到stdout。
但使用类似 cmd 1>&3 这样的形式时,原理相同,但往往不同于 2>&1 和 1>&2 通常用来合并的作用。
注意:普通cmd命令的cmd n>&n 和exec n>&n 是有区别的。
exec 0<infilename # 打开文件infilename作为 stdin
exec 1>outfilename # 打开文件outfilename作为stdout
exec 2>errfilename # 打开文件 errfilename作为 stderr
exec 0<&- # 关闭 FD0
exec 1>&- # 关闭 FD1
exec 5>&- # 关闭 FD5
问:
如果关闭了 FD0、FD1、FD2,其后果是什么?
恢复 FD0、FD1、FD2与 关闭FD0、FD1、FD2 有什么区别?代码分别是什么?
打开了FD3~FD9,我们用完之后,你觉得是将他们关闭还是恢复?
下面是提示(例子来源于CU):
exec 6>&2 2>ver # FD2(本来往monitor送的) 定向到文件ver
command >>dev/null & #丢弃FD1(stdout)
exec 2>&6 # 恢复 FD2
4、简单举例(其中 yes.txt存在,no.txt不存在)
a、stdout 和stderr 都通过管道送给egrep了:
(ls yes.txt 2>&1;ls no.txt 2>&1) 2>&1|egrep \* >file
(ls yes.txt;ls no.txt) 2>&1|egrep \* >file
这个例子就是让大家:理解 命令执行顺序 和 管道“|”
在命令执行前,先要进行重定向的处理,并将把 nested sub-shell 的stdout 接到 egrep 命令的 stdin。
nested sub-shell ,在 ( ) 中的两个命令可以看作一个命令。其 stdout(FD1) 通过 “|” 作为 egrep 的 stdin,再加上 2>&1 时,初始 stdout 和 stderr 都往管道 “|” 送。
b、没有任何东西通过管道送给egrep,全部送往monitor。
(ls yes.txt 2>&1;ls no.txt 2>&1) >&2|egrep \* >file
虽然在()里面将 FD2转往FD1,但在()外,遇到 >&2 ,结果所有的都送到monitor。
5、中阶例子(其中 you 这个文件是存在的,no 和 wu 这两个文件不存在)
r2007兄的:?t=221848&show_type=new&sid=cf30398c911e0d2b16313c6922123f67
条件:stderr通过管道送给egrep,正确消息仍然送给monitor(不变)
exec 4>&1;(ls you no 2>&1 1>&4 4>&-;ls wu 2>&1 1>&4 4>&-)|egrep \* >file;exec 4>&-
或者
exec 4>&1;(ls you no;ls wu) 2>&1 1>&4 4>&-|egrep \* >file;exec 4>&-
r2007 兄在其贴已有详细说明,如果加两个条件:
(1)要求cmd1和cmd2并行运行;
(2)将cmd1的返回值赋给变量 ss。
则为:
exec 3>&1;exec 4>&1
ss=$(((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file) 4>&1)
exec 3>&-;exec 4>&-
说明:
exec 3>&1;4>&1
### 建立FD3,是用来将下面ls那条语句(子shell)中的FD1 恢复到正常FD1,即输出到monitor,你可以把FD3看作最初始的FD1的硬盘备份(即输出到monitor);
### 建立FD4,到时用作保存ls的返回值(echo $?),你可以将FD4看作你考试时用于存放计算“echo $?”的草稿纸;
(ls you no 2>&1 1>&3 3>&-;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,留以备用。
((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file)
于是,stderr 通过管道送给 egrep ,stdout 送给monitor,但是,还有 FD4,它送到哪去了?
$(((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep \* >file) 4>&1)
最后的 4>&1 ,就是把FD4 重定向到 FD1。但由于其输出在 $( )中,其值就赋给变量ss了。
最后一行关闭 FD3、FD4。
相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://www.juheyunku.com/jiaob/shell/10489.shtml
相关文章
热门TAG
命令 权重 外链 企业网站 白帽 php 织梦教程 dedecms修改内容 javascript 织梦 功能 标签 调用 详解 服务器 网站流量 实例解析 Dedecms 织梦cms HTML tags标签 python jquery教程 jquery windows SEO优化 蜘蛛 搜索引擎 网站收录 JSP最新文章
-
Centos下PHP5升级为PHP7的方法
时间:2021-01-03
-
在php当中常量和变量的区
时间:2020-12-29
-
PHP中经典的四大排序算法
时间:2020-12-29
-
dw怎么运行php文件?
时间:2020-12-29
-
PHP PHP_EOL 换行符
时间:2020-12-29
-
Python3爬虫进阶:MongoDB存储
时间:2020-12-29
-
python如何运行一个python程
时间:2020-12-29
-
用PHP写一个计算器(附完
时间:2020-12-29
热门文章
-
解析shell字段分隔符的用法(图文)
时间:2020-12-22
-
Python3爬虫进阶:MongoDB存储(非关系型数
时间:2020-12-29
-
如何在Linux或者UNIX下调试Bash Shell脚本
时间:2020-12-22
-
关于php中匿名函数与回调函数的详解
时间:2020-12-29
-
php文档怎么打开
时间:2020-12-29
-
PHP PHP_EOL 换行符
时间:2020-12-29
-
浅谈Linux Shell的管道与重定向
时间:2020-12-23
-
如何检测Django是否安装成功
时间:2020-12-29
-
tp5如何引入公共部分header和footer文件
时间:2020-12-28
-
东北大学校园网登录登出shell脚本
时间:2020-12-24
