Bash 重定向
当 Bash 启动的时候,它会打开三个标准文件描述符 (File Descriptor)
/dev/stdin
- file descriptor 0/dev/stdout
- file descriptor 1/dev/stderr
- file descriptor 2
除非你将文件描述符关了,否则它总是指向某个文件。通常 Bash 启动的这三个文件描述符,stdin
, stdout
和 stderr
会指向你的终端。从终端读取输入,也输出到终端。
假设你的终端是 /dev/tty0
,那么当 Bash 启动的时候,你的文件描述符表会像下面这样
当 Bash 运行一个命令时,它会 folk 出一个子进程 (查看 man 2 fork
),继承父进程的所有文件描述符,然后设置重定向,最后执行该命令 (查看 man 3 exec
)。
将标准输出和标准错误重定向到相同文件
2>1
表示将 stderr
重定向到文件名为 1
的文件。正确的将 stderr
重定向到 stdout
的写法是 2>&1
,使用 &
符号来表示后面跟的是一个文件描述符,而不是一个文件名。
下面的命令将 stdout
和 stderr
都重定向到文件 file
command >file 2>&1
当 Bash 看到重定向时,会按照从左到右的顺序来处理,过程如下:
首先是初始化的文件描述符表
然后 Bash 处理第一个重定向 >file
,让 stdout
指向 file
接着 Bash 处理第二个重定向 2>&1
,让文件描述符2指向与文件描述符1相同的地方
Bash 使用 &>
操作符简化上面的重定向命令
command &>file
注意,重定向的顺序非常重要,下面的重定向只将 stdout
重定向到了文件 file
,而 stderr
依然还是指向到原来的 terminal。
command 2>&1 >file
执行该命令时的过程如下:
初始的文件描述符表
然后处理 2>&1
接着处理 >file
,stdout
被重定向到 file
,但 stderr
没变,还是指向原来的终端
忽略命令产生的输出
command > /dev/null
/dev/null
是个特殊的文件,任何写入到它的数据都会被忽略。所以将标准输出重定向到这个特殊文件来忽略命令产生的输出。同样,我们也可以同时将标准输出和标准错误重定向到这个文件。
command >/dev/null 2>&1
或者使用简单的写法
command &> /dev/null
这时的文件描述符表如下