当命令被执行时,会打开三个文件描述符,标准输入,标准输出,标准错误。标准输入默认来自键盘,标准输出和标准错误默认为屏幕。我我们可以利用重定向功能来改变命令执行时的标准输入、标准输出和标准错误。 重定向标准输入重定向标准输入语法如下
它表示在文件描述符 n 上打开文件 file,用于读文件。如果 n 被省略,那么默认在标准输入上打开文件 file。 例如,在执行 cat 命令的时候,如果不附带任何参数,那么它会读取标准输入(键盘)的内容,然后把它显示到标准输出(屏幕)。那么,我们可以重定向它的标准输入为一个文件
当然,
重定向输出重定向输出的语法如下
它表示在文件描述符n上打开文件 file,用于写文件。如果省略 n,那么表示在标准输出上打开文件 file,用于向文件写内容。 我们可以利用这个语法来重定向标准输出和标准错误。例如,ls 命令默认会把输出显示到屏幕(标准输出)上,我们可以利用重定向功能,把 ls 命令的执行结果写到一个特定的文件中。
然而,执行 ls 命令会出错,例如权限拒绝,这些错误信息会从标准错误显示到屏幕上。而上面的命令只是重定向了标准输出,因此错误信息还是会显示到屏幕上
我们利用重定向输出的功能,把标准错误重定向到一个单独的文件中
追加重定向输出如果重定向输出的文件不存在,那么会默认创建它,如果文件已经存在,那么会把文件的大小截断为了0,也就是经常说的文件被重写。 我们可以利用追加重定向输出的功能,把重定向输出追加到一个文件中,而不是重写文件。 追加重定向输出的语法如下
它表示在描述符 n 上打开文件 file,用于追加写文件。如果省略 n,那么表示在标准输出上打开文件,向文件里追加写内容。 例如,我们可以把多个 ls 命令执行的结果输出到同一个文件
重定向标准输出和标准错误在前面,我们用了一个很长的命令来分别重定向标准输出和标准错误,命令如下
其实,大可不必这么复杂,直接把标准输出和标准错误重定向到一个文件中。这就需要重定向标准输出和标准错误功能,语法如下
或者
那么,我们用重定向标准输出和标准错误的语法,来重构上面的复杂的命令
追加重定向标准输出和标准错误同样地,重定向标准输出和标准错误,在文件存在时,会截断文件的长度为0。如果为了避免这种情况的发生,我们可以选择使用追加重定向标准输出和标准错误的功能,语法如下
或者
那么现在我们利用这个语法,把 ls 命令的标准输出和标准错误,追加重定向到一个文件,而不是截断并写入一个文件
Here DocumentsHere Documents 语法如下
Here Documents 语法让 shell 去读取 here-document-lines 的内容,作为文件描述符 n 的输入。如果省略 n,那么读取的内容作为标准输入。 Here Documents 其实也是利用了重定向标准输入的功能,它通常在脚本中使用。例如有如下一个脚本,它格式化输出一段 HTML 文本
如果我们在脚本中使用的是 首先我们用
从输出结果中可以看到,我们使用了 Here Documents 的
Here Documents 针对 shell 扩展还有一个奇怪的用法。如果第一个 delimiter,不加引号,那么 Here Documents 的文本行会执行 shell 扩展,例如,下面的脚本使用了参数扩展
$1 表示执行脚本时传入的第一个参数,当我们执行脚本的时候,会把 $1 展开为第一个参数的值
而如果把 Here Documents 语法的第一个 delimiter 加上引号(单引号或双引号),那么 Here Documents 的文本行 不会 执行 shell 扩展
Here StringsHere Strings 语法如下
Here Strings 会让 shell 把 string 以及一个换行符,作为文件描述符 n 的输入。如果省略 n,那么使用的是标准输入。
我们以 cat 命令为例,cat 会读取参数指定的文件的内容或者标准输入的内容,我们使用 Here String 语法来重定向 cat 的标准输入
复制文件描述符我们在介绍重定向标准输出和标准错误的时候,提供有两种语法
或者
第二种语法中, 对于输出的复制文件描述符语法如下
官方的解释特别晦涩难懂,其实它就是把文件描述符 n 的输出重定向到文件描述符 fd上。 与之相对的,输入的复件文件描述符语法如下
这个目前我还没有用到过,所以不好举例了。 移动文件描述符对于输入,移动文件描述符语法如下
对于输出,语法如下
它们都会把文件描述符 fd 移动到 n 上,并且关闭 fd,只不过一个针对输入,一个针对输出。如果省略 n,对于输入而言,默认为标准输入,对于输出而言,默认为标准输出。 打开读写文件描述符
在文件描述符 n 上打开文件 file,用于读和写,如果省略 n,n 的值默认为0。 工作经验在编译 Android 源码的时候,有时我们既想把日志显示到终端上,又想把日志保存到文件中,我们可以使用 tee 命令。但是 tee 命令只操作标准输出,而日志信息还包含标准错误的信息,因此我们还需要复制文件描述符的功能,把标准错误重定向到标准输出。
当然,我们可以使用另一种管道操作符 |&,它会把前一个命令的标准错误和标准输出,连接到下一个命令的标准输入。 因此上面的命令可以改写成如下命令
|
|