Linux 详细教程(Ubuntu)

Linux 详细教程(以 Ubuntu 为例)

目录

  1. 什么是 Linux
  2. 文件系统结构
  3. 终端基础
  4. 文件与目录操作
  5. 文件权限
  6. 用户与组管理
  7. 进程管理
  8. 软件包管理 (apt)
  9. 文本处理
  10. Shell 基础
  11. 网络操作
  12. 磁盘管理
  13. systemd 服务管理
  14. 常用命令速查表

1. 什么是 Linux

1.1 操作系统结构

7653370610499944486.png~tplv-a9rns2rl98-image-face-cut_0_0_2970_2070_2970_2070

Linux 严格来说只是内核(Kernel),但通常我们说”Linux”指的是基于 Linux 内核的完整操作系统(GNU/Linux 发行版)。

1.2 常见的 Linux 发行版

1
2
3
4
5
6
7
8
9
10
11
12
Debian 系(使用 apt/dpkg):        Red Hat 系(使用 yum/dnf/rpm):
├── Ubuntu (桌面/服务器) ├── RHEL (企业级)
│ ├── Kubuntu (KDE) ├── CentOS (免费 RHEL 克隆,已停止)
│ ├── Xubuntu (XFCE) ├── Fedora (前沿技术)
│ └── Linux Mint (易用桌面) └── Rocky Linux (CentOS 替代)
├── Debian (稳定/通用)
└── Kali Linux (安全渗透)

其他:
├── Arch Linux (滚动更新,DIY)
├── openSUSE (企业/社区)
└── Alpine (极简,常用于 Docker)

本教程以 Ubuntu 22.04 LTS 为例。

1.3 Linux 哲学

“一切皆文件” —— 硬件设备、进程、网络连接、系统信息,在 Linux 中都以文件形式存在。

1
2
3
4
/dev/sda      ← 硬盘
/dev/tty ← 终端
/proc/cpuinfo ← CPU 信息
/sys/class ← 设备信息

2. 文件系统结构

2.1 根目录结构总览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/                           ← 根目录,一切文件系统的起点
├── bin/ ← 基本用户命令 (/usr/bin 的符号链接)
│ ├── ls ← 列出目录
│ ├── cp ← 复制
│ ├── mv ← 移动
│ └── cat ← 显示文件

├── boot/ ← 启动相关文件
│ ├── vmlinuz ← Linux 内核
│ └── initrd.img ← 初始 RAM 磁盘

├── dev/ ← 设备文件
│ ├── sda ← 第一块硬盘
│ ├── sda1 ← 第一个分区
│ ├── tty ← 终端
│ ├── null ← 黑洞(丢弃一切写入的数据)
│ ├── zero ← 无限零字节流
│ └── random ← 随机数生成器

├── etc/ ← 系统配置文件 (Editable Text Configuration)
│ ├── passwd ← 用户账户信息
│ ├── shadow ← 用户密码(加密)
│ ├── group ← 用户组信息
│ ├── hosts ← 主机名-IP 映射
│ ├── hostname ← 主机名
│ ├── fstab ← 文件系统挂载表
│ ├── apt/sources.list ← 软件源配置
│ ├── ssh/sshd_config ← SSH 服务配置
│ └── nginx/ ← Nginx 配置目录

├── home/ ← 用户主目录
│ ├── alice/ ← 用户 alice 的个人目录
│ │ ├── Desktop/ ← 桌面
│ │ ├── Documents/ ← 文档
│ │ ├── Downloads/ ← 下载
│ │ ├── .bashrc ← Bash 配置文件(以 . 开头表示隐藏)
│ │ └── .config/ ← 用户级应用配置
│ └── bob/ ← 用户 bob 的个人目录

├── lib/ ← 系统库文件 (/usr/lib 的符号链接)

├── media/ ← 可移动媒体挂载点(USB、CD-ROM)

├── mnt/ ← 临时挂载点(手动挂载)

├── opt/ ← 第三方应用软件包 (Optional)

├── proc/ ← 虚拟文件系统(进程和系统信息)
│ ├── cpuinfo ← CPU 信息
│ ├── meminfo ← 内存信息
│ ├── version ← 内核版本
│ ├── uptime ← 系统运行时间
│ ├── [PID]/ ← 每个进程的目录(PID = 进程号)
│ │ ├── cmdline ← 启动命令
│ │ ├── environ ← 环境变量
│ │ └── status ← 进程状态
│ └── mounts ← 挂载信息

├── root/ ← root 用户的主目录

├── run/ ← 运行时变量数据(重启后清空)

├── sbin/ ← 系统管理员命令 (/usr/sbin 的符号链接)

├── srv/ ← 服务数据 (Service Data)

├── sys/ ← 虚拟文件系统(内核和设备信息)

├── tmp/ ← 临时文件(重启后可能清空)

├── usr/ ← 用户系统资源 (Unix System Resources)
│ ├── bin/ ← 大部分用户命令
│ ├── sbin/ ← 系统管理命令
│ ├── lib/ ← 库文件
│ ├── local/ ← 本地编译安装的软件
│ ├── share/ ← 共享数据(文档、图标、字体等)
│ └── include/ ← C/C++ 头文件

└── var/ ← 可变数据 (Variable)
├── log/ ← 系统日志
│ ├── syslog ← 系统日志
│ ├── auth.log ← 认证日志(登录记录)
│ └── apt/history.log ← 软件安装历史
├── cache/ ← 应用程序缓存
├── lib/ ← 应用状态信息
│ └── apt/lists/ ← apt 软件包列表缓存
├── spool/ ← 打印/邮件队列
└── www/ ← Web 服务器文件(可选)

2.2 重要目录详解

/etc — 系统配置的”控制中心”

1
2
3
4
5
6
7
8
9
/etc/passwd          # 用户账户信息(每行一个用户)
/etc/shadow # 用户加密密码
/etc/group # 组信息
/etc/sudoers # sudo 权限配置(用 visudo 编辑!)
/etc/crontab # 定时任务
/etc/fstab # 开机自动挂载的文件系统
/etc/hosts # 本地 DNS 解析
/etc/resolv.conf # DNS 服务器配置
/etc/apt/sources.list # 软件源列表

/proc — 窥探系统运行的窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
# 这是一个伪文件系统,存在于内存中,不占磁盘空间

cat /proc/cpuinfo # CPU 详细信息
cat /proc/meminfo # 内存使用情况
cat /proc/version # 内核版本
cat /proc/uptime # 系统运行时间(秒)
cat /proc/loadavg # 系统负载
cat /proc/mounts # 已挂载的文件系统

# 进程信息
ls /proc/1234/ # 查看 PID 为 1234 的进程信息
cat /proc/1234/cmdline # 进程启动命令
cat /proc/1234/status # 进程详细状态

/dev — 设备即文件

1
2
3
4
5
6
7
8
9
10
11
/dev/sda              # 第一块 SCSI/SATA 硬盘
/dev/sda1 # 第一块硬盘的第一个分区
/dev/sdb # 第二块硬盘
/dev/nvme0n1 # 第一块 NVMe SSD
/dev/tty1 # 第一个虚拟终端 (Ctrl+Alt+F1)
/dev/pts/0 # 伪终端(如终端模拟器窗口)
/dev/null # 数据黑洞,写入的数据会被丢弃
/dev/zero # 提供无限的 null 字节(\0)
/dev/random # 真随机数(可能阻塞)
/dev/urandom # 伪随机数(不阻塞,一般够用)
/dev/loop0 # 回环设备(用于挂载 ISO 等)

