Skip to content

Linux 基础与运维

Linux 是 AI 服务器的事实标准操作系统。无论是登录远程 GPU 服务器跑训练、排查网络问题,还是清理磁盘空间,掌握高频 Linux 命令能覆盖 90% 的日常运维需求。本页按进程管理、网络诊断、磁盘 IO、文本处理、文件权限、SSH 与 systemd 六大主题梳理实操要点。

如果你刚从算法研究转向工程落地,本页可以作为快速参考手册。Shell 自动化脚本的内容见 Shell 脚本编程。

从底层硬件到用户可见的应用程序,Linux 采用清晰的分层架构:

命令作用常用示例
ps aux查看所有进程ps aux | grep python 查找 Python 进程
top / htop实时资源监控htop 交互式查看 CPU/内存(推荐安装 htop)
kill -9 <PID>强制结束进程kill -9 12345 杀掉 PID 为 12345 的进程
nice / renice调整进程优先级nice -n 10 python train.py 以低优先级训练,避免抢占
nvidia-smi查看 GPU 状态nvidia-smi 或 watch -n 1 nvidia-smi 每秒刷新

💡 GPU 服务器多人共享时,训练任务务必用 nice -n 10 降低优先级,避免影响在线推理服务。

Terminal window
# 命令末尾加 & 放到后台运行
python train.py &
# nohup:终端关闭后进程不被挂断(SIGHUP)
nohup python train.py > train.log 2>&1 &
# jobs 查看当前终端的后台任务
jobs -l
# fg 把后台任务调回前台
fg %1
Terminal window
kill -15 <PID> # SIGTERM,优雅终止(默认信号),进程可捕获并清理资源
kill -9 <PID> # SIGKILL,强制杀死,不可捕获(可能留下临时文件)
kill -2 <PID> # SIGINT,等同于 Ctrl+C
kill -l # 列出所有信号

⚠️ 训练脚本收到 SIGTERM/SIGINT 时应捕获信号、保存 checkpoint 再退出,避免训练进度丢失。Python 中用 signal 模块注册 handler。

Linux 内核为每个进程维护一个状态,核心转换路径如下:

Linux Process State Transitions

理解状态转换有助于排查”进程卡住”问题:处于 Blocked(等待 I/O 或事件)的进程占用 CPU 为 0%,而 Running 时间过长又无 I/O 则可能是在做纯计算或死循环。

