一、tmux — 终端复用器

它解决什么问题

SSH 连接到远程服务器时,一旦网络断开或关闭终端窗口,正在运行的程序(比如 hugo serverapt install)会被强制终止。

tmux 在用户和服务器之间插入了一个持久层——你关掉终端、断开 SSH,tmux 里的程序继续跑。下次连上,tmux a 一切恢复原样。

普通 SSH:                      SSH + tmux:

  你 ──SSH── 服务器                你 ──SSH── 服务器
              │                              │
              跑程序                         tmux(持久层)
              │                              │
  SSH 断开 → 程序死                  SSH 断开 → tmux 里的程序继续跑
                                      下次连上 → tmux a → 恢复

层级结构

tmux 服务
├── session 0(工作区 A:博客开发)
│   ├── window 0(这个窗口跑 hugo server)
│   │   ├── pane 0(左边:编辑 config.yml)
│   │   └── pane 1(右边:看日志)
│   └── window 1(这个窗口跑 docker)
│       └── pane 0
├── session 1(工作区 B:渗透练习)
│   ├── window 0(DVWA 目录)
│   └── window 1(查资料)
└── session 2

session = 独立工作区,window = 浏览器标签页,pane = 分屏。 你在一个 session 里"挂起"(detach),另一个终端可以"接入"(attach),无缝切换。

前缀键:Ctrl+A

tmux 所有快捷键都先按一次前缀键(告诉 tmux"下一个按键是给你的,不是给终端里的程序的"),再按功能键。默认前缀是 Ctrl+B,但这里改成 Ctrl+A——离手指更近,按着更舒服。

操作节奏:按下 Ctrl+A → 松开手指 → 按下一个键。 不是同时按;是先后按。

完整操作速查

操作 快捷键 说明
新建 session tmux 创建一个 session,默认带一个 window 和一个 pane
左右分屏 Ctrl+A 然后 % 当前 pane 左右平分
上下分屏 Ctrl+A 然后 " 当前 pane 上下平分
关闭 pane Ctrl+D pane 全关了 → 关 window;window 全关了 → 关 session
选 pane(鼠标) 鼠标点击 直接定位
选 pane(键盘) Ctrl+A 然后 方向键 相邻 pane 间移动
调分割线(鼠标) 拖拽分割线 最直观
调分割线(键盘) Ctrl+A + 方向键(按住不放) 微调
全屏/取消 Ctrl+A 然后 z 当前 pane 临时撑满整个窗口
挂起 session Ctrl+A 然后 d detach——session 在后台继续跑,你回到普通终端
恢复 session tmux a attach——一切恢复
选择 session Ctrl+A 然后 s 方向键上下选、右展开、左收起
新建 window Ctrl+A 然后 c 在当前 session 里开新标签页
选择 window Ctrl+A 然后 w 同 session 选择方式
翻阅内容 Ctrl+A 然后 PageUp 或 鼠标滚轮 查看历史输出
文本选择 按住 Shift + 鼠标拖拽 tmux 里不按 Shift 拖拽会触发 tmux 自己的选择模式
复制 Ctrl+A 然后 [ → 鼠标选文本(自动复制) 进入 tmux 的复制模式
粘贴 Ctrl+A 然后 ] 粘贴 tmux 剪贴板内容

二、vim — 终端里的文本编辑器

为什么学 vim

服务器上没有图形界面,没有 VS Code。改配置文件、写脚本、编辑代码——全在终端里完成。vim 是 Linux 世界最通用的终端编辑器,任何一台 Linux 都预装了 vi(vim 的前身)

vim 不是"简陋版记事本"。它的核心哲学是:大部分时间在阅读/浏览代码,少数时间在修改。 所以默认处于"只读浏览模式"(一般命令模式),而不是"打字模式"(编辑模式)。

三种模式