2.3 路径表示

1
2
3
4
5
6
7
8
9
10
# 两种路径
/home/alice/file.txt ← 绝对路径(从 / 开始)
../bob/file.txt ← 相对路径(相对于当前目录)

# 特殊目录符号
. ← 当前目录
.. ← 上级目录
~ ← 当前用户的主目录
~bob ← bob 用户的主目录
- ← 上一次所在目录(cd - 切换回去)

3. 终端基础

3.1 终端 vs Shell vs 命令行

1
2
3
4
5
6
┌──────────┐    ┌──────────┐    ┌──────────┐
│ 终端模拟器 │ │ Shell │ │ 操作系统 │
│(Terminal)│ ←→ │ (bash) │ ←→ │ (Kernel) │
│ 图形界面 │ │ 命令解释器 │ │ │
└──────────┘ └──────────┘ └──────────┘
你看到的窗口 解析并执行命令 实际干活的部分

常见 Shell:

Shell 特点 配置文件
bash 大多数 Linux 默认,兼容性好 ~/.bashrc
zsh 功能丰富,插件生态好 ~/.zshrc
fish 开箱即用,语法友好 ~/.config/fish/config.fish
dash 轻量,Debian/Ubuntu 的 /bin/sh

3.2 命令格式

1
2
3
4
5
命令名 [选项/标志] [参数...]
│ │ │
│ │ └── 命令操作的对象(文件、目录等)
│ └── 修改命令行为(-短选项 --长选项)
└── 要执行的程序
1
2
3
4
5
6
7
8
9
10
11
12
# 示例
ls -l /home
│ │ │
│ │ └── 参数:要列出哪个目录
│ └── 选项:长格式显示
└── 命令:列出文件

# 选项的多种写法
ls -l -a -h # 分开写
ls -lah # 合并简写(效果完全相同)
ls --all # 长选项
ls --human-readable

3.3 常用快捷键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Ctrl + C     终止当前正在运行的程序
Ctrl + D 发送 EOF(退出终端、退出 Python 等交互环境)
Ctrl + Z 暂停(挂起)当前程序,放入后台
Ctrl + L 清屏(相当于 clear 命令)
Ctrl + A 光标跳到行首
Ctrl + E 光标跳到行尾
Ctrl + U 删除光标前的内容
Ctrl + K 删除光标后的内容
Ctrl + W 删除光标前的一个单词
Ctrl + R 搜索历史命令(最实用的功能之一)
!! 重复上一条命令
!$ 上一条命令的最后一个参数
↑ / ↓ 浏览历史命令
Tab 自动补全(路径、命令、参数)

3.4 获取帮助

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# man — 最权威的参考手册(共 9 个章节)
man ls # 查看 ls 命令的手册
man 5 crontab # 查看第 5 节(文件格式)的 crontab 手册
man -k keyword # 搜索手册 (apropos)

# man 手册章节划分:
# 1 = 用户命令 2 = 系统调用 3 = 库函数
# 4 = 设备文件 5 = 配置文件 6 = 游戏
# 7 = 杂项 8 = 系统管理命令

# --help — 大多数命令都支持
ls --help
git --help

# whatis — 命令的简短描述
whatis ls

# whereis — 查找命令的位置(whereis 查找命令的二进制文件、源码和手册页的路径。)
whereis python3

# which — 显示命令的完整路径
which python3

# tldr — 社区维护的简洁帮助(需安装)
sudo apt install tldr
tldr tar

4. 文件与目录操作

4.1 浏览文件系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# pwd — 显示当前路径
pwd # /home/alice/Documents

# ls — 列出目录内容
ls # 简单列表
ls -l # 长格式(权限、大小、时间等)
ls -a # 显示隐藏文件(以 . 开头的文件)
ls -la # 长格式 + 隐藏文件
ls -lh # 人类可读的文件大小(K, M, G)
ls -lt # 按修改时间排序(最新的在前)
ls -ltr # 按修改时间反向排序(最旧的在前面)
ls -R # 递归列出所有子目录
ls -d */ # 只列出目录

# ls -l 输出解读:
# drwxr-xr-x 2 alice developers 4096 Jun 16 14:30 Documents
# │││││││││ │ │ │ │ │ │
# │││││││││ │ │ │ │ │ └── 文件名
# │││││││││ │ │ │ │ └── 修改时间
# │││││││││ │ │ │ └── 文件大小(字节)
# │││││││││ │ │ └── 所属组
# │││││││││ │ └── 所有者
# │││││││││ └── 硬链接数
# │└┴┴┴┴┴┴┴┴── 权限位(见第 5 节)
# └── 文件类型(d=目录,-=普通文件,l=符号链接)

# cd — 切换目录
cd /home # 绝对路径
cd Documents # 相对路径(进入当前目录下的 Documents)
cd .. # 上级目录
cd ../.. # 上上级目录
cd - # 回到上一次所在目录
cd ~ # 回到用户主目录
cd # 同上(不带参数默认回主目录)

4.2 创建与删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# touch — 创建空文件或更新文件时间戳
touch file.txt
touch file1.txt file2.txt file3.txt # 同时创建多个

# mkdir — 创建目录
mkdir new_folder
mkdir -p a/b/c/d # 递归创建多级目录(最常用)
mkdir -p project/{src,tests,docs} # 花括号展开一次创建多个

# rm — 删除文件(永久删除,没有回收站!)
rm file.txt
rm -i file.txt # 删除前询问确认
rm -f file.txt # 强制删除,不提示
rm -r folder/ # 递归删除目录及内容
rm -rf folder/ # 强制递归删除(⚠️ 极其危险,慎重使用!)

# rmdir — 删除空目录
rmdir empty_folder

# 安全删除(安装 trash-cli,类似回收站)
sudo apt install trash-cli
trash-put file.txt # 移到回收站
trash-list # 查看回收站
trash-restore # 恢复
trash-empty # 清空回收站

4.3 复制与移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# cp — 复制
cp source.txt dest.txt # 复制文件
cp file1.txt file2.txt folder/ # 复制多个文件到目录
cp -r source_dir/ dest_dir/ # 递归复制目录
cp -i source.txt dest.txt # 覆盖前询问
cp -u source.txt dest.txt # 只在源文件更新时才复制
cp -p source.txt dest.txt # 保留权限和时间戳
cp -a source_dir/ dest_dir/ # 归档模式(递归+保留所有属性)

# mv — 移动/重命名
mv oldname.txt newname.txt # 重命名
mv file.txt folder/ # 移动到目录
mv -i source.txt dest.txt # 覆盖前询问
mv -u source.txt dest.txt # 仅在源更新时覆盖

# 重命名的批量技巧
# 将所有 .txt 改为 .md(使用循环或 rename 命令)
for f in *.txt; do mv "$f" "${f%.txt}.md"; done
# 或安装 rename:
sudo apt install rename
rename 's/\.txt$/\.md/' *.txt

4.4 查看文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# cat — 显示文件全部内容
cat file.txt
cat -n file.txt # 带行号
cat file1.txt file2.txt # 连接多个文件

# tac — 反向显示(最后一行先显示)
tac file.txt

