关于/dev/null,以及如何使用它
今天在看MIT的一个课程时,老师给的程序实例中有一个地方没弄明白:
#!/bin/bash
echo "Starting program at $(date)" # Date will be substituted
echo "Running program $0 with $# arguments with pid $$"
for file in "$@"; do
grep foobar "$file" > /dev/null 2> /dev/null
# When pattern is not found, grep has exit status 1
# We redirect STDOUT and STDERR to a null register since we do not care about them
if [[ $? -ne 0 ]]; then
echo "File $file does not have any foobar, adding one"
echo "# foobar" >> "$file"
fi
done
其中的grep foobar "$file" > /dev/null 2> /dev/null
我着实不能理解,然后进行了相关调查,在What is /dev/null and How to Use It这里找到了答案。这篇笔记仅作为我个人记录,防止以后忘记。
Liunx操作系统能自己生成一些虚拟文件以供运行中的程序读取数据,/dev/null就是这样一个文件,但它的特殊之处在于它不是用来读的而是用来写的。无论往这个文件里写什么,最终都会被清理。
我们知道Liunx系统中的数据可以视为stdin,stdout,stderr流。默认情况下,cmd有两个返回值,分别是命令的output和运行状态erroe。output会进入stdout流,error会进入stderr流。一旦程序运行成功,error=0;否则都是运行出现异常
什么是文件描述符(the file descriptor)
在 UNIX 生态系统中,这些是分配给文件的整数值。stdout(文件描述符 = 1)和 stderr(文件描述符 = 2)都有一个特定的文件描述符。使用文件描述符,我们可以把stdout和stderr重定向到其它文件
我们知道>
重定向符,往往我的使用方法是
echo "Hello World" > log.txt
其实这是因为默认情况下,会重定向的是stdout。
如果我们想知道命令运行的状态,可以像下面这样使用
CMD 2> error.txt
那为什么要使用/dev/null呢?
有一些命令在使用的时候,如果报错,会有大量的报错信息,比如grep
作者给了一个很好的例子
$ grep -r hello /sys/
但是使用重定向之后,这些报错全部都会写进/dev/null中,丢弃。
特定情况下,我们可能还希望将output与error全部丢弃,如:
$ grep -r hello /sys/ > /dev/null 2>&1
这个命令可以分为2步,先把所有output输到/dev/null。然后把这个命令的error输出,并和1(output)合并
这样一来程序不会有任何输出,达到了简洁的目的
总结
/dev/null相当于一个垃圾桶,只不过是以一种写入文件的方式把垃圾丢掉而已。
最后感谢这篇文章的原始作者给我的帮助