17 管道 (从新手到菜鸟的Linux教程)
要我说起来呢,shell编程的精髓有两点:一点是它奠定了脚本语言的基础,并实现了交互式命令;另一点就是管道。管道的作用正如其名,就是将程序“连接”在一起,从而简化了许许多多重复繁杂的工作。这一点上,windows cmd就要略逊几筹了。
先举个例子:
$ echo 'Hello World!' | cat
Hello world!
我们知道 cat
的作用是将文件重定向到标准输出(这里的 文件 可以是磁盘上的内容,也可以是 Unix/Linux 意义下各种设备被映射到的操作对象),但是这次 cat
之后没有跟着任何参数,所以 cat
是将什么内容重定向了呢?答案就是在管道符 |
前的 echo 'Hello World!'
命令里。
管道符的使用通常是这样的
command_A | command_B
管道符将 command_A
的标准输出和标准错误 参考这里 定向到 command_B
的标准输入上(这句话似乎不能再通俗了)。考虑到 bash 里所有的变量都是字符串类型,于是利用这个语言特性可以很方便地将信息在命令间传递。
再举几个例子:
$ cat ~/.bashrc | less
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
作用是先将 ~/.bashrc
的内容输出到标准输出,然后由管道符定向到 less
的输入,于是就可以用 less
愉快地查看了。我同学吐槽我,说你直接 less ~/.bashrc
不就完了= =
下一个例子
$ ps -A | grep pts
1793 pts/0 00:00:00 zsh
1890 pts/1 00:01:16 hexo
4170 pts/0 00:00:00 ps
4171 pts/0 00:00:00 grep
上一篇介绍 grep
的时候我们是把目标文件(被匹配的文件)作为参数传给 grep
,但是它其实也资瓷从标准输入读入目标内容啊!所以就可以用管道符把 ps -A
的结果(还记得 ps
的功能吗)传递给 grep
——事实上,至少我在平时看进程的时候还是很常用这个搭配的。
但是这样是不行的
$ ls
file
$ ls | rm
rm: missing operand
Try 'rm --help' for more information.
黑人问号?不是说管道符可以把输出重定向给下一个命令的标准输入吗?为什么 rm
说没收到操作数呢?这是因为 rm
要删除的文件名来自于命令后面的参数,而不是来自标准参数啦……
那么怎么才能把输出内容作为命令参数呢?哈哈哈,那就要用到 xargs
了,戳 >这里< 。