上一篇我们聊了文件操作和文本处理,那是 shell 工程师日常使用频率最高的一组命令。这一篇换个主题,聊聊另外三块同样重要的内容:进程管理、网络工具、系统信息。
这三块是日常运维的另一半。写脚本时除了处理文件,你大概率还要跟运行中的程序打交道------查进程、查网络、查系统状态。掌握好这一篇的命令,你的 shell 脚本就能覆盖 90% 的运维场景。
一、三类工具的共同点
进程、网络、系统信息这三类命令看似不相关,其实有一个共同特点:它们都在"观察和控制运行中的系统"。跟上一篇的"操作静态文件"不同,这里的命令往往:
- 输出的内容是动态变化的(每秒都在刷新)
- 跨进程、跨主机、跨网络边界
- 误用可能影响线上服务(kill 错进程、网络断连)
所以这一篇的命令要更谨慎地使用。我们按"观察 → 控制"的顺序来:先学怎么看,再学怎么动。
二、进程管理
进程是 shell 工程师打交道最多的实体。你的脚本启动后是一个进程,调用外部命令会创建子进程,部署的服务也是进程。理解进程的状态和它们之间的关系,是写出可靠脚本的基础。
2.1 ps:看一眼进程
ps 是 process status 的缩写,它把当前系统里的进程列出来。语法是 ps [options]。
最常用的几个组合:
perl
# 查看当前用户的所有进程
ps
# 查看所有进程(包括其他用户)
ps -ef
# 或者
ps aux
# 查找特定进程
ps -ef | grep nginx
ps -ef 和 ps aux 是两种主流写法,前者是 System V 风格,后者是 BSD 风格。两者的输出列不同,但都能用。日常推荐 ps -ef,跨平台兼容性好。
输出字段解读(以 ps -ef 为例):
swift
UID PID PPID C STIME TTY STAT TIME CMD
root 1 0 0 8月22 ? 00:00:01 /sbin/init
root 123 1 0 8月22 ? 00:00:00 nginx: master process
- UID:进程所有者
- PID:进程 ID
- PPID:父进程 ID
- STAT:进程状态(R 运行、S 睡眠、Z 僵尸、T 停止等)
- CMD:启动命令
几个实用的查询组合:
perl
# 按进程名过滤
ps -ef | grep -v grep | grep nginx
# 按用户过滤
ps -u www-data
# 按 PID 查详情
ps -p 1234 -o pid,ppid,cmd
# 自定义输出列
ps -eo pid,ppid,user,pcpu,pmem,cmd --sort=-pcpu | head
最后一行尤其常用------找出最占 CPU 的几个进程。
2.2 top / htop:动态看
ps 是一次的快照,top 是动态刷新的"实时监控器"。
css
top # 启动 top,默认 3 秒刷新
top -p 1234 # 只监控指定 PID
top -u www-data # 只监控指定用户
top -n 1 # 只刷新一次(适合脚本里用)
top 的输出分两部分:上半部分是系统整体(负载、CPU、内存),下半部分是进程列表。几个看重点:
- load average:三个数字分别是 1 分钟、5 分钟、15 分钟的平均负载
- %Cpu(s):用户态、内核态、空闲 CPU 占比
- KiB Mem:总内存、已用、空闲、缓存
top 里几个交互命令:
- P:按 CPU 排序
- M:按内存排序
- k:kill 进程(输入 PID)
- 1:展开多核 CPU
- q:退出
htop 是 top 的升级版 ------支持鼠标、彩色、树形视图。如果有 htop 就用 htop,体验比 top 好太多。安装:apt install htop 或 yum install htop。
2.3 jobs / fg / bg:前后台切换
这是 shell 自己的进程管理,跟操作系统的进程管理是分开的。
bash
# 启动一个后台任务
sleep 100 &
# 查看当前 shell 的后台任务
jobs
# 输出:[1]+ Running sleep 100 &
# 把后台任务切到前台
fg %1
# 把前台任务切到后台(先用 Ctrl+Z 暂停)
# 按 Ctrl+Z
bg %1
& 是"后台启动"。jobs 列出当前 shell 的后台任务(注意是当前 shell,子 shell 的任务看不到)。
关键概念 :前台任务会占用终端,你按 Ctrl+C 它就死了。后台任务不占用终端,Ctrl+C 不会影响它。所以长时间运行的任务应该用 & 放后台。
但放后台的任务在终端关闭时可能被 SIGHUP 杀掉------解决方案是 nohup,后面讲。
2.4 nohup:脱离终端
bash
nohup long_running.sh &
nohup 让进程忽略 SIGHUP 信号------终端断开时不会被杀,& 让它在后台跑。这是"启动一个能跑很久的服务"的标准组合。
输出默认会写到 nohup.out,除非你重定向:
bash
nohup long_running.sh > /var/log/myservice.log 2>&1 &
注意 nohup 不是万能的,它只处理 SIGHUP,不处理其他信号。真正的守护进程需要用 systemd 或专门的 daemon 工具。
2.5 kill / pkill / killall:发信号
kill 的本意是"发信号",不是"杀进程"------只是发 TERM 信号是它的默认行为。前面信号那篇讲过细节,这里只讲实战用法。
bash
# 发 TERM(默认,优雅退出)
kill 1234
# 发 KILL(强制,9 号信号)
kill -9 1234
# 发 HUP(重载配置,常见于 nginx/apache)
kill -HUP 1234
# 按名字杀
pkill nginx
# 强杀所有匹配
pkill -9 nginx
# 杀整个进程组(比如杀某个脚本启动的所有子进程)
kill -- -1234 # 注意负号
几个安全实践:
- 永远先 kill(默认 TERM),给进程 5-10 秒清理时间,再 kill -9
- pkill 之前先用 pgrep 看看会杀哪些进程:
pgrep nginx先确认 - 不要 pkill 名字太通用的进程(比如 pkill sh 会杀掉很多不相关的东西)
2.6 nice / renice:调整优先级
nice 调整进程优先级(niceness 值),范围是 -20 到 19。值越大优先级越低,越不抢CPU。普通用户只能调正值(降低优先级),root 可以调任何值。
bash
# 启动时设置优先级
nice -n 19 long_running.sh &
# 调整已运行进程的优先级
renice -n 10 -p 1234
什么时候用:批量任务、定时任务、备份脚本等不影响主业务的进程,调高 nice 值让它们礼貌地跑。
三、网络工具
shell 工程师的另一大任务是跟网络打交道------调 API、传文件、查连接、查 DNS。这一节把最常用的网络工具过一遍。
3.1 ping:基本连通性
r
# 简单 ping
ping example.com
# 限制次数
ping -c 4 example.com
# 设置间隔
ping -i 0.5 example.com
# 不解析域名(纯 IP ping)
ping -n 8.8.8.8
ping 的实战用法:
bash
# 等待服务启动(轮询 + ping)
until ping -c 1 -W 1 myservice.local &>/dev/null; do
sleep 1
done
echo "服务已就绪"
但注意 ping 不一定反映服务的真实状态,主机能 ping 通不代表端口能连上(防火墙可能禁 ICMP)。测试服务可用性用 curl 或 nc。
3.2 curl / wget:HTTP 客户端
curl 和 wget 都是 HTTP 客户端,但curl 更通用,wget 更专注下载。
bash
# 简单 GET
curl https://example.com
# 跟随重定向
curl -L https://example.com
# 输出 HTTP 头
curl -I https://example.com
# POST 请求
curl -X POST -d 'name=alice&age=25' https://api.example.com/users
# JSON POST
curl -X POST -H 'Content-Type: application/json' \
-d '{"name":"alice","age":25}' \
https://api.example.com/users
# 携带 cookie
curl -b cookies.txt -c cookies.txt https://example.com
# 显示详细请求
curl -v https://example.com
# 下载文件
curl -O https://example.com/file.zip
curl -o myfile.zip https://example.com/file.zip
curl 的常用选项:
- -X:指定 HTTP 方法
- -H:自定义 header
- -d:请求体
- -o:输出到文件
- -O:保持远程文件名
- -I:只显示响应头
- -L:跟随重定向
- -k:忽略证书错误(不推荐生产用)
- -s:静默模式(不显示进度)
- -v:详细模式(调试用)
curl 的几个实战组合:
bash
# 测试 API 健康
curl -sf https://api.example.com/health || echo "API 不健康"
# 调 API 并解析 JSON(配合 jq)
curl -s https://api.example.com/users | jq '.[] | .name'
# 下载并限速
curl --limit-rate 1M -O https://example.com/bigfile.zip
# 跟踪重定向
curl -L -o file.html https://bit.ly/shortlink
-f 是"失败时返回非零" 。配合 set -e 用,curl 失败时脚本会立即退出。这是 shell 脚本里调 API 的标准做法。
wget 跟 curl 的取舍:curl 功能更强、支持更多协议(FTP、SFTP、SMTP 等),wget 专注 HTTP 下载、递归下载更简单。日常 API 调用用 curl,批量下载用 wget。
3.3 ssh / scp / rsync:远程操作
ssh 是最常用的远程登录工具,scp 是基于 ssh 的文件传输,rsync 是更强大的同步工具。
ruby
# 登录远程
ssh user@host
# 指定端口
ssh -p 2222 user@host
# 执行远程命令
ssh user@host 'ls -la'
# 拷贝文件到远程
scp file.txt user@host:/remote/path/
# 从远程拷贝文件
scp user@host:/remote/file.txt ./
# 拷贝目录
scp -r dir/ user@host:/remote/path/
ssh 的几个实用技巧:
perl
# 免密码登录(用密钥)
ssh-keygen -t ed25519 # 生成密钥
ssh-copy-id user@host # 上传公钥
# SSH 配置文件(~/.ssh/config)
Host myserver
HostName 192.168.1.100
User alice
Port 2222
IdentityFile ~/.ssh/work_key
# 配置后直接用别名
ssh myserver
scp file.txt myserver:/tmp/
rsync 比 scp 强大得多------增量同步、保留权限、断点续传。
ruby
# 本地同步
rsync -av src/ dst/
# 远程同步
rsync -av -e ssh src/ user@host:/remote/path/
# 删除目标里多余的文件
rsync -av --delete src/ dst/
# 排除某些文件
rsync -av --exclude='*.tmp' src/ dst/
# 模拟运行(看看会同步哪些文件,但不真做)
rsync -avn src/ dst/
rsync 的关键选项:
- -a:归档模式(保留所有属性,等于 -rlptgoD)
- -v:详细输出
- -z:传输时压缩
- --progress:显示进度
- --delete:删除目标端多余文件
- -n:模拟运行(dry-run)
rsync 的经典用法:
bash
# 备份脚本(每天跑)
rsync -av --delete /data/ /backup/data/
# 部署到多台服务器
for host in server1 server2 server3; do
rsync -az -e ssh ./app/ $host:/opt/app/
done
3.4 ss / netstat:网络连接
ss 是新一代的网络连接查看工具(替代 netstat)。netstat 在新系统上逐步被淘汰------如果系统有 ss 就用 ss。
bash
# 查看所有 TCP 连接
ss -t
# 查看所有监听端口
ss -tlnp
# 查看所有 UDP 连接
ss -u
# 查看建立的连接
ss -t state established
# 按端口过滤
ss -tlnp 'sport = :80'
# 统计各状态的连接数
ss -tan | awk '{print $1}' | sort | uniq -c
ss 跟 netstat 的输出差别 :netstat 把"地址"和"端口"合成一列,ss 分开两列。机器可读性 ss 更好,awk 解析更简单。
3.5 dig / nslookup / host:DNS 查询
csharp
# 查询 A 记录
dig example.com
# 简短输出
dig +short example.com
# 查询特定记录类型
dig example.com MX
dig example.com TXT
# 指定 DNS 服务器
dig @8.8.8.8 example.com
# 反向 DNS(IP 查域名)
dig -x 8.8.8.8
host 是更简洁的版本,输出更友好:
host example.com
host 8.8.8.8
nslookup 是最老的 ,现在一般不推荐用。dig 输出的信息最全,是排查 DNS 问题时的首选。
3.6 nc / ncat:网络瑞士军刀
nc(netcat)是一个底层网络工具,可以读写 TCP/UDP 连接。调试网络问题时特别有用。
bash
# 监听端口(作为 server)
nc -l 12345
# 连接端口(作为 client)
nc example.com 80
# 端口扫描
nc -zv example.com 80-100
# 文件传输(简单的两端)
# 接收端
nc -l 12345 > file.txt
# 发送端
nc host 12345 < file.txt
nc 的实战用法:
bash
# 测试端口是否开放
nc -zv example.com 80
# 调试 HTTP 请求(手动发)
printf "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n" | nc example.com 80
# 等待服务启动(比 ping 更靠谱)
until nc -z myservice 8080; do
sleep 1
done
四、系统信息
最后一组命令是查系统状态------查内核、查内存、查磁盘、查用户。日常脚本里经常用这些做"环境检查"。
4.1 uname:系统信息
bash
# 系统信息
uname -a
# 单独看内核
uname -r
# 单独看主机名
uname -n
4.2 hostname:主机名
bash
hostname # 显示主机名
hostname -I # 显示所有 IP 地址
hostname -f # 显示完整域名(FQDN)
4.3 date / uptime:时间信息
bash
date # 当前时间
date +%Y-%m-%d # 格式化输出
date +%s # Unix 时间戳
date -d "2024-01-15" # 解析字符串为日期
date -d "@1704067200" # 时间戳转日期
date -u # UTC 时间
date -R # RFC 2822 格式
uptime # 系统运行时间和负载
date 在脚本里的常见用法:
bash
# 日志文件加日期后缀
log_file="app_$(date +%Y%m%d).log"
# 计算时间差
start=$(date +%s)
do_something
end=$(date +%s)
echo "耗时 $((end - start)) 秒"
# 7 天前的时间
date -d "7 days ago" +%Y-%m-%d
4.4 who / whoami / id:用户信息
bash
whoami # 当前用户名
id # 详细信息(UID、GID、组)
who # 登录的用户
w # 更详细的登录信息
id 在脚本里最常用------判断当前是不是 root:
bash
if [ "$(id -u)" -ne 0 ]; then
echo "请用 root 权限运行"
exit 1
fi
4.5 free:内存
bash
free # 内存使用情况
free -h # 人类可读
free -m # 以 MB 为单位
free -s 5 # 每 5 秒刷新
输出字段:total 总内存、used 已用、free 空闲、shared 共享、buff/cache 缓存、available 可用。注意 available 才是"真正能用的" ------buff/cache 算上才准。
4.6 df / du:磁盘
上一篇讲过 df 和 du 的基础用法,这里补充几个组合:
bash
# 看磁盘 IO 统计
iostat
# 看文件系统类型
df -T
# 找出最大的 5 个文件
find /var -type f -exec du -h {} + | sort -rh | head -5
# 找出大于 1G 的文件
find / -type f -size +1G 2>/dev/null
4.7 lscpu / lsblk / lspci:硬件信息
bash
lscpu # CPU 信息
lsblk # 块设备(磁盘)信息
lspci # PCI 设备
lsusb # USB 设备
这些命令在排查硬件问题时偶尔用到,日常脚本里用得不多。
4.8 /proc 文件系统
Linux 把进程和内核信息暴露在 /proc 下------很多命令的输出其实就是从这里读的。
bash
# 当前进程信息
cat /proc/self/status
# CPU 信息
cat /proc/cpuinfo
# 内存信息
cat /proc/meminfo
# 系统启动时间
cat /proc/uptime
# 进程的命令行
cat /proc/1234/cmdline
脚本里读 /proc 比调用命令更高效------不用 fork 进程。比如判断系统启动时间:
ini
uptime_seconds=$(awk '{print $1}' /proc/uptime)
五、总结
这一篇我们覆盖了另外三组常用命令:
- 进程管理:ps、top、jobs、fg、bg、nohup、kill、pkill、nice
- 网络工具:ping、curl、wget、ssh、scp、rsync、ss、dig、nc
- 系统信息:uname、hostname、date、uptime、who、id、free、df
跟上一篇一样,重点不是记住每个命令的参数,而是知道什么时候用哪个、怎么组合。
下一篇是这个系列的最后一部分------讲归档、压缩、权限、用户、还有几个进阶工具(xargs、tee、cron、screen/tmux)。这是 shell 工具箱的最后一组拼图,写完这三篇,你对 shell 日常命令的掌握就完整了。