Перейти к содержимому

        GNU Screen: сессии, которые переживают обрыв SSH - Featured image

GNU Screen: сессии, которые переживают обрыв SSH

Долгий apt upgrade, миграция, сборка — и ноутбук ушёл в сон. SSH рвётся, процесс получает SIGHUP и умирает. GNU Screen держит терминал на сервере: отключился, подключился снова, работа на месте.

Это не замена nohup и не «ещё один SSH». Это мультиплексор: именованные сессии, несколько окон внутри одной, общая сессия на двоих. На старых RHEL/Debian screen часто уже стоит, когда tmux ещё нет.

Минимальный цикл

На сервере:

screen -S deploy

Дальше обычный шелл. Чтобы уйти, не убивая процессы: Ctrl-a, отпустить, затем d. Сессия остаётся Detached.

Список и возврат:

screen -ls
screen -r deploy

Если сессия всё ещё Attached на другом терминале (забыли отсоединиться на работе):

screen -d -r deploy

Сначала отсоединит там, потом подключит здесь.

Заметка

Префикс — Ctrl-a. Клавиши не жмут вместе: Ctrl-a, отпустить, затем буква. Ctrl-a a отправляет настоящий Ctrl-a в программу внутри (это нужно emacs и редко bash).

Установка

# Debian / Ubuntu
sudo apt install screen

# RHEL / Alma / Rocky
sudo dnf install screen

# Alpine
sudo apk add screen

Проверка: screen -v. Вертикальный сплит (Ctrl-a |) есть с GNU Screen 4.1; на очень старых ящиках его нет.

Ключи командной строки

КлючЧто делаетПример
-S имясоздать или обратиться по имениscreen -S logs
-ls / -listсписок сессийscreen -ls
-r [имя]подключиться к отсоединённойscreen -r logs
-d -r имяотсоединить там, подключить здесьscreen -d -r logs
-Rподключить существующую или создать новуюscreen -R logs
-x [имя]подключиться не отсоединяя другую сторонуscreen -x logs
-dmS имя командастарт в фоне, сразу Detachedscreen -dmS backup /opt/backup.sh
-Lписать лог screenlog.N в текущем каталогеscreen -L -S migrate
-Logfile файлпуть к логу (вместе с -L)screen -L -Logfile /tmp/migrate.log -S migrate
-X командапослать команду в уже живую сессиюscreen -S logs -X stuff 'tail -f /var/log/nginx/error.log\n'
-wipeубрать мёртвые сокеты из спискаscreen -wipe

Имя в -S — то, что потом ищете в screen -ls. Без имени получите что-то вроде 12345.pts-0.hostname — вспоминать неудобно.

Типичный фон для скрипта, который должен пережить разрыв SSH:

screen -dmS pg-dump pg_dump -Fc -f /backup/app.dump app
screen -ls
# позже
screen -r pg-dump

Когда команда завершится, сессия обычно исчезает. Нужен шелл после скрипта:

screen -dmS build bash -lc 'make -j"$(nproc)"; exec bash'

Окна внутри сессии

Одна сессия — несколько окон: сборка, логи, второй шелл. Переключение без нового SSH.

КлавишаДействие
Ctrl-a cновое окно
Ctrl-a n / Ctrl-a pследующее / предыдущее
Ctrl-a 0Ctrl-a 9окно по номеру
Ctrl-a "список окон, выбор стрелками
Ctrl-a 'перейти по номеру или имени
Ctrl-a Aпереименовать текущее окно
Ctrl-a Ctrl-aпредыдущее активное окно
Ctrl-a kзакрыть окно (спросит подтверждение)
Ctrl-a \убить все окна и выйти из screen

Имена окон помогают, когда их больше двух: Ctrl-a Anginx-log.

Сессия, копирование, сплит

