Долгий 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 имя команда | старт в фоне, сразу Detached | screen -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 0 … Ctrl-a 9 | окно по номеру |
Ctrl-a " | список окон, выбор стрелками |
Ctrl-a ' | перейти по номеру или имени |
Ctrl-a A | переименовать текущее окно |
Ctrl-a Ctrl-a | предыдущее активное окно |
Ctrl-a k | закрыть окно (спросит подтверждение) |
Ctrl-a \ | убить все окна и выйти из screen |
Имена окон помогают, когда их больше двух: Ctrl-a A → nginx-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 отказывается | сессия висит на другом pty | screen -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 — тот минимум, из-за которого его держат в привычке.
