设为首页 收藏本站
查看: 1056|回复: 0

shell输出的那个垃圾桶——/dev/null

[复制链接]

尚未签到

发表于 2018-8-25 08:30:52 | 显示全部楼层 |阅读模式
  昨晚花费一整晚在知乎回答了一个关于shell里面的重定向输出到/dev/null的问题。果断今晚也同步发在这里,反正也没人看~~~~
  以下来自一个重度linux使用患者不请自来的回答。
  先用简单的语言回答题主的问题:
shell程序中 2> /dev/null 代表什么意思?
  答:“2> /dev/null” 代表忽略掉错误提示信息。
如题 2> 代表什么意思?讲错误输出删除?
  答:“2>” 代表重定向操作错误提示信息。只有这两个字符并不能删除错误输出。
如果有正确的输出并赋值给i,i会得到正确的值吗?
  答:i会得到正确的值。
  上面的三个回答是我认为相对比较友好,容易理解的回答。
  ---------------------------------------我是啰哩啰唆回答的分割线-------------------------------------
  下面,咱们一起来看看这个命令操作涉及到的知识点(敲黑板。。。。)题主问题里描述的这条命令其实涉及到三部分的内容,如下图:
<img src="https://pic1.zhimg.com/v2-32b909c43d75fa9c1f7c9286fdbffdc4_b.png" data-rawwidth="247" data-rawheight="175">(原谅我奇怪的画风……)    下面的所有回到都是假设大家对linux没有太多的了解所作的,如有高手,打脸的时候请轻一点。+_+
  
  1. 文件描述符
  下面手打一段《linux shell脚本攻略》的描述(如有侵权我会删除的 T_T):
文件描述符是与文件输入、输出关联的整数。它们用来跟踪已打开的文件。最常见的文件描述符是stidin、stdout、和stderr。我们可以将某个文件描述符的内容重定向到另外一个文件描述符中。                                                                                          《linux shell脚本攻略》
  文件描述符我们常见的就是系统预留的0,1和2这三个,他们的意义分别有如下对应关系:

  •   0 —— stdin(标准输入)
  •   1 —— stdout (标准输出)
  •   2 —— stderr (标准错误)
  其中,shell编程里经常用到的就是描述符1,和描述符2。这样下面我们来举两个栗子,就知道神马是1和2了:
  1 —— stdout
  假设:在当前目录下我们“有且只有”一个文件名为 123.txt 的文本文件。这个时候我们运行下面的命令【ls 123.txt】:
<img src="https://pic4.zhimg.com/v2-8830db673e8054c3050bc47f3d083c73_b.png" data-rawwidth="622" data-rawheight="158">  我们就会获得一个标准输出stdout的输出结果“123.txt” 。  2 —— stdout
  按照上面同样的假设,我们运行另外一跳命令【ls abc.txt】:
  <img src="https://pic1.zhimg.com/v2-32eebce74f8dbe4f8ea6c1a3cee4684c_b.png" data-rawwidth="608" data-rawheight="112">  我们就会获得一个标准错误stderr的输出结果“ls:无法访问abc.txt:没有那个文件或目录”
  有同学应该会觉得,这两个事例好像跟1和2这两个阿拉伯数字好像没有关系。这个就要结合第二个知识点“重定向操作”来理解了。
  2.重定向操作
  书里找不到准确的关于重定向的描述,我很不要脸滴来说一下我的理解吧。重定向操作,其实就是通过在shell命令后面追加一个重定向操作符号,将shell命令对应的文件描述符输出的文本信息重新输入到另外一个指定文件的操作。
  重定向操作符号有两个>和>>。尽管这两个操作符都可以将重定向到文件,但是前者会先清空文件,再写入内容;后者会将内容追加到现有文件的尾部。(对了,重定向的操作制定的文件如果原来不存在的话,重定向的操作会主动创建这个文件名的文件的)
  下面我们结合第1个知识点文件描述符来举栗子吧。
  重定向标准输出stdout
  <img src="https://pic2.zhimg.com/v2-344ea7a024ecd442d39ab9f6e68ff0ad_b.png" data-rawwidth="557" data-rawheight="136">  如上图所示,对比没有添加重定向的操作,ls命令在使用之后并没有将字符“123.txt”这个字符串打印到屏幕上。在紧接着的cat操作之后,我们可以看到本来应该输出字符串被记录在了stdout.txt这个文件里面了。
  其实,对于标准输出的重定向操作,>等同于1>。上面栗子执行命令【ls 123.txt > stdout.txt】得到的效果也是一样的。
  重定向标准错误stderr
  <img src="https://pic3.zhimg.com/v2-cf091eefd7ca4eca5dc44dc8ba5bf8ee_b.png" data-rawwidth="545" data-rawheight="134">  如上图所示,文件描述符2,标准错误的重定向也是同样的原理被记录在了文件stderr.txt这个文件里面了。
  描述符的重定向还有下面的几种用法:
  你可以将stderr单独定向到一个文件,将stdout重定向到另一个文件:
