shell重定向

经常会在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
2
jekyll serve --w > /dev/null 2>&1 & 
python goagent/local/proxy.py &> /dev/null &

世界终于清净了许多!

PS:最后一个&符号用来后台运行脚本的,有了它,ctrl-z之后,我们就可以用当前终端窗口去干一些其他事情。