Bash的基本特性之管道pipe

管道是 Unix 中最古老的进程之间的通信形式。把数据流从一个进程连接到另一个进程就叫做 “管道”。

管道的操作符是 |,仅能处理经由前面一个命令传出的正确输出信息,即标准输出(standard output) 的信息,而对于错误的输出信息,即标准错误输出(stdandard error) 信息没有直接处理能力。而后将标准输出传递给下一个命令,作为下一个命令的标准输入(standard input)。

如上图所示 command1 的标准(正确)输出作为 command2 的标准输入,然后 comand2 的标准(正确)输出作为 comand3 的输入 ,comand3 的输出直接显示在屏幕。下面是一个比较简单的例子:

1
2
3
4
5
6
7
8
9
[user1@study ~]$ ls | grep file
file
file2.txt
file3.txt
file.bak
file.txt
[user1@study ~]$ ls | grep file | grep [0-9]
file2.txt
file3.txt

管道右边的命令,必须能够接收标准输入流命令才行,否则无法正常进行:

1
2
3
4
[user1@study ~]$ ls | touch
touch: missing file operand
Try 'touch --help' for more information.
[user1@study ~]$

管道只处理前一个命令的标准输出,不处理标准错误输出:

1
2
3
[user1@study ~]$ ls file_abc | grep 'No such file or directory'
ls: cannot access file_abc: No such file or directory
[user1@study ~]$

如果既想处理前一个命令的标准输出,又想要处理标准错误输出该怎么办呢?这时可以用 |& 来解决,它实际上是对 2>&1 | 的缩写

1
2
3
4
5
6
7
[user1@study ~]$ ls abcfile | grep -i -o -w 'no' 
ls: cannot access abcfile: No such file or directory
[user1@study ~]$ ls abcfile |& grep -i -o -w 'no'
No
[user1@study ~]$ ls abcfile 2>&1 | grep -i -o -w 'no'
No
[user1@study ~]$

管道和重定向的区别

  • 管道:
    • 左边的命令应该有标准输出 | 右边的命令应该接受标准输入
    • 管道两边必须是 shell 命令,触发了两个子进程,两边命令都各自触发了一个子进程
  • 重定向:
    • 左边的命令应该有标准输出 > 右边只能是文件
    • 左边的命令需要接受标准输入 < 右边需要能产生标准输出进程或文件
    • 重定向是在一个进程内执行的
有钱任性,请我吃包辣条
0%