管道(pipe)
| 把左边命令的输出作为右边命令的输入。
命令A | 命令B
# 命令A 的 stdout → 命令B 的 stdin
示例
# 逐行显示 PATH 中的每个目录
echo $PATH | tr ':' '\n'
# 查找包含 "error" 的日志行
cat app.log | grep "error"
# 统计文件行数
cat names.txt | wc -l
# 排序并去重
cat list.txt | sort | uniq
管道可以连续拼接,如
A | B | C,前一个命令的输出依次传给下一个。
重定向(redirect)
每个命令都有三个数据流:
| 文件描述符 | 名称 | 说明 |
|---|---|---|
0 | stdin(标准输入) | 命令读取输入的来源,默认是键盘 |
1 | stdout(标准输出) | 命令的正常输出,默认是终端屏幕 |
2 | stderr(标准错误) | 命令的错误/警告信息,默认也是终端屏幕 |
常用写法
# stdout 写入文件(覆盖)
echo "hello" > output.txt
# stdout 追加到文件
echo "hello" >> output.txt
# stderr 丢弃(文件不存在时不报错)
grep -n "error" app.log 2>/dev/null
# stdout 和 stderr 都写入文件
command > output.txt 2>&1
# stdout 和 stderr 都丢弃
command > /dev/null 2>&1
/dev/null
特殊文件,写入的内容全部丢弃,读取时立即返回 EOF。常见用途:
# 丢弃错误输出:搜索多个文件,不存在的文件静默跳过
grep -n ".local/bin" ~/.zshrc ~/.zprofile ~/.zshenv 2>/dev/null
# 丢弃所有输出:只关心命令是否成功(退出码)
command > /dev/null 2>&1 && echo "成功"
/dev/null是 Linux 中的”黑洞”,常配合重定向用来静默不需要的输出。
文本处理
以下命令常与管道组合使用。
tr
字符级别的替换、删除或压缩。从 stdin 读取,输出到 stdout。
常用参数
| 参数 | 说明 |
|---|---|
-d | 删除指定字符 |
-s | 压缩连续重复字符为一个 |
示例
# 替换:冒号换成换行
echo $PATH | tr ':' '\n'
# 替换:小写转大写
echo "hello" | tr 'a-z' 'A-Z'
# 删除:去掉所有数字
echo "abc123def" | tr -d '0-9'
# 压缩:连续重复字符合并为一个
echo "heeelllooo" | tr -s 'a-z'
grep
文本搜索工具,按行过滤匹配的内容。
常用参数
| 参数 | 说明 |
|---|---|
-i | 忽略大小写 |
-v | 反向匹配,排除含关键词的行 |
-n | 显示行号 |
-c | 只输出匹配的行数 |
-r | 递归搜索目录 |
-l | 只输出包含匹配的文件名 |
示例
# 搜索包含 "error" 的行
cat app.log | grep "error"
# 忽略大小写搜索
cat app.log | grep -i "error"
# 排除包含 "debug" 的行
cat app.log | grep -v "debug"
# 显示行号
cat app.log | grep -n "error"
# 递归搜索目录中的文件
grep -r "TODO" ./src
# 只列出包含匹配的文件名
grep -rl "TODO" ./src
wc
统计文件的行数、单词数、字节数。
常用参数
| 参数 | 说明 |
|---|---|
-l | 统计行数 |
-w | 统计单词数 |
-c | 统计字节数 |
示例
# 统计文件行数
cat names.txt | wc -l
# 统计文件单词数
cat readme.md | wc -w
# 直接统计文件(输出 行数/单词数/字节数)
wc file.txt
sort
对文本行排序。默认按字典序升序。
常用参数
| 参数 | 说明 |
|---|---|
-r | 降序排列 |
-n | 按数值大小排序 |
-k <列> | 按指定列排序 |
-u | 排序并去重(等同于 sort + uniq) |
示例
# 默认升序
cat names.txt | sort
# 降序
cat names.txt | sort -r
# 按数值大小排序
cat scores.txt | sort -n
# 按第 2 列排序
cat data.txt | sort -k 2
# 排序并去重
cat names.txt | sort -u
uniq
去除相邻的重复行。通常先用 sort 排序后再去重。
常用参数
| 参数 | 说明 |
|---|---|
-c | 在每行前显示该行出现的次数 |
-d | 只显示重复的行 |
-u | 只显示不重复的行 |
示例
# 排序后去重(经典组合)
cat names.txt | sort | uniq
# 统计每行出现次数
cat names.txt | sort | uniq -c
# 只显示重复的行
cat names.txt | sort | uniq -d
head
显示文件的开头部分,默认输出前 10 行。
常用参数
| 参数 | 说明 |
|---|---|
-n <行数> | 指定显示的行数 |
-c <字节数> | 指定显示的字节数 |
示例
# 显示文件前 10 行(默认)
head file.txt
# 显示文件前 5 行
head -n 5 file.txt
# 显示文件前 100 字节
head -c 100 file.txt
# 配合管道:查看占用 CPU 最高的前 3 个进程
ps aux | sort -k 3 -rn | head -n 3
# 同时查看多个文件的开头
head -n 3 file1.txt file2.txt
提示:与
head对应的是tail,用于查看文件末尾。tail -f file可以实时追踪文件新增内容(常用于查看日志)。
sed
流编辑器(Stream Editor),逐行读取文本,按规则完成替换、删除、插入等编辑后输出。默认只输出结果,不修改原文件。
常用参数
| 参数 | 说明 |
|---|---|
-n | 静默模式,只输出被 p 命令处理的行 |
-i | 直接修改原文件(macOS 需写成 -i '') |
-e | 指定多个编辑命令 |
-E | 使用扩展正则表达式 |
常用编辑命令
| 命令 | 说明 |
|---|---|
s/old/new/ | 替换每行第一个匹配 |
s/old/new/g | 替换每行所有匹配(g = global) |
d | 删除行 |
p | 打印行(常配合 -n) |
i | 在行前插入 |
a | 在行后追加 |
示例
# 替换每行第一个 foo 为 bar(输出到屏幕,不改原文件)
sed 's/foo/bar/' file.txt
# 替换每行所有的 foo
sed 's/foo/bar/g' file.txt
# 直接修改文件本身
sed -i 's/foo/bar/g' file.txt # GNU sed(Linux)
sed -i '' 's/foo/bar/g' file.txt # BSD sed(macOS)
# 只打印第 5~10 行
sed -n '5,10p' file.txt
# 删除第 3 行
sed '3d' file.txt
# 删除所有注释行和空行
sed '/^#/d; /^$/d' config.conf
# 配合管道使用
echo "hello world" | sed 's/world/sed/'
提示:macOS 自带的是 BSD sed,与 Linux 的 GNU sed 在
-i等用法上有差异。三者分工:grep负责找,sed负责改,awk负责按列分析。
进程查看
ps
显示当前系统中的进程快照(某一瞬间的状态)。如需实时监控,用 top 或 htop。
常用参数
BSD 风格(macOS / Linux 通用):
| 参数 | 说明 |
|---|---|
aux | 显示所有用户的全部进程(最常用) |
axo | 自定义输出列,如 ps axo pid,comm,%cpu,%mem |
System V 风格(Linux):
| 参数 | 说明 |
|---|---|
-ef | 显示全部进程(另一种写法) |
-eLf | 显示线程信息 |
输出列含义(ps aux)
| 列 | 说明 |
|---|---|
USER | 进程所属用户 |
PID | 进程 ID(唯一标识) |
%CPU | CPU 占用百分比 |
%MEM | 内存占用百分比 |
VSZ | 虚拟内存大小(KB) |
RSS | 实际物理内存大小(KB) |
TT | 控制终端(?? 表示无终端,即后台进程) |
STAT | 进程状态(S=休眠,R=运行中,Z=僵尸进程) |
STARTED | 进程启动时间 |
TIME | 累计占用 CPU 时间 |
COMMAND | 启动该进程的完整命令 |
示例
# 查看所有进程
ps aux
# 查找特定进程(配合 grep)
ps aux | grep nginx
# 在 macOS 上查看所有进程(BSD 风格)
ps ax
# 只显示 PID 和命令名
ps axo pid,comm
# 查看当前终端启动的进程
ps
常见场景
# 1. 检查某个服务是否在运行
ps aux | grep nginx
# 2. 获取 PID 以便结束进程
ps aux | grep my-app
kill <PID>
# 3. 查看占用内存最多的进程
ps aux | sort -k 4 -rn | head -10
# 4. 查看某个用户的所有进程
ps -u sunven
提示:
ps是一次性快照,想持续观察进程变化请使用top(系统自带)或htop(需安装,界面更友好)。
命令查找与信息查询
type
Shell 内建命令,查看命令的类型和实际位置。按优先级识别:别名 → 函数 → 内建命令 → 可执行文件。
常用参数
| 参数 | 说明 |
|---|---|
-a | 列出所有匹配项(别名、函数、可执行文件等) |
示例
# 查看命令的类型和位置
type python3
# 列出所有匹配项(同一命令可能有多处定义)
type -a python3
# python3 is an alias to /usr/local/bin/python3.12
# python3 is /usr/bin/python3
# python3 is /usr/local/bin/python3
which
外部命令,只在 $PATH 目录中搜索可执行文件。无法识别 shell 别名、函数或内建命令。
示例
# 查找可执行文件路径
which python3
# /usr/local/bin/python3
# 查找多个命令
which python3 node git
# 显示所有匹配(非仅第一个)
which -a python3
# /usr/local/bin/python3
# /usr/bin/python3
type vs which
| 场景 | which | type |
|---|---|---|
| 命令是别名 | ❌ 找不到或显示底层命令 | ✅ 显示别名定义 |
| 命令是 shell 函数 | ❌ 找不到 | ✅ 显示函数定义 |
命令是内建命令(如 cd) | ❌ 找不到 | ✅ 正确识别 |
| 多个同名可执行文件 | 默认只返回第一个 | -a 列出全部 |
| 类型 | 外部命令(/usr/bin/which) | Shell 内建命令 |
建议:日常排查问题时优先用
type -a,它理解 shell 的完整命令解析机制,结果更可靠。