# less — 分页查看(推荐,按 q 退出)
less file.txt
# less 中的快捷键:
# Space / f 向前翻页
# b 向后翻页
# g 跳到开头
# G 跳到末尾
# /pattern 向下搜索
# ?pattern 向上搜索
# n 下一个匹配
# N 上一个匹配
# q 退出

# head — 查看文件头部
head file.txt # 默认前 10 行
head -n 20 file.txt # 前 20 行
head -c 100 file.txt # 前 100 个字节

# tail — 查看文件尾部
tail file.txt # 默认后 10 行
tail -n 20 file.txt # 后 20 行
tail -f /var/log/syslog # 实时跟踪文件更新(Ctrl+C 退出,最常用!)

# nl — 带行号显示
nl file.txt

# wc — 统计
wc file.txt # 行数 单词数 字节数
wc -l file.txt # 只统计行数
wc -w file.txt # 只统计单词数
wc -c file.txt # 只统计字节数

# file — 判断文件类型
file mystery_file
file *.png

4.5 链接

Linux 中有两种链接:硬链接符号链接(软链接)

1
2
3
4
5
6
7
8
9
10
11
硬链接 (Hard Link):                    符号链接 (Symbolic Link):

[文件数据块] [文件数据块]
↑ ↑ ↑
| | |
file.txt hardlink file.txt symlink → file.txt

共享同一个 inode(数据块) symlink 存储的是目标路径(类似 Win 快捷方式)
删除原文件不影响硬链接 删除原文件后,软链接失效
不能跨文件系统 可以跨文件系统
不能链接目录 可以链接目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ln — 创建硬链接
ln original.txt hardlink.txt

# ln -s — 创建符号链接(更常用)
ln -s /usr/bin/python3 python
ln -s /var/www/html web-root
ln -s ../config/settings.json settings.json

# 查看链接
ls -l
# lrwxrwxrwx 1 alice alice 10 Jun 16 14:30 python -> /usr/bin/python3
# ↑ 文件类型 l 表示符号链接
# ↑ -> 指向的目标

# 查看链接指向
readlink python # /usr/bin/python3
readlink -f python # 解析所有层级的最终目标

5. 文件权限

5.1 权限模型

Linux 权限基于三个主体和三种操作:

1
2
3
4
5
三个主体:                    三种操作:
u = user (所有者) r = read (读) = 4
g = group (所属组) w = write (写) = 2
o = other (其他人) x = execute(执行) = 1
a = all (所有)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ ls -l
-rwxr-xr-- 1 alice developers 4096 Jun 16 14:30 script.sh
│││││││││
│└┴┴┴┴┴┴┴┴── 权限位
└── 文件类型

权限位拆解:
- rwx r-x r--
│ │ │ │
│ │ │ └── other: 只读 (r--)
│ │ └── group: 读+执行 (r-x)
│ └── user (owner): 读+写+执行 (rwx)
└── 类型: 普通文件

等价数字表示:
rwx = 4+2+1 = 7
r-x = 4+0+1 = 5
r-- = 4+0+0 = 4
→ 权限: 754

注意:目录也是一种”文件”,同样有 rwx 权限,只是含义略有不同:

  • r — 能否列出目录内容(ls)
  • w — 能否在其中创建/删除文件
  • x — 能否进入该目录(cd)

5.2 常用权限组合

数字 权限 含义 典型用途
777 rwxrwxrwx 所有人都能读写执行 ⚠️ 不安全,避免使用
755 rwxr-xr-x 所有者全权限,其他人读取执行 可执行文件、目录
750 rwxr-x— 所有者和组有权限,其他人无 团队共享目录
700 rwx—— 只有所有者有权限 个人脚本、SSH 密钥
644 rw-r–r– 所有者可写,其他人只读 普通文件
640 rw-r—– 所有者和组可读,其他人无 配置文件
600 rw——- 只有所有者可读写 敏感文件(私钥、密码)

5.3 修改权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# chmod — 修改文件权限

# 符号模式:
chmod u+x script.sh # 给所有者添加执行权限
chmod g-w file.txt # 移除组的写权限
chmod o= file.txt # 移除其他人的所有权限
chmod a+r file.txt # 给所有人添加读权限
chmod u=rwx,g=rx,o= script.sh

# 数字模式(更常用):
chmod 755 script.sh # rwxr-xr-x
chmod 644 file.txt # rw-r--r--
chmod 600 id_rsa # rw-------

# 递归修改目录下所有文件,-R 递归作用于目录内所有文件和子目录,全部设成 755
chmod -R 755 project/
# 更精细的递归:目录和文件分开设置
find project/ -type d -exec chmod 755 {} \;
find project/ -type f -exec chmod 644 {} \;

# chown — 修改所有者和所属组
chown alice file.txt # 修改所有者
chown alice:developers file.txt # 同时修改所有者和组
chown :developers file.txt # 只修改组
chown -R alice:developers dir/ # 递归修改整个目录

# chgrp — 修改所属组(等同于 chown :group)
chgrp developers file.txt

5.4 特殊权限

1
2
3
SUID (Set User ID)  — 4—  # 以文件所有者的身份执行
SGID (Set Group ID) — 2— # 以文件所属组的身份执行 / 目录中新文件继承组
Sticky Bit — 1 # 只有文件所有者才能删除(用于 /tmp)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 设置 SUID,普通情况下,运行一个程序时用的是你自己的身份。SUID 位设上后,程序运行时会临时切换成文件所有者的身份。
# 典型例子:/usr/bin/passwd 的所有者是 root,设了 SUID,所以你(普通用户)执行它时,它实际以 root 身份去修改 /etc/shadow,否则你没权限改自己的密码。
chmod u+s /usr/bin/passwd # passwd 需要以 root 身份修改 /etc/shadow
# ls -l: -rwsr-xr-x (x 被 s 替代)

# 设置 SGID
#正常情况下,你在目录里创建文件,文件所属组 = 你的主组。但目录设了 SGID 位后,该目录下新建的文件/子目录自动继承目录的所属组,而非创建者的组。
chmod g+s /shared/team_dir/ # 目录内新建的文件会继承目录的组

# 设置 Sticky Bit
chmod +t /tmp # /tmp 默认已有
# ls -l: drwxrwxrwt (最后的 t 表示 sticky bit)

# 数字表示(加在三位权限前面):
chmod 4755 file # SUID
chmod 2755 file # SGID
chmod 1755 dir # Sticky Bit
chmod 6755 file # SUID + SGID

5.5 umask — 默认权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 查看当前 umask
umask
# 输出: 0022 (默认,root 为 0022,普通用户通常也为 0022)

# umask 是"屏蔽"值:
# 文件默认最大权限 = 666
# 目录默认最大权限 = 777
# 新建文件权限 = 666 - umask
# 新建目录权限 = 777 - umask

# 例如 umask = 022:
# 新建文件: 666 - 022 = 644 (rw-r--r--)
# 新建目录: 777 - 022 = 755 (rwxr-xr-x)

# 临时修改(只影响当前 shell 会话)
umask 027

# 永久修改:添加到 ~/.bashrc 或 /etc/profile
echo "umask 027" >> ~/.bashrc

6. 用户与组管理

6.1 用户类型

1
2
3
root (UID=0)           ← 超级管理员,拥有一切权限
└── 系统用户 (1-999) ← 运行系统服务(如 www-data, mysql),通常无登录权限
└── 普通用户 (1000+) ← 你创建的用户,日常使用

6.2 用户管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# whoami — 我是谁
whoami

