首页 Shell 管道
文章
取消

Shell 管道

用法

将上一个命令的标准输出作为下一个命令的标准输入,这两个命令之间使用|管道连接符相连。

如,查找是否存在用户 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"
本文由作者按照 CC BY 4.0 进行授权

Shell 重定向

Shell subshell