Рано или поздно вы попадёте на сервер, где нет ни вашего любимого редактора, ни графики, ни даже nano. Зато vi там есть всегда: это часть стандарта POSIX, и даже минимальный busybox несёт его внутри. Задача этого урока - научиться не паниковать в vi: войти, поправить конфиг, сохранить и выйти, не сломав файл. Разберём режимы, навигацию, базовую правку, поиск и замену, а в конце скажем пару слов про nano как запасной аэродром.

Как это работает
Главная идея, которая ломает мозг новичкам: vi - модальный редактор. В большинстве редакторов клавиша a печатает букву a. В vi всё зависит от текущего режима. По сути это два мира: в одном вы двигаетесь и командуете, в другом - набираете текст.
Режимов фактически четыре. Командный (он же нормальный) - стартовый режим: тут буквы это не текст, а команды (h - влево, x - удалить символ, dd - удалить строку). Режим вставки - сюда входят по i, a, o и здесь уже печатают как обычно. Визуальный режим (это уже расширение vim, в чистом vi его не было) выделяет блоки текста: входим по v, выделяем движением курсора, потом применяем операцию. И ex-режим, он же режим командной строки - всё, что начинается с двоеточия: :w, :q, :s///. Исторически ex - это строчный редактор-предок, а команды через двоеточие это обращение к нему.
Связующий клавиша - Esc. Она почти всегда возвращает в командный режим из любого другого. Привыкайте жать Esc рефлекторно, когда не уверены, где находитесь: лишний Esc в командном режиме безвреден (только пискнет).
Важно понимать разницу между vi и vim. На современных системах /usr/bin/vi - это почти всегда симлинк или обёртка на vim (Vi IMproved). Vim добавил подсветку синтаксиса, многоуровневый undo, визуальный режим, плагины. В RHEL и Fedora из коробки ставится урезанный vim-minimal (команда vi), полноценный пакет называется vim-enhanced. В Debian и Ubuntu базовый пакет vim-tiny, а полный - vim. Это объясняет, почему на одном сервере u отменяет много шагов, а на другом - только один.
Команды и примеры
Установка полной версии там, где её нет:
Код: Выделить всё
# Debian / Ubuntu
sudo apt install vim
# RHEL 10 / Fedora 41+
sudo dnf install vim-enhanced
Код: Выделить всё
h j k l влево, вниз, вверх, вправо
w / b на слово вперёд / назад
0 / $ в начало / конец строки
gg / G в начало / конец файла
:42 перейти на строку 42 (можно и 42G)
Ctrl-f страница вниз, Ctrl-b - вверх
Код: Выделить всё
i перед курсором a после курсора
I в начало строки A в конец строки
o новая строка снизу O новая строка сверху
Код: Выделить всё
x удалить символ под курсором
dd удалить (вырезать) строку целиком
yy скопировать (yank) строку в буфер
p / P вставить после / перед курсором
u отменить последнее действие
Ctrl-r вернуть отменённое (redo)
. повторить последнюю команду правки
Поиск и замена. Поиск - слэш вперёд, вопрос назад; n повторяет в ту же сторону, N в обратную:
Код: Выделить всё
/error искать error вниз
?error искать вверх
n / N следующее / предыдущее совпадение
Код: Выделить всё
:s/foo/bar/ заменить ПЕРВЫЙ foo в текущей строке
:s/foo/bar/g заменить ВСЕ foo в текущей строке (g = global по строке)
:%s/foo/bar/g во ВСЁМ файле (% = все строки)
:%s/foo/bar/gc то же, но спрашивать подтверждение каждой замены
:10,20s/foo/bar/g только в строках с 10 по 20
Код: Выделить всё
:w записать (сохранить), остаться в файле
:q выйти, если нет несохранённых правок
:wq записать и выйти (то же, что :x или ZZ)
:q! выйти БЕЗ сохранения, отбросить правки
:w! записать принудительно (если права позволяют)
:w файл сохранить под другим именем
Код: Выделить всё
:w !sudo tee % > /dev/null
- Печатаете команды в режиме вставки и наоборот. Признак: в тексте вдруг появляются буквы dd, :wq. Лекарство одно - Esc, потом u для отката.
- Застряли и не можете выйти. Классика. Жмёте Esc, затем :q! - выход без сохранения гарантированно работает.
- Вставка из буфера обмена терминала ломает отступы: автоиндент дублирует пробелы лесенкой. Перед вставкой включите :set paste, после - :set nopaste.
- Caps Lock включён - hjkl превращаются в команды H, J, L, M (это другие действия), правка едет вкривь.
- Открыли файл, vim ругается на .swp (swap-файл): значит, прошлая сессия рухнула или файл уже открыт в другом окне. Выберите (R)ecover чтобы восстановить, или (D)elete если правок там не было.
- :wq на файле, открытом без прав, молча не сохраняет или ругается E212. Это не баг - просто нет прав; выходите через sudoedit или трюк с tee.
- Путаете :s/// без флага g (меняет только первое вхождение в строке) с полной заменой. Для всего файла нужно именно :%s///g.
- Создайте файл командой printf 'one\ntwo\nthree\nfour\nfive\n' > lab.txt и откройте его: vi lab.txt.
- Перейдите на последнюю строку (G), создайте под ней новую строку (o), впишите six, вернитесь в командный режим (Esc).
- Скопируйте первую строку: gg, потом yy. Перейдите в конец (G) и вставьте (p). Удалите вставленную строку (dd).
- Сделайте замену по всему файлу: :%s/o/0/g - посмотрите, как поменялись все o на нули. Отмените всё это несколькими u.
- Найдите слово five через /five, нажмите n и посмотрите, как поиск зацикливается.
- Сохраните и выйдите через :wq. Откройте заново и попробуйте выйти без изменений через :q, затем внесите правку и выйдите через :q!.
- Чем командный режим vi отличается от режима вставки и какой клавишей всегда возвращаются в командный?
- Что делает команда :%s/old/new/gc и за что отвечают флаги g и c?
- Какая команда удалит три строки за раз и как она устроена (оператор плюс счётчик)?
- Чем :q отличается от :q! и :wq?
- Что означает swap-файл при открытии и какие действия предлагает vim, если он найден?
- Почему на минимальном сервере стоит рассчитывать именно на vi, а не на nano?