>/dev/null 2>&1和2>&1 >/dev/null区别根本分析

Linux中的标准输入输出
标准输入0 从键盘获得输入 /proc/self/fd/0
标准输出1 输出到屏幕(即控制台) /proc/self/fd/1
错误输出2 输出到屏幕(即控制台) /proc/self/fd/2

区别:

/dev/null 2>&1
//会将标准输出,错误输出都重定向至/dev/null,也就是全部丢弃
2>&1 >/dev/null
//只会将标准输出重定向至/dev/null,即丢掉标准输出,错误输出显示到屏幕上

为什么仅仅改变了命令顺序就会使结果不同呢?我们先来看看linux是如何做到“重定向”的。
在这里插入图片描述
  上图是linux中单进程的文件数据结构图,最左边使我们熟悉的fd标志,也就是文件描述符,一个进程内所有的文件描述符按照顺序排列构成一张文件描述符表,其中包括fd0,fd1,fd2。(注意:这里并没有说标准输入,标准输出,错误输出,原因后面讲)
  那么,问题来了,假如我们想fd1写入数据时,最终数据会到哪儿呢?事实上fd1作为文件描述符,它本身并不是文件的真正的“入口”,文件真正的“入口”在文件描述符表的第二列:记录了每个文件描述符所对应文件位置的文件指针。换言之,如果我们更换fd1所对应的文件指针,就改变了fd1指向文件的”真正位置”。
  fd0,fd1,fd2指向的文件默认情况下分别是/dev/stdin、/dev/stdout和/dev/stderr,这才是真正的标准输入,标准输出,错误输出,如果将数据写入到/dev/stdout中,就会在屏幕上显示数据,fd0,fd1,fd2只是标志而已,真正起作用的是他们对应的文件指针!
  所以重定向命令’>’所做的工作就是就是改变了fd所对应的文件指针!
  这样我们就很好理解为什么>/dev/null 2>&1和2>&1 >/dev/null命令是不一样的。

/dev/null 2>&1
//1. 首先将fd1的文件指针更改为指向/dev/null
//2. 然后将fd2的文件指针更改为fd1所对应的文件指针,也就是/dev/null文件

结果就是fd1和fd2对应的文件指针都指向/dev/null,也就是将“标准输出”,“错误输出”都重定向至/dev/null,但是程序依然把fd1,fd2当做”标准输出”,”错误输出”,向其中写入“标准信息”和“错误信息”(ps:愚蠢的程序)。但是其实都写到了/dev/null这个无底洞里~

2>&1 >/dev/null
//1. 首先将fd2的文件指针更改为fd1所对应的文件指针,也就是STDOUT文件
//2. 然后将fd1的文件指针更改为指向/dev/null

这样fd2的文件指针指向STDOUT,fd2其实代表的是“标准输出”!,不过程序还是将fd2当做”标准错误””,向其中写入“错误信息”,结果都到了标准输出里面,而fd1的文件指针指向/dev/null,程序写入的“标准信息”都会到/dev/null里~

至此就明白了为什么改变了命令顺序就会使结果不同,其实这和linux重定向命令’>’的工作原理有关,详见I/O重定向的原理和实现
  还需要注意的是,linux默认将fd0,fd1,fd2设置为指向/dev/stdin、/dev/stdout和/dev/stderr文件,程序工作时也默认把fd0,fd1,fd2当做标准输入,标准输出,错误输出的文件描述符。但是fd0,fd1,fd2的文件指针都是可以随意更改的,例如使用dup2(),所以fd0,fd1,fd2并不是所有场合都是代表标准输入,标准输出,错误输出,这只是个约定俗成的习惯,并不属于UNIX的标准规范。毕竟输入0,1,2要比输入/dev/stdin、/dev/stdout和/dev/stderr文件位置要简单得多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值