Команда screen
Расскажу, пожалуй, еще об одной очень нужной и полезной, с моей точки зрения, команде, которая сильно облегчает жизнь при удаленной работе с устройствами под управлением Linux
. Речь пойдет о screen
.
Немного о том, как состоялось мое знакомство с этой командой. В то время я только начинал осваивать удаленное управление моими домашними железками, работающими под управлением Linux
- сервером на базе нетбука Toshiba и двумя домашними сетевыми накопителями семейства MyBookLive
. Громкое определение "управление" сводилось, как правило, к подкладыванию torrent
файлов демону transmission
и копированием уже скачанных этим демоном файлов на домашние NAS-ы. Казалось бы, что может быть проще: вошел по SSH
на сервер и, при помощи midnight commander
или scp
, копируешь нужные файлы. На самом деле, в этих несложных, в общем-то, манипуляциях, меня поджидало две неприятности.
Первая была чисто техническая: на моем сервере, работающем под Debian Wheezy
, а потом Jessie
, что-то было не так с сетевыми драйверами. Точнее, я подозреваю, что драйвера были лишь частью проблемы; свою лепту, скорее всего, вносили еще BarracudaDrive
(теперь это FuguHub
) и VPN
сервер, работающие на сервере. А может, и само железо было не без изьяна, хотя...
Суть неприятности, собственно, заключалась в том, что сетевое соединение, неважно, проводное или WiFi (именно поэтому в вину hardware
верилось с трудом - обычно "глючит" что-то одно), в какой-то момент просто отваливалось. Причем, предсказать и объяснить "отваливание" было довольно сложно, но одно можно было утверждать смело: под нагрузкой оно происходило чаще, и WiFi, как ни странно, обладал большей надежностью, нежели витая пара. Надо признаться, что причин этой проблемы я так и не выявил, чему немало способствовали факты непредсказуемости и редкости ее возникновения (с WiFi это случалось от нескольких раз в месяц до пары раз в полгода), а потому, воспроизвести ее по требованию было просто невозможно. Как результат, если такое случалось, я просто переподключал WiFi на нетбуке, или, если был в это время, например, на работе, просил это сделать своих домочадцев.
Вторая проблема заключалась, скажем так, в моих особенностях, как пользователя. Эти особенности находят свое отражение, в частности, в том, что я не очень-то жалую командную строку и, где только возможно, пытаюсь использовать различные оболочки. В случае с копированием больших файлов это приводит к драматическим потерям времени: кто пробовал копировать файлы между устройствами при помощи midnight commander
, тот понимает, что я имею в виду. И, хотя, как говорят, есть три вещи, на которые можно смотреть бесконечно: как бежит вода, как танцует пламя и как движется ползунок, отображающий процесс скачивания торрента (с чем я, в принципе, согласен), но смотреть на процесс копирования файлов в midnight commander
, особенно ту его часть, которая связана не с ползунком, а с отсчетом скопированных и проверенных байт... Раздражение - это самая безобидная эмоция, посещавшая меня в такие моменты, и, кроме того, всегда возникало жгучее желание именно в это время занятся чем-то другим, более полезным, чем просто ожидание.
К сожалению, проблемы имеют такое нехорошее свойство - сходиться вместе. Когда это (отваливание сети) происходит в конце копирования большого файла при помощи midnight commander
, то просто хочется рвать и метать - разрыв связи означает прерывание SSH
соединения, и, как следствие, необходимости копировать файл по новой. Чтобы обезопасить себя от таких нежелательных последствий, я решил поискать какой-нибудь способ, который бы позволил завершиться производимому действию, вне зависимости от того, активно ли SSH
соединение, или нет.
Для меня было ясно, что надо копать в сторону использования другого потока, сессии и так далее. И первым опробованным решением было фоновое копирование в самом midnight commander
. Не буду сейчас подробно рассказывать все перепетии этого процесса, отмечу лишь, что довольно быстро я осознал необходимость продолжения поиска более приемлемого решения. И оно было найдено - команда screen
.
Что же это за зверь такой? Всезнающая wiki дает на этот вопрос немного непонятный ответ: консольный мультиплексор. Но если почитать дальше, то становится понятным употребление термина "мультиплексор" - речь идет о возможности использовать в одном терминальном окне нескольких виртуальных консолей, с такой дополнительной функциональностью, как "отсоединение" и “воссоединение" сессий. Если отвлечься от высокой теории, и опуститься на землю, то, на практике, это все означает, что можно одновременно использовать несколько консольных приложений, а также, что можно разорвать связь между запущенным консольным приложением и сессией, это приложение запустившей. Как результат, можно закрыть удаленное соединение, а запущенные приложения продолжат свою работу. А это именно то, что мне требовалось! Ну а теперь по порядку - что, да как.
Начнем с того, что эта утилита может быть изначально установлена в вашей системе, но, в моем случае (Debian Wheezy
), пришлось ставить ее самостоятельно
apt-get install screen
Не стоит забывать, что при установке надо иметь права "суперпользователя". Так, если вспомнить команду su
, то команду на установку можно записать примерно так:
su -c "apt-get install screen" -
С результатом можно ознакомиться на скриншоте:
После установки можно сразу начать использовать эту утилиту. Причем, для этого совершенно не надо обладать правами администратора системы. Простейший способ запустить команду - просто набрать в командной строке screen
. В результате выполнения этой команды будет создана сессия screen
и в этой сессии - новая виртуальная консоль . При этом, она займет окно терминала полностью и в ней отобразится лицензионная информация о самой screen
.
Все, что вы будете делать, все программы и команды, которые вы будете запускать - все будет работать в этой виртуальной консоли (и, соответственно, в сессии screen
). Наверное, единственным исключением является сама команда screen
- будучи запущенной в виртуальной консоли без параметров, она создаст новую виртуальную консоль в той же сессии screen
.
Что делать, если вы захотите завершить работу виртуальной консоли? Как это часто бывает, для этого можно использовать команду exit
. При этом, если вы закрываете последнюю используемую виртуальную консоль сессии (в нашем примере так и есть), то закрыта будет и сама сессия
Надо сказать, что в таком режиме использовать screen
вроде как нет никакого смысла - ну что такого особенного в том, чтобы открыть, немного поработать и закрыть виртуальную консоль. Может оно и так, но если вы, скажем, работаете удаленно, и произошло что-то нехорошее, например, обрыв связи, то сессия screen
все равно останется "жива"! И в нее можно будет вернуться после восстановления соединения! Но об этом - чуть позже. Сейчас продолжим играться с самой командой screen
.
Попробуем запустить в такой консоли какой-нибудь долгоиграющий процесс, а самим вернуться в терминальное окно, и продолжить заниматься обычными каждодневными делами. Как это сделать? Да проще некуда. Давайте снова запустим screen
и выполним в нем, например, такую команду:
ping 8.8.8.8
Нет, я, конечно, мог предложить действительно скачать какой-нибудь большой файл, например:
wget https://cdimage.debian.org/cdimage/archive/8.11.0/amd64/iso-cd/debian-8.11.0-amd64-CD-1.iso
Но оно вам надо? Нужно место на диске, потом удалять файл... ping
значительно "безобиднее".
ping
, запущенный без параметров, выполняется до тех пор, пока вы его не прервете при помощи, скажем, комбинации клавиш Ctrl+C
. А до тех пор, вы обречены наблюдать время отклика "пингуемого" сайта. Но, не в этот раз. Хотя, конечно, возникает вопрос: а что, собственно, и, главное, как - можно сделать? Куда вводить команды? На самом деле, все довольно просто - командой screen
можно управлять при помощи специальных комбинаций клавиш.
Для перехода в режим управления screen
используется комбинация клавиш Ctrl+A
. Набирается она следующим образом: нажимается и удерживается клавиша Ctrl
, нажимается клавиша А
(не в смысле "заглавная буква А" а просто клавиша, обозначенная как английская буква A
), клавиши отпускаются. После этого оказывается включен режим управления командой screen
и следующая нажатая (и отпущенная) клавиша приведет к выполнению какого-нибудь действия. Например, если после ввода комбинации Ctrl+A
нажать клавишу ?
(в дальнейшем, такие комбинации будем записывать так: Ctrl+A ?
), то будет выведен экран помощи по команде screen
.
Давайте внимательно посмотрим на этот экран и запомним несколько комбинаций, скажем, Ctrl+A c
(эта комбинация помечена, как screen
), Ctrl+A n
(помечена, как next
), Ctrl+A p
(помечена, как prev
) и Ctrl+A w
(помечена, как windows
). Запомнили? Теперь, давайте немного поэксперементируем. И начнем, пожалуй, с комбинацииCtrl+A c
- просто задействуем ее, пока на экране нашей виртуальной консоли все бежит и бежит результат отклика сервера DNS от Google (8.8.8.8
- это один из серверов Google). Если все сделано правильно, вы должны увидеть перед собой пустую консоль, в которой можно ввести какую-нибудь команду. Это вторая созданная нами виртуальная консоль screen
, причем работает она в той же сессии, что и первая. Такого же эффекта мы бы добились, если бы в командной строке виртуальной консоли выполнили команду screen
(конечно, если бы могли воспользоваться командной строкой).
Что бы нам такое сделать с этой второй виртуальной консолью? Не будем оригинальничать и "запингуем" другой DNS сервер от Google - 8.8.4.4
:
Теперь мы знаем время отклика и от этого сервера Google. Но, стоп! А это время лучше или хуже? Для ответа на этот вопрос внимательно смотрим на время отклика от 8.8.4.4
, запоминаем его, после чего применяем комбинацию Ctrl+A p
.
Если вам кажется, что ничего не изменилось, то либо вы чуточку невнимательны, либо вы не совсем правильно воспользовались управляющей комбинацией клавиш. Если же эти предположения к вам не относятся, то, присмотревшись, вы увидите, что теперь перед вами время отклика от сервера 8.8.8.8
! То есть, комбинация клавиш Ctrl+A p
вернула нас в предыдущую виртуальную консоль screen
. Ну что, сравнили время отклика? Нет? Забыли? Не беда, воспользуемся управляющей комбинацией Ctrl+A n
и освежим свою память - перед нами виртуальная консоль в результатами ping
до сервера 8.8.4.4
, то есть, мы переключились на следующую виртуальную консоль screen
.
Теперь посмотрим, что делает управляющая комбинация Ctrl+A w
Мы видим, что в левом нижнем углу появилось перечисление работающих виртуальных консолей: одна консоль - под логическим номером 0
, другая - под номером 1
. То есть, комбинация Ctrl+A w
выводит список виртуальных консолей, которые вы успели запустить к этому моменту в сессии screen
. Ну а сами логические номера консолей можно использовать для того, чтобы переключаться между ними. Для этого надо будет воспользоваться комбинацией вида Ctrl+A номер_консоли
, где номер_консоли
- цифры от 0 до 9, обозначающие логический номер виртуальной консоли.
Итак, мы находимся в одной из запущенных нами виртуальных консолей. Возникает вопрос: а можем мы оказаться в обычном терминальном окне, оставив при этом работать и саму сессию и ее виртуальные консоли? И ответ довольно предсказуем: да! Для этого надо отключиться от сессии, или, другими словами, отсоединиться от нее, для чего можно использовать комбинацию Ctrl+A d
в любой виртуальной консоли, принадлежащей сессии. Задействовав ее, мы окажемся в обычном терминальном окне.
Надо заметить, в обычном терминальном окне управляющие комбинации команды screen
не действуют. Сюрприз, не правда ли? Тем временем, у нас, где-то, работают две виртуальных консоли (в рамках запущенной сессии screen
). И что нам делать, чтобы снова, каким-то волшебным способом, к ним подключиться? К счастью, у команды screen
имеется некоторый набор опций (или ключей) командной строки, часть из которых позволят нам решить нашу задачу - вернуться обратно в виртуальные консоли.
Во-первых, нам нужно посмотреть какую-нибудь информацию о запущенных сессиях команды screen
. Сделать это можно при помощи команды screen -ls
(допустимо использовать и более развернутый синтаксис команды - screen -list
). В ответ, нам будет выдан список запущенных сессий (или сеансов, кому как больше нравится):
По каждой сессии screen
выдается следующая информация: идентификационная строка, дата/время создания сессии и ее статус. Строка-идентификатор сессии выдается в формате pid.tty.host
. Она состоит из следующих элементов: pid
- идентификатор запущенного процесса, tty
- название терминала, host
- имя хоста. Иногда, когда, например, при помощи команды screen -S имя_сессии
, создаются так называемые именованные сессии (или уже существующей сессии задают/изменяют имя при помощи управляющей комбинации клавиш Ctrl+A :sessionname name
), вместо tty.host
выводится имя соответствующего сеанса.
С датой и временем создания сессии вопросов возникнуть не должно. Немного по статусу (или состоянию) сессии:
- Если указано
Detached
, то сессия работает в "отсоединенном" режиме, то есть, отвязана от какого бы то ни было терминального окна (например, была использована управляющая комбинация клавишCtrl+A d
). Такие сеансы можно возобновить с помощью командыscreen -r
. - Если указано
Attached
, то сессия работает и "привязана" к какому-то терминальному окну (такие окна иногда называют " управляющими"). - Если сеанс работает в многопользовательском режиме, он помечается как
Multi
. - Сеансы, отмеченные как
Unreachable
, либо "живут" на другом хосте, либо "мертвы". Недоступный сеанс считается "мертвым", когда его имя совпадает либо с именем локального хоста, либо со специальным, ранее указанным, параметром. "Мертвые" виртуальные консоли могут быть удалены при помощи командыscreen -wipe
, но, конечно, вы должны быть уверенными в том, что вы делаете.
Итак, мы видим, что есть "отсоединенная" сессия. Для того, чтобы вернуться в виртуальную консоль этой сессии можно использовать команду screen -r идентификатор_сессии
. В качестве параметра идентификатор_сессии
можно указать либо всю идентификационную строку целиком, либо ее часть. У меня получалось подключаться и по целой строке, и по значению pid
, и по значению tty.host
, и только по значению tty
. Примеры:
screen -r 23236
screen -r 23236.pts-0.debian
screen -r pts-0.debian
screen -r pts-0
Если необходимо подключиться к именованной сессии, то, в качестве еще одной альтернативы, можно указать имя нужной сессии:
screen -r test
При этом я заметил, что если в сессии есть несколько открытых виртуальных консолей, то возвращаешься в ту же виртуальную консоль, которая была активна на момент отсоединения от сессии при помощи, например, комбинации клавиш Ctrl+A d
.
На самом деле, у screen
есть масса возможностей: можно, например, разделить окно терминала между несколькими виртуальными консолями, можно не просто создать сессию, но и сразу запустить в ней нужную команду, можно даже указать, чтобы созданная сессия с запущенным приложением сразу "отсоединилась". Можно даже попытаться изменить стандартное поведение screen
- для этого есть специальные файлы: ~/.screenrc
и /etc/screenrc
. Я не буду подробно рассказывать про все эти возможности, в конце концов, можно и документацию почитать, да и в сети полно разнообразных материалов по этой теме. Но несколько примеров запуска screen
я, все-таки, приведу: просто потому, что документация - документацией, это, так сказать, теория, а практика - это наглядная иллюстрация того, как можно пользоваться знаниями, полученными в результате изучения теории, и эта наглядность позволяет быстрее и проще понимать теорию, облегчая ее применение на практике... фуф...
Чуть выше я упоминал "именованные" сессии. Работать с ними довольно удобно - можно давать вполне осмысленные имена, которые и проще запомнить и, следовательно, проще использовать. Задать имя сессии можно при ее создании:
screen -S test
Эта команда создаст новую сессию с незамысловатым именем test
.
А вот так можно сразу еще и команду какую-нибудь запустить:
screen -S ping ping 8.8.8.8
В результате выполнения такой команды будет создана новая сессия screen
с именем ping
, и в виртуальной консоли этой сессии будет запущена команда ping 8.8.8.8
. Надо заметить, что если после такого запуска прервать выполнение команды ping
, то сессия будет завершена. Если же запустить такую команду:
screen -dmS ping ping 8.8.8.8
то будет создана новая сессия с именем ping
, в виртуальной консоли которой будет запущена команда ping 8.8.8.8
и кроме всего этого - будет произведено отключение от этой сессии. Но все можно повернуть и чуть-чуть иначе:
screen -dR ping ping 8.8.8.8
Эта команда попробует заново подсоединиться к сессии с именем ping
, а если таковой нет, то она будет создана, после чего в ней будет запущена команда ping
и произведено отключение. А еще можно подключиться к сессии, которая выполняется в другом терминальном окне, для чего следует использовать ключ x
:
screen -x ping
Такое может потребоваться, например, при неожиданном обрыве связи в процессе удаленного управления. Кстати, другой пользователь, работающий под такой же учетной записью, как и вы[1], может выполнить эту же команду и вы оба окажетесь в одной виртуальной консоли сессии screen
. Получится "многопользовательская" консоль. На самом деле, можно все устроить таким образом, чтобы к виртуальной консоли мог подключиться пользователь, работающий и под другой учетной записью, но для этого надо делать специальные манипуляции.
Теперь представим, что мы очень часто выполняем команду screen
и нам порядком надоело лицезреть стартовый экран. Для того, чтобы избавиться от него, надо в конфигурационный файл команды screen
добавить строку:
startup_message off
Сделать это можно при помощи любого текстового редактора. Причем, если произвести это изменение в файле ~/.screenrc
(в домашнем каталоге текущего пользователя), то стартовый экран перестанет появляться при запуске screen
под этим пользователем. Если же модифицировать файл /etc/screenrc
, то произведенное редактирование получит статус "system wide", то есть, затронет всех пользователей системы.
Такие примеры можно продолжать приводить довольно долго. Но пора и честь знать, и так получилось довольно длинное повествование. Напоследок хочу отметить, что удаленное управление (по ssh
, например) - не единственная область деятельности администратора (да и простого пользователя), когда команда screen
приходит, что называется, на выручку. Можно еще вспомнить, что с ее помощью легко эмулируется режим демона, то есть, можно запускать в фоне задачи, которые не могут быть запущены в качестве демона, по причине, скажем, наличия пользовательского интерфейса. Очень часто так запускают rtorrent
, например. Да и это не последняя возможность применения команды screen
. Так что, дерзайте...
обратите внимание, я не пишу "под вашей учетной записью", а "под такой же учетной записью" - передавать данные своей учетной записи какому-то другому пользователю я бы не советовал, а вот пользоваться специально созданной "общей" учеткой - вполне нормально, особенно если не оставлять свои конфиденциальные данные ↩︎