shell 中的重定向

背景

相当一段时间以来,我对 Shell 中的重定向只有两个简单的认知:

  1. 可以把命令的结果写到文件里
  2. 写脚本的时候,如果不想让内容输出到终端,要重定向到特定的位置

由于认知不深刻,导致很多功能只能现学现查,不仅记不住,而且用起来也不知甚解。这里系统的整理一下。

首先,*nix 系统中有三种特殊的文件描述符,其中 0 表示标准输入,它一般指的是我们的键盘,1 表示标准输出,2 表示错误输出,它们一般都表示屏幕。所以 Shell 可以理解为一个盒子,它从 0(标准输入,也就是键盘)读取命令,没有错误的话就输出到 1(标准输出),命令执行错误的话输出到 2(错误输出),最终都会在屏幕上显示出来。

举一个例子,请看下面这行代码:

ls exist.sh not_exist.sh 1>success 2>fail

这行代码的意思首先是要展示两个文件,假设一个文件存在,另一个文件不存在(从名字就能看出来了),这样会产生一行标准输出和一行错误输出。1>success 的意思是说把标准输出重定向到 success 这个文件,类似的,2 > fail 表示把错误信息输出到 fail 这个文件。

类似的语法还可以写成:

ls exist.sh not_exist.sh >success 2>&1

这是因为如果 > 前面不加数字,默认是标准输出。而 2>&1 表示让错误输出使用和标准输出相同的重定向方式。因此这个命令等价于 ls exist.sh not_exist.sh 1>success 2>success

从严格意义上讲,使用 2>&1 的效率更高一些,因为它会复用标准输出的管道。

取消输出

有了上述背景的积累,我们来看一个实际的问题。有时候在 Shell 脚本中我们只希望用到一个命令的功能, 但不希望它产生任何输出,此时可以使用如下命令:

top Created with Sketch.