「速通Shell」常用命令(中)——进程、网络与系统信息

上一篇我们聊了文件操作和文本处理,那是 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 htopyum 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 日常命令的掌握就完整了。

相关推荐
YuSun_WK7 小时前
shell脚本
shell·脚本
柒号华仔3 天前
「速通Shell」Shell 脚本测试详解
shell
柒号华仔4 天前
「速通Shell」Shell 脚本模块化
shell
柒号华仔5 天前
「速通Shell」Shell编程的错误处理与日志
shell
柒号华仔6 天前
「速通Shell」Shell 数组、关联数组与 mapfile
shell
苏灿烤鱼8 天前
一套进程代替八件套,桌面更稳还是单点更大
linux·github·shell
茶本无香8 天前
通用报表自动化框架:Java调用Shell传参执行PostgreSQL SQL模板
java·sql·postgresql·shell
柒号华仔9 天前
「速通Shell」Shell 循环与遍历
shell·编程语言
十里春风_jzh10 天前
Tabby 修改版:更美观的现代终端
shell·tabby