# id — 查看用户 ID 和组
id # 当前用户信息
id alice # 查看 alice 的信息
# uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo),1001(developers)

# 用户文件
cat /etc/passwd # 用户列表(每行格式:用户名:x:UID:GID:描述:主目录:Shell)
cat /etc/shadow # 加密密码(需要 root 权限查看)
sudo cat /etc/shadow

# sudo — 以 root 身份执行命令
sudo apt update
sudo -i # 切换到 root 用户(交互式 shell)
sudo -u alice whoami # 以 alice 的身份执行命令

# su — 切换用户
su - alice # 切换到 alice(- 表示加载该用户的环境)

# useradd — 添加用户
sudo useradd -m -s /bin/bash bob # 创建用户并指定 shell
# -m = 自动创建主目录
# -s = 指定登录 Shell

# passwd — 修改密码
passwd # 修改自己的密码
sudo passwd bob # 修改 bob 的密码
sudo passwd -l bob # 锁定账户
sudo passwd -u bob # 解锁账户

# usermod — 修改用户属性
sudo usermod -aG sudo bob # 将 bob 加入 sudo 组(-a=追加,-G=附加组)
sudo usermod -aG docker bob # 加入 docker 组
sudo usermod -s /bin/zsh bob # 修改 shell
sudo usermod -L bob # 锁定
sudo usermod -U bob # 解锁

# userdel — 删除用户
sudo userdel bob # 只删除用户
sudo userdel -r bob # 同时删除主目录和邮件

6.3 组管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查看组
cat /etc/group
groups alice # 查看 alice 属于哪些组

# groupadd — 创建组
sudo groupadd developers

# groupmod — 修改组
sudo groupmod -n devs developers # 重命名组

# groupdel — 删除组
sudo groupdel developers

# gpasswd — 管理组成员
sudo gpasswd -a alice developers # 添加用户到组
sudo gpasswd -d alice developers # 从组移除用户

6.4 /etc/sudoers 配置

1
2
3
4
5
6
7
8
9
10
11
12
# ⚠️ 必须用 visudo 编辑,不要直接编辑!
sudo visudo

# 常用配置:
# 允许 alice 无需密码执行所有命令
alice ALL=(ALL:ALL) NOPASSWD: ALL

# 只允许 bob 执行特定命令
bob ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx

# 允许 developers 组执行特定命令(不需要密码)
%developers ALL=(ALL) NOPASSWD: /usr/bin/apt update, /usr/bin/apt upgrade

7. 进程管理

7.1 进程概念

1
2
3
4
5
6
7
8
9
进程(Process):正在运行的程序的实例。
每个进程有一个唯一的 PID(Process ID)。

进程状态:
R = Running / Runnable 正在运行或可运行
S = Sleeping (Interruptible) 可中断睡眠
D = Sleeping (Uninterruptible) 不可中断睡眠(通常等待I/O)
T = Stopped 已停止(被 Ctrl+Z 暂停)
Z = Zombie 僵尸进程(已完成但未被回收)

7.2 查看进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# ps — 查看进程快照
ps # 当前 shell 的进程,ps 不带参数只显示当前终端、当前用户的进程
ps aux # 所有用户的所有进程(BSD 风格,最常用),列用 %CPU、%MEM、VSZ、RSS 等,统计多
ps -ef # 所有进程(Linux 风格),列用 PPID 更清晰,没有资源统计,常用于查父子关系用

# ps aux 输出解读:
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 1 0.0 0.1 168196 11440 ? Ss Jun15 0:05 /sbin/init

# 常用组合:
ps aux | grep nginx # 查找 nginx 相关进程
ps -fp $(pgrep nginx) # 查看 nginx 进程的详细信息,先 pgrep nginx 找出所有 nginx 的 PID, 再 ps -fp 以详细格式(-f 全格式,-p 指定 PID)查看这些进程信息。比 ps aux | grep nginx 更精准,不会把 grep 自己也算进去。
ps aux --sort=-%mem | head # 按内存使用排序
ps aux --sort=-%cpu | head # 按 CPU 使用排序

# pgrep — 按名称查找进程 PID
pgrep nginx
pgrep -u alice # 查看 alice 的所有进程
pkill nginx # 按名称终止进程

# top — 实时进程监控(按 q 退出)
top
# top 快捷键:
# 1 显示/隐藏每个 CPU 核心的使用情况
# M 按内存使用排序
# P 按 CPU 使用排序
# k 输入 PID 终止进程
# q 退出

# htop — 更友好的 top(需安装)
sudo apt install htop
htop

7.3 前台与后台

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 在后台运行命令
sleep 100 & # & 表示在后台运行
# [1] 12345 # [任务编号] PID

# 查看后台任务
jobs
# [1] + Running sleep 100 &

# 将后台任务调到前台
fg %1 # fg %任务编号

# 将前台任务放到后台
# 1. Ctrl+Z 暂停当前任务
# 2. bg %1 将暂停的任务在后台继续运行

# nohup — 退出终端后程序继续运行
nohup ./long-script.sh &
nohup python3 server.py > output.log 2>&1 &

# disown — 将后台任务从任务列表中移除(终端关闭后继续运行)
disown %1

7.4 终止进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 信号机制
# SIGTERM (15) = 请求正常终止(默认)
# SIGKILL (9) = 强制终止(不能被捕获或忽略)
# SIGINT (2) = 中断信号(相当于 Ctrl+C)
# SIGHUP (1) = 挂断信号(常用于让守护进程重新加载配置)

# kill — 向进程发送信号
kill 1234 # 发送 SIGTERM(优雅终止)
kill -15 1234 # 同上(显式指定)
kill -9 1234 # 强制终止 SIGKILL(最后手段)
kill -HUP 1234 # 发送 SIGHUP(常用于重载配置)
kill -l # 列出所有信号

# killall — 按名称终止
killall nginx # 终止所有名为 nginx 的进程
killall -9 node # 强制终止所有 node 进程

# pkill — 按名称/模式终止
pkill -f "python server.py" # 匹配完整命令
pkill -u alice # 终止 用户alice 的所有进程

7.5 进程优先级

1
2
3
4
5
6
7
8
9
# nice — 以指定优先级启动
# 优先级范围: -20 (最高优先级) 到 19 (最低优先级)
nice -n 10 ./cpu-heavy-task # 以较低优先级运行
nice -n -10 ./important-task # 需要 root 权限

# renice — 修改运行中进程的优先级
sudo renice -n 5 -p 1234 # 修改 PID 1234 的优先级

# 在 top 中按 r 也可以修改优先级

8. 软件包管理 (apt)

8.1 APT 体系

Debian/Ubuntu 使用 APT (Advanced Package Tool) 管理软件包,底层是 dpkg。

1
2
3
4
APT 工作流程:

sources.list ──→ apt update ──→ 本地包缓存 ──→ apt install pkg
(软件源地址) (下载索引) (包信息数据库) (下载并安装)

8.2 包管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 更新相关
sudo apt update # 更新软件包索引(元数据)
sudo apt upgrade # 升级所有可升级的软件包
sudo apt full-upgrade # 升级,必要时卸载冲突包
sudo apt autoremove # 自动删除不再需要的依赖包
sudo apt autoclean # 清理下载的包缓存

# 安装与卸载
sudo apt install nginx # 安装
sudo apt install -y nginx # 自动确认(-y 跳过确认提示)
sudo apt install ./package.deb # 安装本地 deb 包(自动处理依赖)

