理解 Linux shell 脚本的 2>&1
我们在编程中经常会使用一些固定语句来解决对应固定的问题,在 shell 脚本中一个被经常使用但不太好理解的短句就是 2>&1
,例如:
ls foo > /dev/null 2>&1
下面我们一步步了解下这种结构的含义。
I/O redirection 重定向
简单理解,redirection 重定向就是将一个命令的 output 输出发送到另一个地方。例如,我们通过 cat
命令打印一个文件的内容到屏幕:
$ cat foo.txt
foo
bar
baz
我们也可以将输出的内容发送到其他地方,例如将内容重定向到另一个文件 file.txt:
$ cat foo.txt > output.txt
$ cat output.txt
foo
bar
baz
执行第一条 cat 命令,我们不会看到任何输出信息,因为我们修改了 standard output (stdout)标准输出到一个文件,所以它就不会输出到屏幕了。
需要注意的是还有另一个地方:standard error (stderr)标准错误,当有错误时会输出信息。所以当我们通过 cat 命令输出一个不存在的文件内容时:
$ cat nop.txt > output.txt
cat: nop.txt: No such file or directory
以上示例中即使我们将 stdout 重定向到一个文件了,由于 output.txt 不存在,stderr 依然会输出错误信息到屏幕。因为我们重定向的只是 stdout 而不包括 stderr。
file descriptors 文件描述器
一个文件描述器是一个正整数,用来表示一个打开文件的。每个文件都有其各自的文件描述器。这里我们只需要知道 stdout 和 stderr 有其各自的文件描述器 id 定义了它们各自的地址。
stdout 是 1,stderr 是 2。
在之前的示例中,我们可以修改命令为如下结构:
cat foo.txt 1> output.txt
这里的 1 就是 stdout 的文件描述器,通过重定向语法 [FILE_DESCRIPTOR]>
将 stdout 重定向到另一个文件。注意 1>
可以简写为 >
。
类似的,可以将 stderr 重定向到指定的目的地:
$ cat nop.txt 2> error.txt
$ cat error.txt
cat: nop.txt: No such file or directory
这样就会将 error 存入 error.txt 文件,屏幕上不会输出任何信息。
下面我们理解下 2>&1
的意义。我们使用 &1
来指向 stdout 的重定向地址,所以 2>&1
表示重定向 stderr 到和 stdout 同样的重定向位置上。所以我们就可以通过下面示例的方法同时将 stdout 和 stderr 重定向到同一个文件中:
$ cat foo.txt > output.txt 2>&1
$ cat output.txt
foo
bar
baz
$ cat nop.txt > output.txt 2>&1
$ cat output.txt
cat: nop.txt: No such file or directory
总结
- 有两个地方用来让程序发送输出内容:stdout,stderr
- 可以单独定义两个输出的重定向目的地
- 文件描述器用来识别 stdout (1) 和 stderr (2)
command > output
是command 1> output
的简写- 通过
&[FILE_DESCRIPTOR]
指向一个文件描述器的重定向目标地址上 2>&1
可以将 stderr 重定向到 stdout 同样的重定向地址上。反之亦然。
参考链接
Understanding Shell Script's idiom: 2>&1
In the shell, what does “ 2>&1 ” mean?
标签:无