用法
将上一个命令的标准输出作为下一个命令的标准输入,这两个命令之间使用|
管道连接符相连。
如,查找是否存在用户 zhang3:cat /etc/passwd | grep 'zhang3'
或grep 'zhang3' /etc/passwd
。
注意:管道只会将前一个命令的 stdout 作为后一个命令的 stdin,而 stderr 则不会被后一个命令读取!
如果要让后一个命令获取前一个命令的 stdout 和 stderr,则:cat /etc/passwd 2>&1 | grep 'zhang3'
。
踩坑
当 shell 解释器遇到管道时,会 fork 两个进程来执行;
比如 foo | bar
,一个进程执行 foo,另一个执行 bar;
这意味着不能在 foo 或 bar 中修改当前进程的数据,如变量;
所以像这种代码是无效的,因为管道后面的代码在独立的进程执行:
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
n=0
# 统计行数
cat /etc/systemd/system.conf | while read line; do
((n++))
done
echo "$n" # 将会输出0
像这种情况,建议改为 I/O 重定向形式,还可以减少 fork 调用:
1
2
3
4
5
6
7
8
9
#!/bin/bash
n=0
while read line; do
((n++))
done </etc/systemd/system.conf
echo "$n"