sudo apt remove nginx # 卸载(保留配置文件)
sudo apt purge nginx # 完全卸载(包括配置文件)
sudo apt remove --purge nginx # 同上

# 搜索与信息
apt search nginx # 搜索软件包
apt show nginx # 显示包详细信息
apt list --installed # 列出已安装的包
apt list --upgradable # 列出可升级的包

# dpkg — 底层包管理
dpkg -l # 列出所有已安装的包
dpkg -l | grep nginx
dpkg -L nginx # 列出包安装的所有文件
dpkg -S /usr/bin/nginx # 查看文件属于哪个包
sudo dpkg -i package.deb # 安装本地 deb(不处理依赖)

8.3 软件源配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Ubuntu 官方源配置文件
cat /etc/apt/sources.list

# 格式:
# deb [选项] URL 发行版 组件
# deb http://archive.ubuntu.com/ubuntu/ jammy main restricted universe multiverse

# 常见源(镜像):
# 清华: https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
# 阿里: https://mirrors.aliyun.com/ubuntu/
# 中科大: https://mirrors.ustc.edu.cn/ubuntu/

# 更换源的步骤(以 Ubuntu 22.04 LTS jammy 为例):
sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup
sudo sed -i 's|http://archive.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list
sudo apt update

8.4 Snap 与 Flatpak

1
2
3
4
5
6
7
8
9
# Snap(Ubuntu 默认支持)
snap find vscode
sudo snap install vscode --classic
snap list

# Flatpak(需要手动安装支持)
sudo apt install flatpak
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install flathub com.visualstudio.code

9. 文本处理

9.1 文本查看与搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# grep — 文本搜索(最常用的命令之一)
grep "error" app.log # 在文件中搜索
grep -i "error" app.log # 忽略大小写
grep -v "debug" app.log # 反向匹配(不包含的)
grep -r "TODO" src/ # 递归搜索目录
grep -rn "TODO" src/ # 递归 + 显示行号
grep -c "error" app.log # 统计匹配行数
grep -A 3 "error" app.log # 显示匹配行及之后 3 行
grep -B 3 "error" app.log # 显示匹配行及之前 3 行
grep -C 3 "error" app.log # 显示匹配行及前后各 3 行
grep -E "(error|warning)" app.log # 扩展正则(-E = egrep)
grep -P "\d{3}-\d{4}" file.txt # Perl 正则(最强大)

# 结合管道(grep 最经典用法)
ps aux | grep nginx
history | grep "git"
dpkg -l | grep python

9.2 文本处理三剑客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# ─── sed — 流编辑器(查找替换为主) ───
sed 's/old/new/' file.txt # 替换每行第一个匹配
sed 's/old/new/g' file.txt # 替换所有匹配(g = global)
sed 's/old/new/gi' file.txt # 替换所有匹配,忽略大小写
sed -i 's/old/new/g' file.txt # 直接修改文件(-i = in-place),不加 -i 的话,修改后的内 容只输出到终端,原文件不动。加了 -i,直接写回原文件,终端 不显示任何输出,文件内容已变更。
sed -i.backup 's/old/new/g' file.txt # 修改前备份为 file.txt.backup
sed '5,10s/old/new/g' file.txt # 只替换第 5-10 行
sed '/pattern/s/old/new/g' file.txt # 只替换匹配 pattern 的行
sed '/^$/d' file.txt # 删除空行
sed -n '5,10p' file.txt # 输出第 5-10 行
sed '1i\# Header' file.txt # 在第一行前插入

# ─── awk — 文本分析工具 ───
awk '{print $1}' file.txt # 打印每行的第 1 列(默认按空格分割)
awk '{print $1, $3}' file.txt # 打印第 1 和第 3 列
awk -F: '{print $1, $7}' /etc/passwd # 用 : 作为分隔符
awk '{sum += $1} END {print sum}' file # 计算第一列的总和
awk 'NR>=5 && NR<=10' file.txt # 打印第 5-10 行
awk '$3 > 100' file.txt # 第三列大于 100 的行
awk '/error/ {count++} END {print count}' app.log # 统计包含 error 的行数

# ─── sort — 排序 ───
# sort 把文件的行按字母/数字顺序重新排列,每行是一个完整单位。默认按行首字母排序
sort file.txt # 按字母排序
sort -n file.txt # 按数字排序
sort -r file.txt # 倒序
sort -u file.txt # 去重
sort -t: -k2 /etc/passwd # 按 : 分隔后第 2 列排序
sort -h sizes.txt # 人类可读格式排序 (1K, 2M, 1G)

# ─── uniq — 去重 ───
uniq file.txt # 去除相邻重复行(通常需要先 sort)
sort file.txt | uniq # 先排序再去重
sort file.txt | uniq -c # 去重并统计出现次数
sort file.txt | uniq -d # 只显示重复的行

# ─── cut — 截取列 ───
cut -d: -f1 /etc/passwd # 以 : 分隔,取第 1 列
cut -c1-10 file.txt # 取每行的第 1-10 个字符
cut -d',' -f1,3 data.csv # 取 CSV 的第 1 和第 3 列

# ─── tr — 字符转换/删除 ───
echo "hello" | tr 'a-z' 'A-Z' # 小写转大写
echo "hello world" | tr ' ' '\n' # 空格转换行
echo "hello world" | tr -s ' ' # 压缩连续空格
echo "abc123def" | tr -d '0-9' # 删除所有数字

# ─── xargs — 将标准输入转为命令行参数 ───
find . -name "*.txt" | xargs rm # 删除所有找到的 .txt 文件
find . -name "*.log" | xargs grep "error" # 在所有 .log 中搜索 error
echo "file1 file2 file3" | xargs -n 1 cp -t dest/

9.3 重定向与管道

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 标准流:
# 标准输入 (stdin) = 0 默认: 键盘
# 标准输出 (stdout) = 1 默认: 终端
# 标准错误 (stderr) = 2 默认: 终端

# ─── 重定向 ───
# 输出重定向
command > file # 覆盖写入(标准输出)
command >> file # 追加写入(标准输出)
command 2> file # 只重定向标准错误
command &> file # 同时重定向标准输出和标准错误

# 输入重定向
command < file # 从文件读取输入
command << EOF # Here Document:读取多行直到 EOF
多行内容
EOF

# 示例:
ls -la > listing.txt # 保存输出到文件
echo "new line" >> file.txt # 追加到文件
grep "error" app.log 2>/dev/null # 屏蔽错误信息
command > output.log 2>&1 # 输出和错误都写入同一文件

# /dev/null — 数据黑洞(舍弃写入的内容)
command > /dev/null 2>&1 # 完全静默执行

# ─── 管道 (|) ───
# 将前一个命令的标准输出作为后一个命令的标准输入

command1 | command2 | command3

# 实用示例:
cat /var/log/syslog | grep "error" | less
ps aux | grep nginx | awk '{print $2}'
find . -type f | wc -l # 统计文件数量
dpkg -l | grep "^ii" | wc -l # 统计已安装包数
history | awk '{print $2}' | sort | uniq -c | sort -rn | head -10 # 最常用的10条命令

9.4 Vim 速成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 启动(至少学会退出!)
vim file.txt # 打开文件
vim +10 file.txt # 打开并跳到第 10 行

