linux命令每日学-管道与重定向

linux命令每日学-管道与重定向

  经常搞混管道与重定向这两种命令,今天特意对这两种命令进行一个梳理,从而加深对着两个命令的理解。

管道

  在linux种管道的主要目的是实现两个不同进程间的通信,通俗的说也就是将A进程的输出传递给B进程的输入。通过‘ | ’命令来实现,实现方式为A | B。但是有两点需要注意:

  • 管道只能传递A进程的正确输出,异常输出将不会被传递。
  • B进程必须是能够接收标准输入的程序,否则传递的数据会被抛弃。

示例

1
cat test.txt | grep hello #这段代码将test.txt文档中的内容输出到查找hello字符串的grep命令中去

重定向

  要理解重定向,首先要弄清楚linux系统程序是如何使用文件的。在linux系统中用三个独立的数据结构来表示文件:

  • 描述符表:每个进程都有自己独立的文件描述符表,表中的内容是指向进程打开的文件的文件表的指针。
  • 文件表: 打开的文件的集合是由一张文件表来表示的,所有的进程共享这张表,该表中的每个表项包含当前文件的位置,引用计数,以及一个指向v-node表中对应表项的指针。 每当关闭一个文件描述符,文件表中对应的表项中的引用计数就会减1,当引用计数为0时,内核就会删除该表项。多个文件描述符可以指向同一个文件表项(例如调用fork)。
  • v-node表: 通文件表一样,所有的进程共享这张v-node表。v-node表中的表项对应于一个文件,它记录了文件的元数据信息,包括文件权限、文件类型等。多个文件表项可以指向同一个v-node表项(例如利用open打开同一个文件)。

三者的关系如下图所示:
image

  讲了这么多,我们就可以进入主题了。重定向本质上就是将进程中的标准输入或输出文件描述符指向我们指定的文件的文件表表项。

  • ‘>’命令将进程的标准输出描述符重定向到指定的文件,其形式为A > filename。A程序的输出会全部写入到filename文件中。
  • ‘<’命令将进程的标准输入描述符重定向到指定的文件,其形式为A < filename。A程序的输入内容为filename文件中的内容。

示例

1
2
3
ps -ef > out.txt ps命令输出的系统进程信息会全部写入out.txt文件中。

grep hello < out.txt grep命令回在out.txt中搜索有hello的行。