Linux 与命令行


文档摘要

Linux 与命令行 命令行是 ML 工程的主要接口:训练任务、服务器管理、数据管道、集群运维,全都发生在终端里。本文件覆盖 shell、文件系统、权限、进程管理、包管理器、环境变量、SSH,以及每位 ML 工程师每天都在用的必备命令。 图形界面(GUI)用来浏览网页很方便,但如果你要在凌晨两点给远端 GPU 集群跑一个训练任务,它就无能为力了。命令行(command line,也叫终端 terminal 或 shell)才是能扩展的工具:它能在任何机器上工作,可以被脚本化,可以组合,而且无论你用的是笔记本、云虚拟机(VM)还是高性能计算(HPC)集群,它都长得一样。

Linux 与命令行

命令行是 ML 工程的主要接口:训练任务、服务器管理、数据管道、集群运维,全都发生在终端里。本文件覆盖 shell、文件系统、权限、进程管理、包管理器、环境变量、SSH,以及每位 ML 工程师每天都在用的必备命令。

  • 图形界面(GUI)用来浏览网页很方便,但如果你要在凌晨两点给远端 GPU 集群跑一个训练任务,它就无能为力了。命令行(command line,也叫终端 terminal 或 shell)才是能扩展的工具:它能在任何机器上工作,可以被脚本化,可以组合,而且无论你用的是笔记本、云虚拟机(VM)还是高性能计算(HPC)集群,它都长得一样。

  • 如果你是一个只用 Jupyter notebook 和 VS Code 按钮的 ML 工程师,那你就把巨大的生产力留在了桌面上。每一个生产级 ML 系统,都是通过命令行来部署、监控和调试的。

Shell

  • shell(外壳)是一个从你这里读取命令并执行它们的程序。它是你和操作系统(第 13 章)之间的中间人。最常见的 shell 是 bash(大多数 Linux 系统的默认)和 zsh(macOS 的默认)。

  • 一条命令的格式是:command [options] [arguments]

ls -la /home/user # command=ls, options=-la, argument=/home/user
  • 选项用来修改行为(短形式通常以 - 开头,长形式以 -- 开头)。ls -l 用长格式列出,ls --all 显示隐藏文件。很多选项可以合并:ls -la 表示 -l-a 一起用。

必备导航命令

pwd # print working directory(我在哪?) ls # 列出当前目录的文件 ls -la # 列出所有文件(含隐藏文件)并显示详细信息 cd /path/to/dir # 切换目录 cd .. # 上一级目录 cd ~ # 回到主目录(home) 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 的杀手锏是可组合性(composability):把小命令连接起来做复杂的事情。

  • 管道(pipe,|):把一个命令的输出作为下一个命令的输入。

cat training.log | grep "loss" | tail -5 # 最后 5 行包含 "loss" 的行 ps aux | grep python # 查找正在运行的 Python 进程 history | grep "docker" # 查找之前用过的 docker 命令
  • 重定向(redirection):把输出送到文件而不是屏幕。
python train.py > output.log 2>&1 # stdout 和 stderr 都写到文件 python train.py >> output.log # 追加(不覆盖) echo "data" > file.txt # 覆盖文件 echo "more" >> file.txt # 追加到文件
  • 2>&1 把 stderr(文件描述符 2)重定向到 stdout(文件描述符 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 # 大于 100 MB 的文件 find . -mtime -1 # 最近 24 小时内修改过的文件 which python # python 可执行文件在哪里? locate filename # 快速文件搜索(使用预建索引)

文件系统层级

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

文件权限

  • 每个文件和目录对三类用户都有三种权限:
权限 文件 目录
r(read,读) 查看内容 列出内容
w(write,写) 修改内容 在里面创建/删除文件
x(execute,执行) 作为程序运行 进入(cd 进去)该目录
  • 三类用户:owner(所有者,u)group(用户组,g)others(其他人,o)
ls -l script.py # -rwxr-xr-- 1 henry ml_team 2048 Mar 28 script.py # ^^^ 所有者权限:rwx(读、写、执行) # ^^^ 用户组权限:r-x(读、执行,不可写) # ^^^ 其他人权限:r--(只读)
chmod 755 script.py # owner=rwx, group=rx, others=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 来跑。

进程管理

  • 进程(process)是一个正在运行的程序(第 13 章)。shell 给了你管理它们的工具:
ps aux # 列出所有正在运行的进程 ps aux | grep python # 查找 Python 进程 top # 实时进程监控(CPU、内存) htop # top 的更好版本(需单独安装) nvidia-smi # GPU 使用情况(ML 必备) 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 对 ML 训练至关重要:没有它,关闭 SSH 连接会杀掉训练任务。nohup 把进程从终端上解绑。

  • screentmux 是终端复用器(terminal multiplexer),能创建持久化的会话。你可以在一个 tmux 会话里启动一个训练任务,断开 SSH,之后再重新连上,会话(和训练)仍然在运行。

tmux new -s training # 创建命名会话 # ... 启动训练 ... # Ctrl+B, then 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
  • 陷阱:永远不要往系统 Python 里 pip install。一定要用虚拟环境(python -m venv envconda createuv venv)。系统 Python 是被 OS 工具共用的,弄坏它可能让你的系统崩溃。

环境变量

  • 环境变量(environment variables)是所有程序都能访问的键值对。它们让你无需改代码就能配置行为。
export CUDA_VISIBLE_DEVICES=0,1 # 只使用 0 号和 1 号 GPU 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 key、数据库密码)放在 .env 里,并把 .env 加进 .gitignore。永远不要把密钥提交到 git。

SSH(Secure Shell)

  • SSH 通过加密通道把你连到远端机器。这是你访问云 VM、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 config~/.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 更聪明)

ML 必备命令速查表

# 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 # 内存使用 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 # 统计第 1 列的唯一值数量

发布者: 作者: HenryNdubuaku 转发
评论区 (0)
U