竖线 |:管道、按位或、掩码组合

一、前言

在 Linux 学习过程中,绝大多数人都会被同一个符号 | 搞混淆:

命令行里它是管道、代码里它是位运算、系统函数参数里它是标志叠加。

很多人疑惑:明明都是竖线,为什么功能完全不同?

标准答案:符号本身没有任何意义,解析环境决定意义。

Shell 解释器、C语言编译器、Linux 内核,三套完全不同的解析规则,互不干涉。


二、Shell 终端中:| 是「管道符」

1. 作用

Shell 里的|和数学运算没有任何关系。

它的唯一作用:把前一个命令的输出,交给后一个命令当输入,实现进程数据接力。

2. 特点

  • 多个命令同时运行(流水线并发)

  • 数据在内存流动,不产生临时文件

  • 下游依赖上游输出,实现链式数据处理

3. 示例

bash 复制代码
ls -l | grep txt | wc -l
cat app.log | grep error | awk '{print $5}' | sort | uniq -c

4. Shell 极易混淆四组符号

  • | 管道:数据接力

  • || 逻辑或:前命令失败,才执行后命令

  • && 逻辑与:前命令成功,才执行后命令

  • & 后台并行:两个命令独立同时跑


三、编程语言中:| 是「按位或运算符」

在 C / C++ / Python / Java 中,| 是标准 二进制位运算,纯粹数学计算,和管道无关。

1. 运算规则

有1则1,全0才0,逐位独立计算。

cs 复制代码
0b0010 | 0b0100 = 0b0110

2. 基础示例

cs 复制代码
int a = 2;    // 0010
int b = 4;    // 0100
int res = a | b; // 0110 = 6

四、系统编程中:| 是「掩码叠加」(最容易混淆)

你写 open、socket、epoll 时看到的:

O_WRONLY | O_CREAT | O_TRUNC

这里绝对不是管道,是标准按位或运算。

1. 内核 flag 本质

Linux 所有 flag 本质都是 整数掩码:

每一个二进制 bit 代表一个开关功能。

内核宏定义简化如下:

cs 复制代码
#define O_WRONLY  0001  // 只写
#define O_CREAT   0100  // 不存在则创建
#define O_TRUNC   1000  // 存在则清空

2. 按位或叠加多个功能

使用 | 可以同时开启多个开关:

cs 复制代码
  0001  O_WRONLY
| 0100  O_CREAT
| 1000  O_TRUNC
= 1101

最终结果同时拥有:只写、创建、清空三种能力。

3. 为什么不能用加号 +

加法会进位、会丢 bit,会导致功能错乱;

按位或只置1、不进位,是唯一安全的叠加方式。

cs 复制代码
#define A 0b0010
#define B 0b0010

A + B = 0b0100  // 错误,进位丢失
A | B = 0b0010  // 正确,保留开关状态

4. 经典系统调用统一写法

cs 复制代码
// 文件打开
open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);

// 非阻塞 socket
socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);

// epoll 多事件监听
ev.events = EPOLLIN | EPOLLOUT;

五、一张表彻底终结混淆

使用场景 符号含义 本质 示例
Shell 命令行 管道符 进程数据流传递 `ls
代码数值运算 按位或 二进制数学运算 `x = a
系统函数 flag 掩码按位或 叠加多个功能开关 `O_WRONLY

六、最终总结

  • 终端里的 | 是管道,负责命令数据流接力;

  • 代码里的 | 是按位或,负责二进制运算;

  • open/socket 参数里的 | 是掩码叠加,用来组合多个系统功能;

  • 永远不要用 + 代替 | 组合系统标志;

  • 符号不决定功能,环境决定一切。

相关推荐
逃逸线LOF2 小时前
服务网关Gateway
java·运维·gateway
Funlang2 小时前
给机器写的 JavaScript 造个笼子
开发语言·javascript·ecmascript
普通人63 小时前
PHP文件读写完全指南
开发语言·php·1024程序员节
灿飞屋3 小时前
Kotlin与Java虚拟机四:函数
java·python·kotlin·安卓·android jetpack
坤坤子吖3 小时前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习
阡陌数智3 小时前
Claude API新版本重大变更与安全升级指南
java·linux·安全
一晌小贪欢4 小时前
Python基础:第 09 篇 · while 循环:重复直到不满足
开发语言·c++·python·数据可视化·面向对象·python办公
xiaoye-duck4 小时前
《C++ 项目:手写大模型接入 SDK》LLMManager架构设计与实现
开发语言·网络·c++·语言模型
一条大祥脚5 小时前
CuTe 与 CuTe DSL:从 C++ 模板元编程到 Python DSL 的 GPU 编程演进
开发语言·c++·python·cutlass·cute·cute dsl
学长毕设5 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端