# 三种模式:
# Normal 模式(默认,按键是命令)
# Insert 模式(按 i 进入,正常打字)
# Visual 模式(按 v 进入,选择文本)

# Normal 模式常用命令:
i # 进入插入模式(光标前)
a # 进入插入模式(光标后)
o # 下方新建行并进入插入模式
O # 上方新建行并进入插入模式
Esc # 回到 Normal 模式
:w # 保存
:q # 退出
:wq / ZZ # 保存并退出
:q! # 不保存强制退出
dd # 删除(剪切)当前行
yy # 复制当前行
p # 粘贴
u # 撤销
Ctrl+r # 重做
/pattern # 搜索(按 n 下一个,N 上一个)
:%s/old/new/g # 全局替换
gg # 跳到文件开头
G # 跳到文件末尾
:10 # 跳到第 10 行

10. Shell 基础

10.1 变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 定义变量(注意 = 两边不能有空格!)
name="Alice"
count=42

# 使用变量
echo $name # Alice
echo ${name} # 加花括号更安全
echo "Hello, ${name}" # 字符串中使用

# 环境变量 vs 局部变量
local_var="only here" # 局部变量(只在当前 shell 有效)
export GLOBAL_VAR="everywhere" # 环境变量(子进程也可访问)

# 常见环境变量
echo $HOME # 主目录
echo $USER # 当前用户名
echo $PATH # 命令搜索路径
echo $PWD # 当前工作目录
echo $SHELL # 当前 shell

# 修改 PATH
export PATH="$HOME/bin:$PATH" # 临时
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc # 永久

# 命令执行结果赋值
files=$(ls | wc -l)
today=`date +%Y-%m-%d`
echo "Today is $today"

10.2 引号规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 三种引号的区别

# 单引号:一切内容原样输出(不解析变量和命令)
echo '$HOME is $HOME' # 输出: $HOME is $HOME

# 双引号:解析变量和命令,保留空格
echo "$HOME is home" # 输出: /home/alice is home

# 反引号 / $():执行命令并获取输出
echo "Today is $(date)" # 输出: Today is Mon Jun 16 14:30:00 2026
echo "Today is `date`" # 同上(旧语法,推荐用 $())

# ⚠️ 引号在文件处理中极其重要
# 文件名包含空格时必须用引号
mv "my file.txt" "new name.txt"

10.3 条件判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 基本语法
if [ condition ]; then
commands
elif [ condition ]; then
commands
else
commands
fi

# 字符串比较
[ "$a" = "$b" ] # 等于
[ "$a" != "$b" ] # 不等于
[ -z "$a" ] # 字符串为空
[ -n "$a" ] # 字符串非空

# 数字比较
[ "$a" -eq "$b" ] # 等于
[ "$a" -ne "$b" ] # 不等于
[ "$a" -gt "$b" ] # 大于
[ "$a" -lt "$b" ] # 小于
[ "$a" -ge "$b" ] # 大于等于
[ "$a" -le "$b" ] # 小于等于

# 文件测试
[ -f "$file" ] # 是否为普通文件
[ -d "$file" ] # 是否为目录
[ -e "$file" ] # 文件是否存在
[ -r "$file" ] # 是否可读
[ -w "$file" ] # 是否可写
[ -x "$file" ] # 是否可执行
[ -s "$file" ] # 文件是否非空

# 逻辑运算
[ "$a" -gt 0 ] && [ "$b" -lt 10 ] # AND
[ "$a" -gt 0 ] || [ "$b" -lt 10 ] # OR

# 现代替代(更安全,推荐):
[[ $a -gt 0 && $b -lt 10 ]]

10.4 循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# for 循环
for i in 1 2 3 4 5; do
echo "Number: $i"
done

for i in {1..10}; do
echo $i
done

for file in *.txt; do
echo "Processing $file"
done

# while 循环
count=1
while [ $count -le 5 ]; do
echo "Count: $count"
count=$((count + 1))
done

# 读取文件逐行处理
while IFS= read -r line; do
echo "Line: $line"
done < file.txt

10.5 Shell 脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash
# 上面一行是 shebang,指定解释器

# 脚本示例:备份工具
# 用法:./backup.sh source_dir backup_dir

set -euo pipefail # 最佳实践:遇错即停,未定义变量报错

SOURCE_DIR="${1:?请指定源目录}" # 第一个参数,为空则报错
BACKUP_DIR="${2:?请指定备份目录}" # 第二个参数
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/backup_${DATE}.tar.gz"

echo "正在备份 $SOURCE_DIR$BACKUP_FILE ..."

tar -czf "$BACKUP_FILE" "$SOURCE_DIR"

if [ $? -eq 0 ]; then
echo "备份成功: $BACKUP_FILE"
echo "文件大小: $(du -h "$BACKUP_FILE" | cut -f1)"
else
echo "备份失败!"
exit 1
fi

# 赋予执行权限并运行
# chmod +x backup.sh
# ./backup.sh ~/Documents ~/Backups

10.6 别名与函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# alias — 命令别名
alias ll='ls -alF'
alias la='ls -A'
alias ..='cd ..'
alias ...='cd ../..'
alias update='sudo apt update && sudo apt upgrade'
alias gs='git status'
alias gc='git commit'

# 查看所有别名
alias

# 永久别名(添加到 ~/.bashrc)
echo "alias ll='ls -alF'" >> ~/.bashrc
source ~/.bashrc # 重新加载

# 函数(比别名更强大,支持参数)
# 添加到 ~/.bashrc
mkcd() {
mkdir -p "$1" && cd "$1"
}
# 用法: mkcd new-project

extract() {
if [ -f "$1" ]; then
case "$1" in
*.tar.gz) tar xzf "$1" ;;
*.zip) unzip "$1" ;;
*.tar) tar xf "$1" ;;
esac
fi
}

11. 网络操作

11.1 网络基础命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# ip — 查看/配置网络(取代旧的 ifconfig)
ip addr show # 查看 IP 地址(简写: ip a)
ip link show # 查看网络接口状态
ip route show # 查看路由表

# ping — 测试连通性
ping google.com
ping -c 4 8.8.8.8 # 发送 4 个包后停止
ping -i 0.5 192.168.1.1 # 间隔 0.5 秒

# ss — 查看网络连接(取代旧的 netstat)
ss -tlnp # 查看所有监听的 TCP 端口
ss -tlnp | grep 80 # 查看 80 端口是否被监听
ss -an # 所有连接

# curl — 发送 HTTP 请求(调试 API 必备)
curl https://api.example.com
curl -X POST https://api.example.com/data -d '{"key":"value"}' -H "Content-Type: application/json"
curl -I https://example.com # 只看响应头
curl -o file.zip https://example.com/file.zip # 下载文件
curl -O https://example.com/file.zip # 下载(使用原始文件名)

# wget — 下载文件
wget https://example.com/file.zip
wget -c https://example.com/large.iso # 断点续传
wget -r https://example.com/docs/ # 递归下载整个站点

# nslookup / dig — DNS 查询
nslookup google.com
dig google.com # 更详细的 DNS 信息
dig +short google.com # 只显示 IP

# traceroute — 追踪路由
traceroute google.com

# nc (netcat) — 瑞士军刀
nc -zv 192.168.1.1 22 # 测试端口是否开放
nc -l 8080 # 在 8080 端口监听
echo "hello" | nc localhost 8000 # 发送数据

