Мультиплексоры терминала: tmux и screen

Как не потерять длинную сборку или миграцию, если SSH-соединение оборвётся, и как держать несколько рабочих контекстов в одном окне.

Мультиплексор терминала (tmux, screen) — программа, которая держит ваши сессии оболочки живыми на сервере независимо от подключения: вы можете «отсоединиться» (detach), закрыть ноутбук, а позже «присоединиться» (attach) и застать процессы ровно там, где их оставили.

Сценарий, знакомый каждому, кто работал с серверами: вы запустили по SSH часовую миграцию базы или сборку, и тут Wi-Fi моргнул — соединение оборвалось, дочерний процесс получил SIGHUP и умер вместе с оболочкой. Всё насмарку. Мультиплексор решает это радикально: процессы живут внутри него, на сервере, и переживают разрыв связи. Бонусом вы получаете несколько окон и панелей в одном терминале — фактически оконный менеджер для текста.

Главная суперсила: detach и attach

Это причина, по которой tmux ставят в первую очередь. Запустите сессию, начните долгую задачу, отсоединитесь — и процесс продолжит работать на сервере сам по себе:

tmux                          # запустить новую сессию tmux
# внутри сессии стартуем долгую задачу:
./long_migration.sh
# отсоединяемся, НЕ прерывая задачу: Ctrl-b, затем d

# ...можно закрыть ноутбук, переподключиться по SSH позже...

tmux ls                       # список живых сессий
tmux attach                   # вернуться в последнюю сессию
tmux attach -t 0              # вернуться в конкретную сессию по имени/номеру

После attach вы увидите тот же экран и работающий процесс. Именно поэтому правило хорошего тона: любую длительную операцию по SSH (сборка, миграция, импорт, обновление) запускают внутри tmux/screen — тогда разрыв связи ей не страшен.

Модель tmux: сессии, окна, панели

Иерархия из трёх уровней:

  • Сессия (session) — самостоятельный набор окон; именно она переживает detach. Сессий может быть несколько (например, одна на проект).
  • Окно (window) — как вкладка: занимает весь экран, в сессии их много, листаются по номерам.
  • Панель (pane) — окно можно разбить на несколько панелей, видимых одновременно (логи слева, редактор справа).

Префиксная клавиша и базовые горячие клавиши

tmux ловит команды через префикс — по умолчанию Ctrl-b: вы нажимаете его, отпускаете и затем жмёте командную клавишу. Самый нужный минимум:

