xDroid's Blog

假装高冷的Geek

20.7 输入输出重定向 (从新手到菜鸟的Linux教程)

这个是 shell 的(一部分)精髓吧 所以我几乎每次都会搞错

简单说来就是通过一些保留的符号,操纵命令的输入流、输出流(包括标准输出流和错误输出流)。我们提到过 Unix/Linux 设计哲学是一切都是文件,所以一个命令(进程?)输入、输出都是“文件”;既然是文件那就可以进行重定向。

我们先从一个范例入手感性认识一下:

$ pwd
/tmp/demo
$ pwd >output_file
$ ls
output_file
$ cat output_file
/tmp/demo

比较第一和第二条命令,第二次的输出“消失了”,而是跑到了大于号后面文件名中。那么这里 > 就是一个重定向符。


一般我们能操纵的流有标准输入流 0 ,标准输出流 1 ,标准错误流 2 。重定向符也有 3 个,输入重定向符 < ,覆盖输出重定向符 > ,追加输出重定向符 >> 。需要注意的是上面提到的 012 是文件描述符,来历比较复杂我也搞不清楚(爬走,参见学习 Linux,101 : 流、管道和重定向)。

这些符号的组合方法是:

[n]<word   # 从文件 word 读取作为输入流到描述符[n],默认 n=0
[n]>word # 将描述符[n]的内容覆盖输出到文件 word,默认 n=1
[n]>>word # 将描述符[n]的内容追加输出到文件 word,默认 n=1
&[n] # 表示描述符[n]此刻指向的文件,而不是保持引用

对于最后一条,我们需要重点举例:

command 2>&1 >output_file  # 不是想要的结果!标准错误定向到了标准输出!
command >output_file 2>&1 # 正确!标准错误一起输出到了 output_file

因此有一个更好的符号是 &>word ,这语义上与 >word 2>&1 等价。


注意:不要轻易使用 > !由于覆盖操作会不经意间清空目标文件内容!


另一个需要简短介绍的功能是 Heredoc ,大概模样长这样

command << delimiter
content
delimiter

最后一行的 delimiter 必须和第一行 heredoc 符号之后的分界符一模一样,这样才能够结束 heredoc 。

其实我也不经常用。

Reference