# 示例
机器 A(192.168.1.10)先监听:
nc -l 8080
机器 B(192.168.1.20)连接:
nc 192.168.1.10 8080
此时 TCP 连接已建立(三次握手完成),两边进入双向通信状态:
机器 B: 嗨,收到没?
机器 A: 嗨,收到没? ← 机器 A 屏幕上显示对方发的
机器 A: 收到了,兄弟!
机器 B: 收到了,兄弟! ← 机器 B 屏幕上显示回复
Ctrl+C 任一端断开,连接终止。全过程就是:监听 → 连接 → 互发消息 → 断开,没有协议限制,纯裸 TCP 管道。

# nmap — 端口扫描(需安装),端口扫描器,探测目标机器上哪些端口开着、跑什么服务、什么操作系统。就是查别人家开了哪些门。nc 是一次测一个端口的手动活,nmap 是自动扫一批,还附带版本、OS 识别等高级功能。
sudo apt install nmap
nmap 192.168.1.1 # 扫描常见端口
nmap -p 1-1000 192.168.1.1 # 扫描指定端口范围

11.2 SSH

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 连接到远程主机
ssh user@192.168.1.100
ssh user@example.com -p 2222 # 指定端口(默认 22)

# 生成 SSH 密钥(推荐使用 ED25519)
ssh-keygen -t ed25519 -C "your.email@example.com"
# 旧格式(兼容性更好):
ssh-keygen -t rsa -b 4096 -C "your.email@example.com"

# 复制公钥到服务器(免密码登录),ssh-copy-id 这一步需要输入密码
ssh-copy-id user@192.168.1.100

# 通过 SSH 执行远程命令
ssh user@host "ls -la /var/www"
ssh user@host "sudo systemctl restart nginx"

# SCP — 文件传输
scp file.txt user@host:/remote/path/ # 上传
scp user@host:/remote/file.txt ./local/ # 下载
scp -r folder/ user@host:/remote/path/ # 上传目录
scp -P 2222 file.txt user@host:/path/ # 指定端口(注意是大写 P)

# rsync — 同步工具(增量传输,更高效)
rsync -avz ./local/ user@host:/remote/
rsync -avz --delete ./local/ user@host:/remote/ # 删除目标多余文件
rsync -avz --exclude='node_modules' ./ user@host:/project/
# 常用选项:-a (归档), -v (详细), -z (压缩), -P (显示进度+断点续传)

11.3 防火墙 (UFW)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Ubuntu 默认的防火墙管理工具(Uncomplicated Firewall)
sudo ufw status # 查看状态
sudo ufw enable # 启用
sudo ufw disable # 禁用

sudo ufw allow 22 # 允许 SSH
sudo ufw allow 80/tcp # 允许 HTTP
sudo ufw allow 443 # 允许 HTTPS
sudo ufw allow 3000:3010/tcp # 允许端口范围
sudo ufw allow from 192.168.1.0/24 # 允许整个子网

sudo ufw deny 8080 # 拒绝 8080 端口
sudo ufw delete allow 8080 # 删除规则

sudo ufw status numbered # 带编号的规则列表
sudo ufw delete 3 # 按编号删除规则

# Docker 用户注意:UFW 对 Docker 容器端口不起作用
# 因为 Docker 直接操作 iptables,绕过了 UFW

11.4 查看日志与时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# journalctl — systemd 日志查看
journalctl # 查看所有日志
journalctl -u nginx # 查看指定服务的日志
journalctl -u nginx -f # 实时跟踪(类似 tail -f)
journalctl -u nginx --since today
journalctl -u nginx --since "2026-06-15" --until "2026-06-16"
journalctl -p err # 只显示错误及更严重级别
journalctl --disk-usage # 日志占用的磁盘空间

# 时间相关
date # 当前日期和时间
date +"%Y-%m-%d %H:%M:%S" # 格式化输出
date -d "7 days ago" # 7 天前
date -d "next Friday"

timedatectl # 查看时区等时间设置
sudo timedatectl set-timezone Asia/Shanghai # 设置时区

12. 磁盘管理

12.1 查看磁盘信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# df — 查看磁盘使用情况
df -h # 人类可读格式
df -h /home # 查看特定挂载点
df -i # 查看 inode 使用情况

# du — 查看目录/文件占用空间
du -sh * # 当前目录下每个文件/目录的大小
du -sh /home/alice # 某个目录的总大小
du -sh --max-depth=1 /var/ # 只看一层深度的子目录
du -h --max-depth=1 / 2>/dev/null | sort -h # 根目录各目录大小排序

# lsblk — 列出块设备(硬盘、分区等)
lsblk
lsblk -f # 显示文件系统类型

# blkid — 查看块设备 UUID
blkid
sudo blkid /dev/sda1

# fdisk — 查看分区表
sudo fdisk -l

12.2 挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# mount — 挂载文件系统
mount # 查看所有挂载
mount | grep /dev/sd # 查看磁盘分区挂载
sudo mount /dev/sdb1 /mnt/usb # 挂载分区到目录
sudo mount -t ext4 /dev/sdb1 /mnt/data # 指定文件系统类型

# 挂载 ISO 文件
sudo mount -o loop ubuntu.iso /mnt/iso/

# umount — 卸载
sudo umount /mnt/usb
sudo umount -l /mnt/usb # 强制卸载(lazy unmount)

# /etc/fstab — 开机自动挂载
# 格式:
# <设备> <挂载点> <类型> <选项> <dump> <pass>
# /dev/sdb1 /data ext4 defaults 0 2
# UUID=abc123-... /backup ext4 defaults,nofail 0 2
# //192.168.1.1/share /nas cifs credentials=/etc/smbcredentials,uid=1000 0 0

# 编辑 fstab 后验证(不重启即可测试)
sudo mount -a

12.3 磁盘分区与格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ⚠️ 危险操作!确保你知道每一步在做什么!

# 使用 parted(推荐,支持 GPT)
sudo parted /dev/sdb
# (parted) mklabel gpt # 创建 GPT 分区表
# (parted) mkpart primary ext4 0% 100% # 创建分区(使用整块盘)
# (parted) print # 查看
# (parted) quit

# 或使用 fdisk
sudo fdisk /dev/sdb # 进入交互式分区工具

# 格式化
sudo mkfs.ext4 /dev/sdb1 # 格式化为 ext4
sudo mkfs.vfat /dev/sdb1 # 格式化为 FAT32(U 盘)
sudo mkfs.ntfs /dev/sdb1 # 格式化为 NTFS(Windows 兼容)

# 检查与修复
sudo fsck /dev/sdb1 # 检查文件系统(必须先卸载!)

13. systemd 服务管理

13.1 基本概念

systemd 是现代 Linux 的初始化系统和服务管理器。大多数 Ubuntu 版本默认使用 systemd。

1
2
3
4
5
systemd 核心概念:
unit 系统可管理的资源(服务、挂载点、定时器等)
service 服务单元(.service),如 nginx.service
timer 定时器单元(.timer),替代 cron
target 目标单元,类似旧的运行级别

13.2 systemctl 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 服务的启动、停止、重启
sudo systemctl start nginx # 启动
sudo systemctl stop nginx # 停止
sudo systemctl restart nginx # 重启
sudo systemctl reload nginx # 重载配置(不中断服务)
sudo systemctl reload-or-restart nginx # 先尝试 reload,不支持则 restart

