基本概念

Linux命令执行过程

File/DevicestdinShFeillle/CDosemtvmdiaecnredrstdoutFile/Device

Linux中,万物皆文件,执行命令的过程也是如此。
将文件读入标准输入流,执行命令;如果执行成功,将结果输出到标准输出流;如果执行失败,则将结果输出到标准错误流。

文件描述符(File Descriptor)

Linux会为打开的文件分配文件描述符,通过描述符对文件进行操作。
为了完成上述流程,系统本身会占用3个文件描述符0,1和2,分别对应:

  • 0 standard input 即标准输入
  • 1 standard output 即标准输出
  • 2 standard error 即标准错误

默认情况下,标准输入为键盘,标准输出和标准错误为监视器,用户可以通过重定向方式来更改它们

重定向

重定向方向和基本用法

Linux系统允许用户通过><分别对输入和输出进行重定向:

  • < 输入重定向。cmd < input.file 即,将input.file重定向为cmd的stdin
  • > 输出重定向。cmd > output.file 即,将cmd的stdout重定向到output.file
  • >> 输出重定向(追加)。cmd >> output.file即,将cmd到stdout重定向到output.file,但是采用追加方式

>>>的区别在于,>会覆盖文件,>>只会将新内容追加到输出文件中

&的作用

通常,在命令的最后添加&,可以使其在后台运行,不占用当前会话
除此之外,&在重定向中有一些特殊作用:

  • &n, 其中n为数字,表示描述符n代表的文件,例如&1代表stdin
  • >&-,表述关闭输出
  • <&-,表述关闭输入

特殊用法

丢弃输出

Linux系统允许用户抛弃某些输出,用户可以通过将输出重定向到/dev/null来抛弃输出
/dev/null也被称为Bit Bucket或黑洞,参考What is the Unix/Linux “bit bucket”?

如果我们希望将stderr的输出丢弃:

cmd 2> /dev/null

重定向到描述符

通常情况下,直接使用cmd > output.file,只会将成功结果输出到output.file中,错误仍然会显示在shell内,此时如果希望将错误也输出到文件,可以使用:

cmd > output.file 2>&1

因为&1在默认情况下表示stdout,所以2>&1是将stderr重定向到stdout上,而在前一步cmd > output.file中,stdout已被重定向到output.file,所以stderr也被重定向到output.file

思考:如果将命令顺序调整会发生什么?

cmd 2>&1 > output.file

在没有其他操作的情况下,这个命令和直接执行cmd > output.file效果是一样的,因为在第一步cmd 2>&1中,stderr被重定向到stdin,即监视器,第二步中,将stdout重定向到output.file,错误仍然会在监视器显示,但是结果会被输出到文件中

exec命令与重定向

管道

了解了重定向和输入、输出后,再理解管道就显得非常容易。 管道使用|描述,实际使用方法为cmd1 | cmd2 | cmd3,管道的意义是将上一个命令的stdout作为下一个命令的stdin,实现连续执行命令的效果:

cmd1stdout/stdincmd2stdout/stdincmd3

遇到执行错误的情况,会发生什么? 管道只能处理stdout的数据,无法处理stderr的数据,即便前一个命令发生错误,后续的命令仍然会被执行,但是只会处理stdout中输出的数据。

总结

懒得写了,其实整篇都在总结。