经常会在shell中看到类似如下的命令,啥意思呢?
1 | command > /dev/null 2>&1 |
在shell重定向中出现的数字称之为文件描述符,linux或者osx等系统开启后,会默认打开以下三种特殊的文件描述符:
- 0:标准输入
- 1:标准输出
- 2:标准错误输出
_0_号文件描述符会从键盘获取数据输入,而_1_、_2_号文件描述符会把数据输出到设备上(命令行终端)。
重定向就是改变数据输入来源或者输出目的地的一种操作,重定向有以下几种操作符:
:重定向输出,比如开篇的那条命令,将输出结果重定向到
/dev/null
文件中。- <:重定向输入,比如:
1 | echo "hello, world" < log.txt |
上述命令将原本输向终端的数据重定向了log.txt文件中。
:与
>
类似,只不过是追加内容- <<:与
<
类似,同样是追加内容
shell还有一个很有用的功能就是将一个文件描述符绑定到另一个,2>&1
的意思就是将标准错误也输出到标准输出当中,这么做的结果就是什么也不在终端上显示。
要将标准输出和标准错误绑定到一起,还有一个更简化的方式:
1 | command &> /dev/null |
或者这样:
1 | command > &/dev/null |
还有一个需要注意的地方就是n>&m
在shell命令中的顺序问题,比如换成这样:
1 | command 2>&1 > /dev/null |
这得出的结果跟开篇的那条命令是不一样的,标准错误仍然会输出到终端上,比如用一个不存在的命令在终端上试试:
1 | xx 2>&1 > /dev/null |
这命令会在终端上输出command not found
。
在以上的写法中,shell会先把标准错误指向标准输出(此时标准输出还未重定向到/dev/null
),然后再把标准输出重定向到/dev/null
。
类似此类的脚本,我们可以用来安静地执行某些脚本,比如goagent或者jekyll等,它们在运行的时候会打出各种log,而我又不想新开一个终端单独运行,这时就可以这样:
1 | jekyll serve --w > /dev/null 2>&1 & |
世界终于清净了许多!
PS:最后一个&
符号用来后台运行脚本的,有了它,ctrl-z之后,我们就可以用当前终端窗口去干一些其他事情。