Shell中经常看到的">/dev/null 2>&1"的含义

shell中我们经常会看到:>/dev/null 2>&1,是什么含义,我们应该怎么使用它:

">“代表重定向到哪里,例如:echo "hello world" > ./hello.txt
1 表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于"1>/dev/null" 。因此,> /dev/null 2> &1也可以写成“1> /dev/null 2> &1”
2 表示stderr标准错误
& 表示等同于的意思,2>&1,表示2的输出重定向等同于1 。

  • & 是一个描述符,如果1或2前不加&,会被当成一个普通文件。
  • 1>&2 意思是把标准输出重定向到标准错误.
  • 2>&1 意思是把标准错误输出重定向到标准输出。
  • &>filename 意思是把标准输出和标准错误输出都重定向到文件filename中
那么本文标题的语句:

1>/dev/null 首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。
2>&1 接着,标准错误输出重定向等同于 标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

原理:
command > file 2>file 与command > file 2>&1

它们有什么不同的地方吗? 

首先command > file 2>file 的意思是将命令所产生的标准输出信息,和错误的输出信息送到file 中.command > file 2>file 这样的写法,stdout和stderr都直接送到file中, file会被打开两次,这样stdout和stderr会互相覆盖,这样写相当使用了FD1和FD2两个同时去抢占file 的管道。
而command >file 2>&1 这条命令就将stdout直接送向file, stderr 继承了FD1管道后,再被送往file,此时,file 只被打开了一次,也只使用了一个管道FD1,它包括了stdout和stderr的内容。
从IO效率上,前一条命令的效率要比后面一条的命令效率要低,所以在编写shell脚本的时候,较多的时候我们会command > file 2>&1 这样的写法。

问题点
1. 2>&1的含义
  • 将错误输出重定向到错误输入
  • “>&”是一个整体,不可分开,分开后就不是上述含义了
    比如有同学会这么想:2是标准错误输入,1是标准输出,>是重定向符号,那么”将标准错误输出重定向到标准输出”是不是就应该写成”2>1”就行了?是这样吗?
    如果是尝试过,你就知道2>1的写法其实是将标准错误输出重定向到名为”1”的文件里去了
  • 写成2&>1也是不可以的
2. 为什么2>&1要放在后面

考虑如下一条shell命令

ping -c 5 $ip  >/dev/null 2>&1

为什么2>&1一定要写到>/dev/null后面,才表示标准错误输出和标准输出都定向到/dev/null中? 

上面的语句实际是这样的:
ping -c 5 $ip 1>/dev/null 2>&1
1. 1表示stdout标准输出,默认是屏幕
2. 执行1>/dev/null后, 本来重写向到屏幕上的内容被重定向到/dev/null中
3. 执行2>&1后, 2指向1(1指向/dev/null),因此2也指向了/dev/null
再来看
1. ping -c 5 $ip 2>&1 >/dev/null
2. 本来1指向屏幕
3. 执行2>&1后, 2指向1(1指向屏幕),因此2也指向了屏幕
4. 执行>/dev/null后,相当于 1>/dev/null,此时1指向/dev/null,而2还是指向屏幕。

这不是我们想要的结果

3. 每次都写”>log 2>&1”太麻烦,能简写吗?

有以下两种简写方式

&>log


>&log

上面两种方式都和”>log 2>&1”一个语义。 

那么 上面两种方式中&>和>&有区别吗?
语义上是没有任何区别的,但是第一中方式是最佳选择,一般使用第一种

 

相关知识点
1. /dev/null

可以将/dev/null看作"黑洞". 它非常等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到. 然而, /dev/null对命令行和脚本都非常的有用.
用处:
禁止标准输出. 1 cat $filename >/dev/null # 文件内容丢失,而不会输出到标准输出.
禁止标准错误. 2>/dev/null 这样错误信息[标准错误]就被丢到太平洋去了.

2. /dev/zero

/dev/zero文件代表一个永远输出 0的设备文件,使用它作输入可以得到全为空的文件。因此可用来创建新文件和以覆盖的方式清除旧文件。
下面使用dd命令将从zero设备中创建一个10K大小(bs决定每次读写1024字节,count定义读写次数为10次),但内容全为0的文件。
dd if=/dev/zero of=file count=10 bs=1024

 

---The End---

 

参考链接:
https://blog.csdn.net/zhaominpro/article/details/82630528
https://www.cnblogs.com/selectztl/p/9477988.html

 

转载于:https://www.cnblogs.com/whatislinux/p/58ca01cd9aeb0b6595c644d7f3c3a7d6.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值