cmd 2>stderr.txt 1>stdout.txt  也可以利用下面的方法,将stderr转换成stdout,使得stderr和stdout都被重新丁香到同一个文件中:
cmd> output.txt 2>&1  或者采用这个方法(这个经常用到,我个人比较喜欢用这个,少写几个字符(*^__^*) )
cmd &> output.txt  (终于最后一个知识点,原来认真答题码字这么嘞。摔~)
  3. linux特殊文件
  手抄一段《linux shell脚本攻略》描述:
/dev/null是一个特殊的设备文件,这个文件接收到的任何数据都会被丢弃。因此,null这个设备通常也被成为位桶(bit bucket)或黑洞。
  简单地理解就是,重定向操作给这个/dev/null文件的所有东西都会被丢弃。
  因为这些文件描述符输出的字符串,总是会显示出来的。如果我们在shell编程的时候,操作到某一条命令的返回结果,我们不想要这个时候又不想让这个输出结果打印到屏幕上(打印错误,多不好看对不对^_^)我们就可以重定向到/dev/null这个文件来,由/dev/null这个文件负责处理后事。
  这个丢弃的结果又不能粗暴的认为是删除错误输出,这个操作是一个丢弃重定向输入输出的操作。形象地理解就是,ATM机打印的纸质流水账单(stdout和stderr)本来应该你来保存处理的,但是你又没有用放在手里(打印屏幕)又碍事,所以账单从你的手里重新被丢到了垃圾桶(/dev/null)了。但是,垃圾桶的垃圾是怎么处理的你是不知道的。
  不知道上面的描述,答主是不是能明白这三个知识点了?
  只要理解了上面的三个点,其实答主的第三个问题很好滴能解决了。
  问题3的思路
  让一个变量获得命令输出的结果,是下面这样的处理:
i=$(ls 123.txt)  这样,i 就能获得命令【ls 123.txt】输出在屏幕的所有结果了。无论输出的是stdout输出还是stderr的错误提示。i 这个变量都能获取到一个字符串。
  针对答主的问题,应该是如下操作:
i=$(ls 123.txt 2> /dev/null)  这样的命令,ls命令如果出现了错误提示,就会被重定向到/dev/null垃圾桶去了。所以,i 这个变量就获取不到stderr标准错误的提示字符串了。所以,在这个命令的操作中,i 就只能获得文件stdout标准输出,也就是文件述符1的屏幕输出结果"123.txt"。
  如果,这个123.txt文件不存在,i 就什么都拿不到,因为错误提示被/dev/null 吃了(划掉),被重定向丢弃了。所以,i 就是个什么都没有的空变量。基本就是如下效果一样:
i=''


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-556175-1-1.html 上篇帖子: SHELL中创建临时文件的方法 下篇帖子: crontab执行shell脚本日志中出现乱码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表