Skip to content

Linux 与命令行

命令行是机器学习工程的主要界面:训练任务、服务器管理、数据流水线和集群管理都通过终端完成。本文涵盖 shell、文件系统、权限、进程管理、包管理器、环境变量、SSH 以及每位机器学习工程师每天都会使用的基础命令。

  • 图形用户界面(GUI)在浏览网页时很方便,但在凌晨 2 点在远程 GPU 集群上运行训练任务时却很糟糕。命令行(或称终端、shell)是能够扩展的工具:它可以在任何机器上工作,可以被脚本化,可组合,并且在你的笔记本电脑、云虚拟机和 HPC 集群上都一样。

  • 如果你是一名只使用 Jupyter notebook 和 VS Code 按钮的机器学习工程师,那么你正浪费大量生产力。每个生产级机器学习系统都是通过命令行进行部署、监控和调试的。

Shell

  • Shell 是一个读取并执行你输入的命令的程序。它是你和操作系统之间的中介(见第13章)。最常见的 shell 是 bash(大多数 Linux 系统的默认 shell)和 zsh(macOS 的默认 shell)。

  • 命令的形式为:命令 [选项] [参数]

ls -la /home/user    # 命令=ls,选项=-la,参数=/home/user
  • 选项用于修改命令行为(通常用 - 加短选项,或用 -- 加长选项)。ls -l 以长格式列出,ls --all 显示隐藏文件。许多选项可以组合:ls -la 表示 -l-a 一起使用。

基础导航

pwd                 # 打印当前工作目录(我在哪里?)
ls                  # 列出当前目录下的文件
ls -la              # 列出所有文件(包括隐藏文件)并显示详细信息
cd /path/to/dir     # 切换目录
cd ..               # 进入上一级目录
cd ~                # 进入主目录
cd -                # 返回上一个目录

文件操作

cp source dest      # 复制文件
cp -r dir1 dir2     # 递归复制目录
mv old new          # 移动/重命名文件
rm file             # 删除文件(没有回收站 — 永久消失)
rm -rf dir          # 递归删除目录(危险 — 无确认)
mkdir -p a/b/c      # 创建嵌套目录
touch file.txt      # 创建空文件(或更新时间戳)
cat file.txt        # 打印文件内容
head -n 20 file     # 前20行
tail -f logfile     # 实时跟踪日志文件(监控训练时非常有用)
  • 陷阱rm -rf 是计算中最危险的命令。没有撤销操作。在按回车前务必三次确认路径。永远不要运行 rm -rf /rm -rf ~

管道与重定向

  • Shell 的杀手锏是可组合性:将多个小命令连接起来完成复杂任务。

  • 管道|):将一个命令的输出作为下一个命令的输入。

cat training.log | grep "loss" | tail -5    # 最后5行包含"loss"的行
ps aux | grep python                        # 查找正在运行的 Python 进程
history | grep "docker"                     # 查找之前的 docker 命令
  • 重定向:将输出发送到文件而不是屏幕。
python train.py > output.log 2>&1    # 标准输出和标准错误都重定向到文件
python train.py >> output.log        # 追加内容(不覆盖)
echo "data" > file.txt               # 覆盖文件
echo "more" >> file.txt              # 追加到文件
  • 2>&1 将标准错误(文件描述符2)重定向到标准输出(文件描述符1)。没有它,错误信息仍会显示在屏幕上,只有普通输出进入文件。

文本处理

grep "error" logfile.txt             # 查找包含"error"的行
grep -r "import torch" src/          # 递归搜索目录
grep -i "warning" log.txt            # 忽略大小写搜索
grep -c "epoch" train.log            # 统计匹配行数

wc -l file.txt                       # 统计行数
wc -w file.txt                       # 统计单词数

sort data.txt                        # 按字母顺序排序
sort -n numbers.txt                  # 按数字顺序排序
sort -u data.txt                     # 排序并去重
uniq -c sorted.txt                   # 统计连续重复行

cut -d',' -f2,3 data.csv            # 提取 CSV 的第2、3列
awk '{print $1, $3}' data.txt       # 打印以空白分隔的第1和第3字段
sed 's/old/new/g' file.txt          # 替换所有"old"为"new"
  • 这些命令可以优美地组合:
# 查找日志文件中出现次数最多的10种错误类型
grep "ERROR" app.log | awk -F': ' '{print $2}' | sort | uniq -c | sort -rn | head -10

查找文件

find . -name "*.py"                  # 查找所有 Python 文件
find . -name "*.pyc" -delete         # 查找并删除编译后的 Python 文件
find /data -size +100M               # 大于100MB的文件
find . -mtime -1                     # 最近24小时内修改过的文件

which python                        # python 可执行文件在哪里?
locate filename                      # 快速文件搜索(使用预建索引)

文件系统层次结构

  • Linux 将所有内容组织在以 / 为根的单棵树中:
目录 用途
/ 整个文件系统的根
/home/user 你的个人文件、配置、项目
/etc 系统级配置文件
/usr 用户程序、库、文档
/usr/local 本地安装的软件(非包管理器)
/var 可变数据:日志(/var/log)、数据库、缓存
/tmp 临时文件(重启后清除)
/opt 可选的第三方软件
/proc 暴露内核和进程信息的虚拟文件系统
/dev 设备文件(磁盘、GPU 会出现在这里)
  • 对于机器学习:训练数据通常在 /data/home/user/data 中,模型在 /home/user/models 中,CUDA 位于 /usr/local/cuda。GPU 设备显示为 /dev/nvidia0/dev/nvidia1 等。

文件权限

  • 每个文件和目录对三类用户各有三种权限类型:
权限 文件 目录
r(读) 查看内容 列出内容
w(写) 修改内容 在内部创建/删除文件
x(执行) 作为程序运行 进入(cd)该目录
  • 三类用户:所有者(u)、用户组(g)、其他用户(o)。
ls -l script.py
# -rwxr-xr-- 1 henry ml_team 2048 Mar 28 script.py
#  ^^^         所有者权限:rwx(读、写、执行)
#     ^^^      组权限:r-x(读、执行,无写)
#        ^^^   其他用户权限:r--(只读)
chmod 755 script.py       # 所有者=rwx,组=rx,其他=rx
chmod +x script.py        # 为所有人添加执行权限
chmod u+w,g-w file.txt    # 为所有者添加写权限,移除组的写权限
chown henry:ml_team file  # 更改所有者和组
  • 陷阱:以 #!/usr/bin/env python3 开头的 Python 脚本需要执行权限(chmod +x)才能以 ./script.py 方式运行。如果没有执行权限,必须使用 python3 script.py

进程管理

  • 进程是正在运行的程序(见第13章)。Shell 提供了管理它们的工具:
ps aux                    # 列出所有正在运行的进程
ps aux | grep python      # 查找 Python 进程
top                       # 实时进程监控(CPU、内存)
htop                      # 比 top 更好(需单独安装)
nvidia-smi                # GPU 使用情况(机器学习必备)
watch -n 1 nvidia-smi     # 每秒刷新一次 nvidia-smi

kill PID                  # 优雅终止进程
kill -9 PID               # 强制终止(优雅失败时使用)
killall python            # 杀死所有 Python 进程

# 后台运行
python train.py &                    # 后台运行
nohup python train.py > log.txt &    # 后台运行,退出登录后仍存活
  • nohup 对机器学习训练至关重要:没有它,关闭 SSH 连接会杀死训练任务。nohup 将进程与终端分离。

  • screentmux 是终端复用器,可创建持久会话。你可以启动一个训练任务放入 tmux 会话,断开 SSH,稍后重新连接,该会话(及训练)仍在运行。

tmux new -s training          # 创建命名会话
# ... 开始训练 ...
# Ctrl+B,然后 D              # 从会话中脱离
tmux attach -t training       # 稍后重新连接(即使 SSH 重新连接后)
tmux ls                       # 列出会话

包管理器

  • 系统包(操作系统级软件):
# Debian/Ubuntu
sudo apt update               # 刷新软件包列表
sudo apt install htop         # 安装软件包
sudo apt upgrade              # 升级所有软件包

# macOS
brew install wget             # 通过 Homebrew 安装
  • Python 包
