Linux Shell管道详解
Linux 管道使用竖线
|
连接多个令,这被称为管道符。Linux 管道的具体语法格式如下:command1 | command2
command1 | command2 [ | commandN... ]
当在两个令之间设置管道时,管道符|
左边令的输出就变成了右边令的输入。只要个令向标准输出写入,而第二个令是从标准输入读取,那么这两个令就可以形成一个管道。大部分的 Linux 令都可以用来形成管道。这里需要注意,command1 必须有正确输出,而 command2 必须可以处理 command2 的输出结果;而且 command2 只能处理 command1 的正确输出结果,不能处理 command1 的错误信息。
为什么使用管道?
我们先看下面一组令,使用 mysqldump(一个数据库备份程序)来备份一个叫做 wiki 的数据库:
mysqldump -u root -p '123456' wiki > /tmp/wikidb.backup
gzip -9 /tmp/wikidb.backup
scp /tmp/wikidb.backup username@remote_ip:/backup/mysql/
上述这组令主要做了如下任务:
- mysqldump 令用于将名为 wike 的数据库备份到文件 /tmp/wikidb.backup;其中
-u
和-p
选项分别指出数据库的用户名和密码。 - gzip 令用于压缩较大的数据库文件以节省磁盘空间;其中
-9
表示最慢的压缩速度最好的压缩效果。 - scp 令(secure copy,安全拷贝)用于将数据库备份文件到 IP 地址为 remote_ip 的备份服务器的 /backup/mysql/ 目录下。其中
username
是登录远程服务器的用户名,令执行后需要输入密码。
上述三个令依次执行。然而,如果使用管道的话,你就可以将 mysqldump、gzip、ssh 令相连接,这样就避免了创建临时文件 /tmp/wikidb.backup,而且可以同时执行这些令并达到相同的效果。
使用管道后的令如下所示:
mysqldump -u root -p '123456' wiki | gzip -9 | ssh username@remote_ip "cat > /backup/wikidb.gz"
这些使用了管道的令有如下特点:
令的语法紧凑并且使用简单。
通过使用管道,将三个令串联到一起就完成了远程 mysql 备份的复杂任务。
从管道输出的标准错误会混到一起。
上述令的数据流如下图所示:

重定向和管道的区别
乍看起来,管道也有重定向的作用,它也改变了数据输入输出的方向,那么,管道和重定向之间到底有什么不同呢?简单地说,重定向操作符>将令与文件连接起来,用文件来接收令的输出;而管道符|将令与令连接起来,用第二个令来接收个令的输出。如下所示:
command > file
command1 | command1
有些读者在学习管道时会尝试如下的令,我们来看一下会发生什么:
command1 > command2
答案是,有时尝试的结果将会很糟糕。这是一个实际的例子,一个 Linux 系统管理员以超级用户(root 用户)的身份执行了如下令:
cd /usr/bin
ls > less
条令将当前目录切换到了大多数程序所存放的目录,第二条令是告诉 Shell 用 ls 令的输出重写文件 less。因为 /usr/bin 目录已经包含了名称为 less(less 程序)的文件,第二条令用 ls 输出的文本重写了 less 程序,因此破坏了文件系统中的 less 程序。这是使用重定向操作符错误重写文件的一个教训,所以在使用它时要谨慎。
Linux管道实例
【实例1】将 ls 令的输出发送到 grep 令:
上述令是查看文件 log.txt 是否存在于当前目录下。[c.biancheng网站站点" rel="nofollow" />
log.txt
我们可以在令的后面使用选项,例如使用
-al
选项:管道符[c.biancheng网站站点" rel="nofollow" />
log.txt
|
与两侧的令之间也可以不存在空格,例如将上述令写作ls -al|grep log.txt
;然而我还是在管道符|
和两侧的令之间使用空格,以增加代码的可读性。我们也可以重定向管道的输出到一个文件,比如将上述管道令的输出结果发送到文件 output.txt 中:
[c.biancheng网站站点" rel="nofollow" />
cat /var/log/message | less
【实例3】查看指定程序的进程运行状态,并将输出重定向到文件中。
[c.biancheng网站站点" rel="nofollow" />
[c.biancheng网站站点" rel="nofollow" />
[c.biancheng网站站点" rel="nofollow" />
command1 < input.txt | command2 command1 < input.txt | command2 -option | command3
例如,使用 tr 令从 os.txt 文件中获取输入,然后通过管道将输出发送给 sort 或 uniq 等令:
[c.biancheng网站站点" rel="nofollow" />
command1 | command2 | ... | commandN > output.txt command1 < input.txt | command2 | ... | commandN > output.txt
【实例1】使用 mount 令显示当前挂载的文件系统的信息,并使用 column 令格式化列的输出,将输出结果保存到一个文件中。
[c.biancheng网站站点" rel="nofollow" />
[c.biancheng网站站点" rel="nofollow" />