┌────────── 一般命令模式 ──────────┐
│  (默认状态,按什么键触发什么动作) │
│  浏览、复制、粘贴、删除、跳转      │
│                                   │
│  按 i → 进入编辑模式               │
│  按 : 或 / → 进入命令行模式         │
└──────────┬──────────────┬────────┘
           │              │
           ▼              ▼
    ┌── 编辑模式 ──┐  ┌── 命令行模式 ──┐
    │  正常打字     │  │  保存、退出     │
    │  ESC → 退回   │  │  查找、替换     │
    └──────────────┘  │  ESC → 退回     │
                      └────────────────┘

移动光标

操作 按键 记忆技巧
h 在最左边
j j 像往下的钩子
k k 像往上指
l 在最右边
右移 n 个字符 n<Space>
行首 0Home
行尾 $End 正则里 $ 就是行尾
文件最后一行 G
文件第一行 gg
第 n 行 nG:n
向下 n 行 n<Enter>

查找与替换

操作 命令 说明
向下找 word /word n 下一个,N 上一个
向上找 word ?word
第 n1 到 n2 行替换 :n1,n2s/word1/word2/g g = 每行全部替换
全文替换 :1,$s/word1/word2/g 1,$ = 第一行到最后一行
全文替换(逐个确认) :1,$s/word1/word2/gc 每次替换前 y/n 确认
关闭高亮 :noh 查找后的高亮不消失,用这个关

复制、剪切、粘贴、删除

vim 里的"删除"本质是"剪切"——被删的内容自动进入寄存器,可以 p 粘贴出来。

操作 按键
选中文本 v + 方向键移动
复制选中 y
复制整行 yy
删除选中(剪切) d
删除整行(剪切) dd
粘贴 p(光标下一行/下一位置)
撤销 u
重做(取消撤销) Ctrl+R

缩进与格式化

操作 按键
选中后右缩进 v 选中 → >
选中后左缩进 v 选中 → <
全文自动格式化 gg=G

保存、退出、配置

操作 命令
保存 :w
强制保存 :w!
退出 :q
强制退出(不保存) :q!
保存并退出 :wq
显示行号 :set nu
隐藏行号 :set nonu
粘贴模式(不自动缩进) :set paste
取消粘贴模式 :set nopaste
卡死时强制中断 Ctrl+Q

.swp 文件异常处理

每次用 vim 打开文件,vim 自动创建一个 .filename.swp 的临时文件用于崩溃恢复。如果 vim 异常退出,.swp 残留,下次打开会报警。

解决方法:
  1. 找到另一个正在编辑该文件的 vim 进程,退出它
  2. 或者直接删掉 .swp 文件:rm .filename.swp

三、vim 作业题解

homework_0

进入 homework_0,创建 names.txt,写入姓名,每行一个:
  cd homework_0
  vim names.txt
  按 i 进入编辑模式,输入:
    AcWing
    yxc
    Bob
    张强
    李明
    Alice
  按 ESC,输入 :wq 保存退出

homework_1

cd homework_1
vim problem.txt

[1] 最后一行第101个字符:G(跳到最后一行)→ 100<Space>(右移100个字符,光标在第101个)
    → d(删除当前字符)

[2] 第3行第8个字符:3G(跳到第3行)→ 7<Space>(右移7个字符,光标在第8个)
    → d

[3] 第1行第30个字符:gg(跳到第1行)→ 29<Space> → d

[4] 第16行第55个字符:16G → 54<Space> → d

[5] 第9行第80个字符:9G → 79<Space> → d

:wq 保存退出

homework_2

cd homework_2
vim problem.txt

[1] 在第1个"two"后面添加"abc"
    /two<Enter>(找到第1个two)→ e(光标跳到单词末尾)→ i(进入编辑模式)→ 输入abc → ESC

[2] 在第2个"two"前面添加"def"
    n(跳到第2个two)→ i(进入编辑模式)→ 输入def → ESC