pip install torch             # 从 PyPI 安装
pip install -e .              # 以可编辑模式安装当前项目
pip install -r requirements.txt  # 根据 requirements 文件安装
pip freeze > requirements.txt    # 导出已安装的包

# Conda(用于复杂依赖,如 CUDA)
conda create -n myenv python=3.11
conda activate myenv
conda install pytorch torchvision cudatoolkit=12.1 -c pytorch
  • 陷阱:永远不要使用 pip install 安装到系统 Python。始终使用虚拟环境(python -m venv envconda createuv venv)。系统 Python 被操作系统工具共享,破坏它可能导致系统故障。

环境变量

  • 环境变量是键值对,所有程序都可以访问。它们在不修改代码的情况下配置行为。
export CUDA_VISIBLE_DEVICES=0,1    # 仅使用 GPU 0 和 1
export PYTHONPATH=/home/user/src   # 添加到 Python 的导入路径
export WANDB_API_KEY=abc123        # Weights & Biases 的 API 密钥

echo $PATH                         # 查看当前 PATH
export PATH=$PATH:/usr/local/cuda/bin  # 将 CUDA 添加到 PATH
  • .bashrc(或 .zshrc):每次打开 shell 时运行的命令。将你的 export 语句放在这里,使其持久化。

  • .env 文件:由 python-dotenv 等工具加载的项目专属变量。将密钥(API 密钥、数据库密码)保存在 .env 中,并将 .env 添加到 .gitignore。永远不要将密钥提交到 git。

SSH(安全外壳)

  • SSH 通过加密通道连接到远程机器。这是你访问云虚拟机、GPU 服务器和 HPC 集群的方式。
ssh user@hostname              # 连接到远程机器
ssh -i ~/.ssh/key.pem user@ip  # 使用特定密钥连接
ssh -L 8888:localhost:8888 user@server  # 端口转发(远程 Jupyter)
  • SSH 密钥(公钥/私钥对)替代密码:
ssh-keygen -t ed25519          # 生成密钥对
ssh-copy-id user@server        # 将公钥复制到服务器
# 现在无需密码即可 SSH 登录
  • SSH 配置文件~/.ssh/config)保存连接信息:
Host gpu-server
    HostName 10.0.1.42
    User henry
    IdentityFile ~/.ssh/gpu_key
    LocalForward 8888 localhost:8888
  • 现在只需 ssh gpu-server 即可自动使用所有这些设置。

  • scprsync 在机器之间传输文件:

scp model.pt user@server:/data/models/     # 复制文件到远程
scp -r user@server:/data/results/ ./       # 从远程复制目录
rsync -avz --progress data/ user@server:/data/  # 同步并显示进度(比 scp 更智能)

机器学习常用命令速查表

# GPU 监控
nvidia-smi                                   # GPU 使用快照
watch -n 1 nvidia-smi                        # 实时监控
gpustat                                      # 更简洁的 GPU 概览(pip install gpustat)

# 训练管理
nohup python train.py > train.log 2>&1 &     # 后台训练,退出登录后仍运行
tail -f train.log                            # 监控训练输出
kill %1                                      # 杀死最后一个后台任务

# 磁盘使用(数据集很大)
df -h                                        # 所有挂载点的磁盘空间
du -sh /data/*                               # /data 下每个项目的大小
du -sh --max-depth=1 .                       # 子目录的大小

# 内存
free -h                                      # RAM 使用情况
cat /proc/meminfo                            # 详细内存信息

# 网络
curl -O https://example.com/dataset.tar.gz   # 下载文件
wget https://example.com/model.bin           # 另一个下载工具
curl -X POST http://localhost:8080/predict \
    -H "Content-Type: application/json" \
    -d '{"text": "hello"}'                   # 测试模型服务端点

# 压缩包
tar -czf archive.tar.gz directory/           # 压缩
tar -xzf archive.tar.gz                      # 解压
zip -r archive.zip directory/                # 压缩为 zip
unzip archive.zip                            # 解压 zip

# 快速数据检查
head -5 data.csv                             # CSV 前5行
wc -l data.csv                               # 统计行数
cut -d',' -f1 data.csv | sort -u | wc -l    # 统计第一列的唯一值个数