# 服务状态管理
sudo systemctl enable nginx # 开机自启
sudo systemctl disable nginx # 禁止开机自启
sudo systemctl is-enabled nginx # 检查是否开机自启
sudo systemctl status nginx # 查看服务详细状态

# 更多操作
sudo systemctl mask nginx # 屏蔽服务(完全禁止启动)
sudo systemctl unmask nginx # 取消屏蔽
systemctl list-units --type=service # 列出所有服务
systemctl list-units --type=service --state=running # 正在运行的服务
systemctl list-unit-files # 列出所有 unit 文件
systemctl list-timers # 列出所有定时器

# 查看启动时间和服务启动耗时
systemd-analyze # 总启动时间
systemd-analyze blame # 各服务启动耗时排行
systemd-analyze critical-chain # 关键启动链

# 日志(见第 11.4 节)
journalctl -u nginx -f

13.3 创建自定义 systemd 服务

1
2
# 创建服务文件
sudo vim /etc/systemd/system/myapp.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[Unit]
Description=My Custom Web Application
After=network.target # 在网络启动后再启动
# Requires=nginx.service # 硬依赖(nginx 必须启动)
# Wants=postgresql.service # 软依赖(尽量启动,不影响自己)

[Service]
Type=simple # simple | forking | oneshot | notify
User=myapp # 以哪个用户运行
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/node /opt/myapp/server.js
ExecStop=/bin/kill -TERM $MAINPID
Restart=on-failure # 异常退出时自动重启
RestartSec=5 # 重启间隔(秒)
Environment=NODE_ENV=production
EnvironmentFile=-/etc/myapp/config # 从文件加载环境变量(- 表示文件不存在也不报错)

# 安全加固(可选)
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes

[Install]
WantedBy=multi-user.target # 在正常多用户模式下启动
1
2
3
4
5
# 部署
sudo systemctl daemon-reload # 重载 systemd 配置
sudo systemctl enable myapp # 启用
sudo systemctl start myapp # 启动
sudo systemctl status myapp # 检查状态

14. 常用命令速查表

14.1 文件和目录

命令 说明 示例
pwd 当前目录 pwd
ls -lah 详细列表 ls -lah /var/log
cd 切换目录 cd ~/Documents
mkdir -p 递归创建目录 mkdir -p a/b/c
touch 创建空文件 touch file.txt
rm -rf 强制递归删除(危险) rm -rf /tmp/test/
cp -r 递归复制 cp -r src/ dest/
mv 移动/重命名 mv old.txt new.txt
ln -s 创建符号链接 ln -s /usr/bin/python3 py
find 查找文件 find . -name "*.log"
locate 快速查找 locate nginx.conf

14.2 文件查看与处理

命令 说明 示例
cat 显示文件 cat file.txt
less 分页查看 less large.log
head -n 头部 N 行 head -n 20 file.txt
tail -f 实时跟踪 tail -f /var/log/syslog
grep -rn 递归搜索 grep -rn "error" src/
wc -l 统计行数 wc -l file.txt
sort 排序 sort file.txt
uniq 去重 sort | uniq
sed 流编辑 sed 's/old/new/g' file
awk 文本分析 awk '{print $1}' file
diff 比较文件 diff a.txt b.txt

14.3 系统信息

命令 说明
uname -a 系统完整信息
lsb_release -a 发行版信息
uptime 运行时间+负载
free -h 内存使用
df -h 磁盘使用
du -sh * 目录大小
top / htop 进程监控
ps aux 进程列表
lscpu CPU 信息
lspci PCI 设备
lsusb USB 设备
dmesg 内核消息

14.4 网络

命令 说明
ip a IP 地址
ping -c 4 连通性测试
ss -tlnp 监听端口
curl -I HTTP 头
wget -O 下载文件
scp 文件传输
rsync -avz 增量同步
ssh user@host 远程登录
ufw status 防火墙状态

14.5 权限与用户

命令 说明
chmod 755 修改权限
chown user:group 修改所有者
whoami 当前用户
id 用户ID和组
sudo 以root执行
passwd 修改密码
usermod -aG 添加用户到组

附录:实战练习

练习 1:文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 创建项目结构
mkdir -p ~/practice/{src,docs,config,logs}
cd ~/practice

# 2. 创建文件
echo "console.log('hello');" > src/app.js
echo "# My Project" > docs/README.md
echo '{"port": 3000}' > config/settings.json

# 3. 查看结构
find . -type f | sort

# 4. 复制和链接
cp src/app.js src/app.backup.js
ln -s config/settings.json settings.json

# 5. 权限设置
chmod 600 config/settings.json
chmod 755 src/
ls -la

练习 2:文本处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 创建测试数据
cat > ~/practice/data.log << 'EOF'
2026-06-16 10:00:01 INFO Server started on port 3000
2026-06-16 10:00:05 DEBUG Database connection established
2026-06-16 10:01:00 ERROR Connection timeout on 192.168.1.1
2026-06-16 10:01:30 INFO User alice logged in
2026-06-16 10:02:00 ERROR Disk space low on /dev/sda1
2026-06-16 10:02:30 WARN Memory usage at 85%
2026-06-16 10:03:00 INFO User bob logged in
2026-06-16 10:04:00 ERROR Connection timeout on 10.0.0.5
EOF

# 过滤 ERROR
grep "ERROR" data.log

# 统计每个级别的日志数量
awk '{print $3}' data.log | sort | uniq -c

# 提取所有 IP 地址
grep -oP '\d+\.\d+\.\d+\.\d+' data.log

# 按时间排序并显示前5条
sort data.log | head -5

练习 3:进程和系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建并管理后台进程
sleep 300 &
sleep 600 &
sleep 900 &

# 查看后台任务
jobs

# 查找 sleep 进程
ps aux | grep sleep

# 终止一个 sleep 进程(用 PID)
# kill <PID>

# 查看系统资源
free -h
df -h /
uptime

练习 4:编写 Shell 脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
cat > ~/practice/cleanup.sh << 'SCRIPT'
#!/bin/bash
# 清理脚本:删除 N 天前的日志文件

set -euo pipefail

LOG_DIR="${1:-/tmp}"
DAYS="${2:-7}"

if [ ! -d "$LOG_DIR" ]; then
echo "错误: 目录 $LOG_DIR 不存在"
exit 1
fi

echo "正在清理 $LOG_DIR$DAYS 天前的 .log 文件..."

COUNT=$(find "$LOG_DIR" -name "*.log" -type f -mtime +"$DAYS" | wc -l)

if [ "$COUNT" -eq 0 ]; then
echo "没有需要清理的文件。"
exit 0
fi

echo "找到 $COUNT 个文件:"
find "$LOG_DIR" -name "*.log" -type f -mtime +"$DAYS" -ls

read -p "确认删除这些文件? (y/N): " CONFIRM
if [[ "$CONFIRM" =~ ^[Yy]$ ]]; then
find "$LOG_DIR" -name "*.log" -type f -mtime +"$DAYS" -delete
echo "清理完成。"
else
echo "已取消。"
fi
SCRIPT

chmod +x ~/practice/cleanup.sh
./cleanup.sh . 0 # 测试:显示当前目录下所有 .log 文件

学习建议:Linux 是实践性极强的技能。建议在虚拟机(如 VirtualBox + Ubuntu)或 WSL2 (Windows Subsystem for Linux) 中动手练习。遇到不熟悉的命令,先用 man commandcommand --help 查看文档,逐步建立肌肉记忆。