[3] 将第3个"two"后面的连续12个字符删掉
    n(跳到第3个two)→ e(跳到单词末尾)→ l(右移一个字符,到要删除的第一个字符)
    → v → 11<Space>(选中12个字符)→ d

[4] 将第4个"two"所在的行删掉
    n(跳到第4个two)→ dd

:wq 保存退出

homework_3

cd homework_3
vim problem.txt

[1] 将第5行至15行中所有of替换成OF
    :5,15s/of/OF/g

[2] 将全文中所有the替换成THE
    :1,$s/the/THE/g

[3] 将全文中的is奇数不变,偶数变为IS
    :1,$s/is/IS/gc
    (然后 n(n不替换) y(替换) 交替按,实现奇数不变偶数替换)

:wq 保存退出

homework_4

cd homework_4
vim problem.txt

[1] 删除第11行:11G(跳到第11行)→ dd

[2] 粘贴到文件末尾下一行:G(跳到最后一行)→ p

[3] 复制第5行:5G(跳到第5行)→ yy

[4] 粘贴到文件末尾下一行:G → p

:wq 保存退出

homework_5

cd homework_5
vim problem.txt

[1] 删除第11行第15个字符至第13行第5个字符:
    11G → 14<Space>(光标在第11行第15个字符)
    → v(进入可视模式)→ 13G → 5<Space>(选到第13行第5个字符)
    → d(删除选中内容)

[2] 粘贴到文件末尾(不另起一行):
    G → $(跳到最后一行的行尾)→ p

[3] 复制第5行第88个字符至第7行第6个字符:
    5G → 87<Space>(光标在第5行第88个字符)
    → v → 7G → 6<Space>(选到第7行第6个字符)
    → y(复制选中内容)

[4] 粘贴到文件末尾(不另起一行):
    G → $ → p

:wq 保存退出

homework_6

cd homework_6

[1] 清空 source0.cpp:
    vim source0.cpp → gg(跳到第一行)→ dG(从当前行删到文件末尾)
    → :wq 保存退出
    或者直接:> source0.cpp

[2] 将 source1.cpp 中的第1-3行和第12-24行复制到 source0.cpp:
    vim source1.cpp
    → gg(跳到第一行)→ v → 3G(选到第3行末尾)→ y
    → :q 退出

    vim source0.cpp
    → p(粘贴第1-3行)
    → :wq 退出

    vim source1.cpp
    → 12G → v → 24G → y
    → :q 退出

    vim source0.cpp
    → G(跳到最后)→ p
    → :wq 保存退出

homework_7

cd homework_7
vim source.cpp
gg=G(全文格式化)
:wq 保存退出

homework_8

cd homework_8
vim source.cpp

[1] 将第15-21行向右缩进2次:
    15G → v → 21G → >(第一次缩进)
    15G → v → 21G → >(第二次缩进)
    或:15Gv21G> 执行两次

[2] 将第22-23行向左缩进1次:
    22G → v → 23G → <

:wq 保存退出

homework_9

cd homework_9
浏览器打开链接:https://www.acwing.com/activity/content/code/content/1694465/
复制全部代码
vim source.cpp
按 i 进入编辑模式
右键粘贴(或 Ctrl+Shift+V)
ESC
:wq 保存退出

四、tmux + vim 的组合使用场景

# 1. 连上服务器
ssh mycvm

# 2. 启动 tmux(如果已有 session,用 tmux a 恢复)
tmux

# 3. 左 pane 编辑代码
Ctrl+A 然后 %

# 4. 右 pane 跑程序/看日志
Ctrl+A 然后 方向键右 → 到这个 pane → 运行命令

# 5. 编辑时:左边 vim 写代码,右边 tail -f 看日志
#    左边修改保存,右边立刻看到效果

# 6. 下班了,断开连接
Ctrl+A 然后 d(挂起)→ 关闭终端 → 回家

# 7. 到家后再连上
ssh mycvm → tmux a → 一切还是下班前那样

本文基于 ACWing Linux 基础课笔记整理,作业题解已补全。