КлавишаДействие
Ctrl-a dотсоединиться, процессы живут
Ctrl-a D D«жёсткое» отсоединение (и с других дисплеев)
Ctrl-a ?справка по клавишам
Ctrl-a :командная строка screen (quit, sessionname, …)
Ctrl-a aпослать Ctrl-a внутрь окна
Ctrl-a [режим копирования / прокрутка буфера
Ctrl-a ]вставить буфер обмена screen
Ctrl-a Escто же, что Ctrl-a [
Ctrl-a Sсплит по горизонтали (регион сверху/снизу)
Ctrl-a |сплит по вертикали
Ctrl-a Tabфокус в соседний регион
Ctrl-a Xзакрыть текущий регион (окно не убивается)
Ctrl-a Qоставить только текущий регион
Ctrl-a Hвкл/выкл лог screenlog.N
Ctrl-a Mследить за активностью в окне (колокольчик)
Ctrl-a xзалочить сессию (пароль пользователя)

Прокрутка: Ctrl-a [, затем стрелки или PageUp / PageDown. Выделение: Пробел — начало, стрелки, Enter — в буфер screen. Выход из режима — Esc. Вставка — Ctrl-a ]. Это не системный clipboard: буфер живёт внутри screen.

После сплита новый регион пустой, пока в него не переключитесь (Ctrl-a Tab) и не выберете окно (Ctrl-a n или Ctrl-a ").

Сценарии с сервера

Долгий деплой. Именованная сессия, лог на диск, отключились и пошли домой:

screen -L -Logfile ~/migrate.log -S migrate
# внутри: ansible-playbook -i prod site.yml
# Ctrl-a d

Утром: screen -r migrate или просто tail -f ~/migrate.log.

Несколько задач в одном SSH. Сессия ops, окна build, journal, sql:

screen -S ops
# Ctrl-a c  — ещё окно
# Ctrl-a A  — имя

Парный просмотр. Оба под одним пользователем:

# первый
screen -S incident
# второй, не выкидывая первого
screen -x incident

Оба видят один и тот же терминал. Для инцидента это быстрее, чем «скинь вывод».

Команда с ноутбука в уже открытую сессию — без входа руками:

screen -S ops -X screen bash
screen -S ops -X stuff 'systemctl status nginx\n'

-X screen создаёт окно, stuff печатает в него символы. \n — как Enter.

Короткий .screenrc

По умолчанию scrollback маленький, баннер при старте мешает, имён окон не видно. В ~/.screenrc:

startup_message off
vbell off
defscrollback 20000
shell -$SHELL

hardstatus alwayslastline
hardstatus string "%{= kw}%-w%{= BW}%n %t%{= kw}%+w %= %H %l %Y-%m-%d %c"

defscrollback — сколько строк доступно в Ctrl-a [. hardstatus — полоса снизу: окна, хост, load, время. Файл читается при создании сессии; уже живущие подхватят только после пересоздания.

Системный /etc/screenrc трогать не обязательно: пользовательский дополняет его.

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

СимптомПочемуЧто делать
There is no screen to be resumedимя другое или сессия уже умерлаscreen -ls, затем точное имя
Attached и -r отказываетсясессия висит на другом ptyscreen -d -r имя
Сессия пропала после командыпроцесс в единственном окне завершилсяобернуть в bash -lc '…; exec bash'
Ctrl-a «съедает» emacs/tmux внутрипрефикс screen перехватываетCtrl-a a для литерала; либо другой escape в .screenrc: escape ^Bb
Нет вертикального сплитаScreen < 4.1горизонтальный Ctrl-a S или поставить пакет новее
Лога нет-L не был задан и Ctrl-a H не жаливключить явно, проверить cwd сессии

Сокеты лежат в /run/screen/S-$USER/ или ~/.screen/. Чужую сессию так просто не взять: права на каталог.

Когда screen, когда нет

Одна фоновая команда без интерактива — достаточно systemd-run --user, tmux или даже nohup. Постоянная рабочая среда на bastion, деплой «запустил и закрыл крышку», совместный просмотр логов — screen закрывает это без лишних зависимостей.

tmux удобнее сплитами и конфигом. Screen выигрывает тем, что уже есть на ящике, куда вы только что зашли по SSH. Именованная сессия и Ctrl-a d — тот минимум, из-за которого его держат в привычке.