Terminal window
# 查看端口占用(找谁在用 8080 端口)
ss -tlnp | grep :8080 # 现代 Linux 推荐 ss,替代已废弃的 netstat
lsof -i :8080 # 另一种方式,列出占用端口的进程
# 测试 HTTP 接口
curl -X POST http://localhost:8080/predict \
-H "Content-Type: application/json" \
-d '{"text": "hello world"}'
# 抓包分析(排查网络层问题)
sudo tcpdump -i eth0 port 443 -w capture.pcap
# 查看防火墙规则
sudo iptables -L -n
命令作用示例
ping测试网络连通性ping -c 4 8.8.8.8
dig / nslookupDNS 解析dig docs.ifdog.com
traceroute / mtr追踪路由路径mtr -n docs.ifdog.com(mtr 交互式,推荐)
ifconfig / ip addr查看 IP 地址ip addr show eth0
iperf3测带宽吞吐(需两端安装)iperf3 -c <server_ip>
Terminal window
# wget 适合下载大文件、支持断点续传
wget -c https://example.com/large-model.bin
# curl 适合 API 测试和单文件下载
curl -O https://example.com/data.tar.gz
# scp / rsync 远程拷贝
scp -P 29966 model.bin user@server:/data/models/
rsync -avzP --progress ./checkpoints/ user@server:/data/checkpoints/
命令作用示例
df -h查看磁盘整体使用df -h 以人类可读单位显示
du -sh *查看目录大小du -sh /data/* 找出占空间最大的子目录
iostat -x 1查看 IO 吞吐(需 sysstat 包)iostat -x 1 每秒刷新,关注 %util 列
ncdu交互式磁盘分析ncdu /data 直观浏览磁盘占用(需安装)

⚠️ 模型 checkpoint 文件动辄数 GB,定期用 du -sh /data/checkpoints/* 清理过期 checkpoint,避免磁盘打满导致训练中断。

Terminal window
free -h # 查看内存使用(关注 available 列)
nproc # 查看 CPU 核心数
cat /proc/cpuinfo | grep "model name" | head -1
uptime # 查看系统负载(1/5/15 分钟平均负载)

grep、sed、awk 是 Linux 文本处理的三大核心工具,配合管道(pipe)可以完成复杂的数据提取。

Terminal window
# grep:搜索文本
grep -rn "TODO" ./src/ # 递归搜索源码中的 TODO
grep -E "ERROR|WARN" app.log # 用正则匹配 ERROR 或 WARN
grep -c "epoch" training.log # 统计 "epoch" 出现的行数
# sed:流编辑(常用于批量替换)
sed -i 's/old_model/new_model/g' config.yaml # 全局替换文件内容(原地修改)
sed -n '10,20p' large_file.txt # 只打印第 10-20 行
# awk:列处理(分析日志必备)
awk '{print $1, $4}' access.log # 打印第 1、4 列
awk -F',' '{sum+=$3} END {print sum}' data.csv # 按逗号分隔,求第 3 列之和
awk '/loss/{print NR, $0}' train.log # 打印含 "loss" 的行号及内容
Terminal window
# find:查找文件
find /data -name "*.ckpt" -mtime -7 # 最近 7 天修改过的 checkpoint
find . -name "*.pyc" -delete # 删除所有 .pyc 文件
# xargs:把输入转为命令参数
find . -name "*.log" | xargs grep "ERROR" # 在所有日志中搜索 ERROR
# sort + uniq:排序去重
sort data.txt | uniq -c | sort -rn | head # 统计高频行
# cut / paste:列操作
cut -d',' -f1,3 data.csv # 提取第 1、3 列
# wc:统计行数/字数
wc -l training.log # 总行数
# jq:JSON 处理(需安装)
cat response.json | jq '.data[].score' # 提取 JSON 数组字段

管道(pipe) 把前一个命令的输出作为后一个命令的输入,是 Unix 哲学的精髓:

Terminal window
# 组合使用:找出占用 CPU 最高的 5 个进程
ps aux | sort -nrk 3 | head -5
# 组合使用:统计日志中各 HTTP 状态码出现次数
awk '{print $9}' access.log | sort | uniq -c | sort -rn

Linux 文件权限分三组:所有者(owner)、所属组(group)、其他用户(others),每组有读(r=4)、写(w=2)、执行(x=1)三个权限。

Terminal window
# 查看权限
ls -l model.bin
# -rw-r--r-- 1 user group 2.3G Jan 15 model.bin
# 依次:文件类型 | owner(rw-) | group(r--) | others(r--)
# chmod:修改权限
chmod 755 script.sh # rwxr-xr-x(数字模式:7=4+2+1, 5=4+1)
chmod +x deploy.sh # 给所有用户加执行权限
chmod u+w,g-w config.yaml # 符号模式:用户加写权限,组去掉写权限
chmod -R 644 /data/configs/ # 递归修改目录下所有文件
# chown:修改所有者和组
sudo chown user:group /data/model.bin
sudo chown -R alice:researchers /data/lab/
# chgrp:只修改所属组
chgrp developers /shared/code/
权限数字含义
setuid4xxx以文件所有者身份执行(如 passwd 命令)
setgid2xxx以文件所属组身份执行;目录上设置后新文件继承组
sticky bit1xxx目录下文件只有所有者能删除(如 /tmp)

⚠️ Docker 容器挂载数据卷时,容器内用户 UID 与宿主机用户 UID 不一致会导致 Permission denied。生产镜像建议创建固定 UID 的非 root 用户。

SSH 是远程登录 AI 服务器的标准方式,也是 Git 远程仓库和 scp/rsync 文件传输的底层协议。

Terminal window
# 生成 ed25519 密钥(比 RSA 更短更安全,推荐)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 一路回车使用默认路径 ~/.ssh/id_ed25519
# 生成 RSA 密钥(兼容性更好,旧系统用)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 把公钥拷贝到远程服务器(免密登录)
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 29966 user@server
# 手动分发(无 ssh-copy-id 时)
cat ~/.ssh/id_ed25519.pub | ssh -p 29966 user@server 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'
Terminal window
# ~/.ssh/config —— 简化连接命令
Host gpu-server
HostName 192.168.1.100
Port 29966
User alice
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60 # 保持连接不断开
Host nocix
HostName x.p.ifdog.com
Port 29966
User ifdog
# 配置后直接用别名连接
ssh gpu-server
scp file.txt gpu-server:/data/
Terminal window
# 本地端口转发:把远程服务的端口映射到本地
ssh -L 8888:localhost:8888 gpu-server
# 现在本地访问 localhost:8888 = 服务器上的 Jupyter
# 远程端口转发:把本地端口映射到远程
ssh -R 6006:localhost:6006 gpu-server
# 远程可以访问其 localhost:6006 = 你本机的 TensorBoard
# 动态端口转发(SOCKS 代理)
ssh -D 1080 gpu-server
Terminal window
# ~/.ssh/authorized_keys 和私钥文件的权限必须严格
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519
# /etc/ssh/sshd_config 关键安全项
# PermitRootLogin no # 禁止 root 直接登录
# PasswordAuthentication no # 禁用密码,仅密钥登录
# AllowUsers alice bob # 白名单

systemd 是现代 Linux(Ubuntu/Debian/CentOS 8+)的初始化系统和服务管理器,管理开机自启的后台服务。AI 服务器的 SSH、Docker、NVIDIA 驱动都是 systemd 服务。

Terminal window
systemctl status docker # 查看服务状态
systemctl start nginx # 启动服务
systemctl stop nginx # 停止服务
systemctl restart nginx # 重启服务
systemctl enable nginx # 设置开机自启
systemctl disable nginx # 取消开机自启
systemctl reload nginx # 重新加载配置(不中断连接)
journalctl -u docker -f # 查看服务日志(实时跟踪)
journalctl -u docker --since "1 hour ago"

为长时间运行的训练任务或推理服务创建 systemd 服务,实现开机自启、崩溃自动重启:

/etc/systemd/system/inference.service
[Unit]
Description=AI Inference Service
After=network.target docker.service
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/inference
Environment=CUDA_VISIBLE_DEVICES=0
ExecStart=/opt/inference/.venv/bin/python -m src.server --port 8000
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Terminal window
# 安装并启用
sudo cp inference.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable inference
sudo systemctl start inference

远程训练任务在 SSH 断开后会被杀死。tmux(或 screen)是终端复用器,可以让会话在后台持续运行,断开重连后恢复。

Terminal window
# 新建会话
tmux new -s training
# 断开会话(会话继续在后台运行)
# 按 Ctrl+B 然后按 D
# 列出会话
tmux ls
# 重新连接
tmux attach -t training
# 在会话内创建新窗口:Ctrl+B 然后 C
# 切换窗口:Ctrl+B 然后数字键
# 左右分屏:Ctrl+B 然后 "
# 上下分屏:Ctrl+B 然后 %
Terminal window
# 创建多窗口训练环境
tmux new -s train -d
tmux send-keys -t train 'watch -n 1 nvidia-smi' C-m # 窗口 0:GPU 监控
tmux new-window -t train
tmux send-keys -t train 'tail -f train.log' C-m # 窗口 1:训练日志
tmux attach -t train
# 训练完成后断开,SSH 断线也不影响
# 下次登录后 tmux attach -t train 即可恢复

💡 推荐用 tmux 而非 nohup 管理交互式训练,因为 tmux 可以随时重新连接、查看输出、发送输入。

场景 1:查找并清理占空间的旧文件

Section titled “场景 1:查找并清理占空间的旧文件”
Terminal window
# 找出 /data 下超过 30 天的大文件(>1GB)
find /data -type f -size +1G -mtime +30 -exec ls -lh {} \;
# 确认无误后删除
find /data -type f -name "*.tmp" -mtime +30 -delete
Terminal window
# 把所有 .jpeg 改为 .jpg
for f in *.jpeg; do mv "$f" "${f%.jpeg}.jpg"; done
# 给文件名加日期前缀
for f in *.log; do mv "$f" "$(date +%Y%m%d)_$f"; done
Terminal window
# 每 5 秒记录一次 GPU 状态到日志文件
while true; do
echo "=== $(date) ===" >> gpu.log
nvidia-smi --query-gpu=index,memory.used,utilization.gpu --format=csv,noheader >> gpu.log
sleep 5
done
术语英文解释
信号signal操作系统发给进程的异步通知(如 SIGTERM、SIGKILL)
管道pipe将前一个命令的输出作为后一个命令输入的机制(|)
端口转发port forwarding通过 SSH 隧道将远程端口映射到本地或反向
终端复用器terminal multiplexertmux/screen,允许多个终端会话在一个屏幕内管理,断线不中断
守护进程daemon后台运行的服务进程,通常由 systemd 管理