СочетаниеДействие
Ctrl-b затем ddetach — отсоединиться от сессии
Ctrl-b затем cсоздать новое окно
Ctrl-b затем 0..9переключиться на окно по номеру
Ctrl-b затем n / pследующее / предыдущее окно
Ctrl-b затем %разбить панель вертикально
Ctrl-b затем "разбить панель горизонтально
Ctrl-b затем стрелкаперейти в соседнюю панель
Ctrl-b затем [режим прокрутки/копирования (выход — q)

Часть тех же действий доступна из командной строки — это удобно в скриптах и для именованных сессий:

tmux new -s deploy            # создать именованную сессию «deploy»
tmux attach -t deploy         # присоединиться к ней по имени
tmux kill-session -t deploy   # завершить сессию
tmux split-window -h          # разбить активное окно по вертикали

screen: классическая альтернатива

screen старше tmux и часто уже стоит на серверах. Идея та же, но префикс — Ctrl-a, и панелей в привычном виде нет (есть разбиение, но беднее). Базовый набор:

screen -S build              # новая именованная сессия
# detach:  Ctrl-a, затем d
# новое окно: Ctrl-a, затем c
# след/пред окно: Ctrl-a, затем n / p

screen -ls                   # список сессий
screen -r build              # вернуться (reattach) в сессию build
screen -d -r build           # отсоединить от другого терминала и забрать себе

Когда что: tmux — современнее, удобнее панели, активно развивается, гибкий конфиг; screen — минимализм и «оно уже здесь». Для повседневной работы обычно выбирают tmux, screen держат в уме как запасной вариант на чужом сервере.

Конфиг tmux.conf

Поведение tmux настраивается в ~/.tmux.conf. Самая частая правка — перенос префикса на Ctrl-a (как в screen, удобнее для пальцев) и включение мыши:

cat > ~/.tmux.conf <<'EOF'
# префикс Ctrl-a вместо Ctrl-b
unbind C-b
set -g prefix C-a
bind C-a send-prefix

# мышь: клик по панели, прокрутка колесом
set -g mouse on

# нумеровать окна с 1, а не с 0
set -g base-index 1

# больше истории прокрутки
set -g history-limit 10000
EOF

# применить конфиг к запущенному tmux:
tmux source-file ~/.tmux.conf

Как это работает под капотом

Секрет живучести — в архитектуре «клиент-сервер». При первом запуске tmux поднимает на машине фоновый процесс — tmux server; именно он, а не ваш терминал, владеет всеми сессиями, окнами и запущенными в них процессами. Каждая оболочка внутри tmux работает не в обычном терминале, а в псевдотерминале (pty), который держит сервер. Команда tmux в окне — это лишь тонкий клиент, который подключается к серверу и рисует его картинку. Поэтому detach — это всего-навсего отключение клиента: сервер и его pty продолжают жить, ваши процессы видят живой терминал и ничего не замечают. А раз процессы привязаны к серверу tmux, а не к вашей SSH-сессии, обрыв SSH не шлёт им SIGHUP — отсюда и неуязвимость к разрывам связи. (Похоже работает nohup, но он лишь глушит один сигнал для одной команды; tmux даёт полноценную живую сессию, к которой можно вернуться.)

Частые ошибки

  • Запускают долгую задачу по SSH без tmux/screen, теряют её при обрыве связи — заводите сессию до старта операции.
  • Забывают, что префикс нажимается отдельно: Ctrl-b отпустить, и лишь потом командную клавишу, а не зажимать всё вместе.
  • Вместо detach (Ctrl-b d) пишут exit — это закрывает оболочку и убивает её процессы; detach сохраняет их живыми.
  • Плодят забытые сессии: tmux ls копит десятки сессий, в которых висят процессы — периодически проверяйте и закрывайте лишние.
  • Путают префиксы tmux (Ctrl-b) и screen (Ctrl-a) — на незнакомом сервере сперва выясните, что именно запущено.

Итоги

  • Мультиплексор держит сессии оболочки живыми независимо от подключения — спасение для долгих задач по SSH.
  • detach (Ctrl-b d) отсоединяет, не прерывая процессы; attach (tmux attach) возвращает к ним позже.
  • Модель tmux: сессия → окна (вкладки) → панели (несколько видимых одновременно); команды идут через префикс Ctrl-b.
  • screen — старший аналог с префиксом Ctrl-a; tmux удобнее и современнее, screen часто уже стоит на сервере.
  • Под капотом — модель клиент-сервер: фоновый tmux server владеет pty и сессиями, поэтому обрыв SSH им не страшен; настройка — в ~/.tmux.conf.
Проверьте себя
1. Вы запустили часовую миграцию базы по SSH, и соединение оборвалось. Как мультиплексор терминала (tmux) предотвращает потерю этого процесса?
Atmux автоматически переподключает ваш Wi-Fi
BПроцессы выполняются внутри фонового tmux-сервера на машине (в его pty), а не в вашей SSH-сессии, поэтому обрыв SSH не шлёт им SIGHUP — они продолжают работать, и к ним можно вернуться через attach
Ctmux сохраняет вывод миграции в файл и перезапускает её заново
Dtmux переносит процесс на другой сервер при разрыве связи
2. Чем команда detach (Ctrl-b, затем d) принципиально отличается от ввода `exit` в сессии tmux?
AНичем, обе закрывают окно
Bdetach отсоединяет вас от сессии, оставляя её и все процессы работающими на сервере (можно вернуться через attach); `exit` завершает оболочку и убивает её процессы
Cdetach удаляет сессию навсегда, а exit её сохраняет
Ddetach работает только в screen, а exit — только в tmux