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

咱们就会得到一个
标准输出stdout的输出结果“123.txt” 。
2 —— stdout
按照上面一样的假设,咱们运行另一跳命令【ls abc.txt】:
<img src="https://pic1.zhimg.com/v2-32eebce74f8dbe4f8ea6c1a3cee4684c_b.png" data-rawwidth="608" data-rawheight="112" class="origin_p_w_picpath zh-lightbox-thumb" width="608" data-original="https://pic1.zhimg.com/v2-32eebce74f8dbe4f8ea6c1a3cee4684c_r.png">咱们就会得到一个

咱们就会得到一个
标准错误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" class="origin_p_w_picpath zh-lightbox-thumb" width="557" data-original="https://pic2.zhimg.com/v2-344ea7a024ecd442d39ab9f6e68ff0ad_r.png">如上图所示,对比没有添加剧定向的操做,ls命令在使用以后并无将字符“123.txt”这个字符串打印到屏幕上。在紧接着的cat操做以后,咱们能够看到原本应该输出字符串被记录在了stdout.txt这个文件里面了。

如上图所示,对比没有添加剧定向的操做,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" class="origin_p_w_picpath zh-lightbox-thumb" width="545" data-original="https://pic3.zhimg.com/v2-cf091eefd7ca4eca5dc44dc8ba5bf8ee_r.png">如上图所示,文件描述符2,标准错误的重定向也是一样的原理被记录在了文件stderr.txt这个文件里面了。

如上图所示,文件描述符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=''