Мне часто приходилось сталкиваться с тем, что при обрыве соединения SSH-сессия закрывалась и все исполняемые в ней процессы прерывались. Иногда это приводило к потере многочасового труда. В этой статье я расскажу про инструмент, который поможет застраховать себя от подобных проблем. Кроме этого этот инструмент даёт нам возможность разделения экрана на области, с возможностью выполнять разные задачи в каждом из них.
В качестве SSH-клиента я использую Putty или его брата-близнеца Kitty. Оба этих инструмента вышли из одного проекта, но потом получили разное, независимое друг от друга, развитие. При использовании SSH-клиента самая большая проблема - это обрыв соединения. Если связь между клиентом и сервером отсутствует больше времени таймаута, то соединение на сервере принудительно завершает свою работу. Избежать этого можно увеличив время таймаута в настройках клиента. Но это не панацея. Более удобным способом, на мой взгляд, является использование утилиты TMUX.
При обрыве соединения tmux, и все процессы, запущенные из под него, продолжат работать в фоновом режиме, и при новом подключении можно будет вновь подключиться к tmux и продолжить работу. Я не буду описывать процесс установки этой утлиты. К тому же она доступна в большинстве репозиториев современных дистрибутивов Linux. Хочу рассказать только об одной особенности использования tmux.
Tmux работает следующим образом. После установления SSH-соединения с сервером, вы запускаете tmux, который в свою очередь запускает экземпляр шела (например bash) и далее вы работаете в нём как обычно. При обрыве соединения, вы вновь подключаетесь по SSH и подключаетесь к той сессии TMUX, которую запустили ранее. Все процессы, запущенные в ней, всё это время, будут работать как ни в чём не бывало. Но я часто ловил себя на том, что, подключаясь к серверу я забывал запустить tmux и работал в обычном окне терминала. Что собственно и приводило к нежелательным последствиям при отключении соединения. Чтобы этого избежать я добавил tmux в “автозагрузку”. Для этого я внёс кое-какие изменения в файл .bashrc.
Существует множество файлов, которые выполняются во время запуска сессии: .bashrc; .bash_profile; .profile и т.д.. В следующих статьях я напишу о нюансах их использования и чем они отличаются.
Если в файл .bashrc просто добавить команду «tmux», то при запуске tmux мы увидим такое сообщение sessions should be nested with care, unset $TMUX to force. Это происходит потому, что при запуске TMUX, файл .bashrc выполняется ещё раз. И пытается запустить tmux повторно, а тот препятствует этому, хоть и говорит, что это возможно, если мы очистим значение переменной $TMUX. Дело в том, что после запуска TMUX он устанавливает значение переменной $TMUX, как показано ниже.
mdanshin:~$ echo $TMUX
/tmp/tmux-1000/default,32666,7
Тут видно, что значение переменной $TMUX = /tmp/tmux-1000/default,32666,7. Таким образом, можно при запуске проверять, если мы уже внутри TMUX, то не нужно пытаться запускать его повторно. Я сделал это так. Вместо просто запуска TMUX вставил условие.
if [ -z $TMUX ]; then
tmux
fi
В Linux есть такая замечательная штука как test. Если набрать man test, то мы увидим, что означает –z:
-z STRING the length of STRING is zeroВ нашем примере, в случае если переменная пуста, то будет возвращено значение TRUE. Таким образом будет проведена проверка и TMUX запуститься только в том случае, если переменная $TMUX пуста (то есть TMUX еще не был запущен).
В результате мы добиваемся своей цели. При подключении к серверу и входе в систему TMUX будет запускаться автоматически.
I often ran into a situation where an SSH session would close after a network disconnect, and all processes running inside that session would be terminated. Sometimes that meant losing hours of work. In this article I describe a tool that helps protect you from this. It also lets you split the terminal into multiple panes and work on different tasks in each one.
As an SSH client I use PuTTY or its close “twin” KiTTY. Both started from the same project but later evolved independently. The biggest problem with SSH is a connection drop: if the client and server are disconnected for longer than the timeout, the server forces the session to end. You can mitigate this by increasing the timeout in the client settings, but it’s not a silver bullet. A more convenient approach (in my opinion) is to use tmux.
When the connection drops, tmux (and all processes started under it) continues running in the background. After reconnecting, you attach to the same tmux session and continue where you left off. I won’t cover the installation process here — tmux is available in most repositories of modern Linux distributions. Instead, I want to describe one useful usage pattern.
tmux works like this: after you SSH to a server, you start tmux. tmux starts a shell (for example, bash), and you work there as usual. If the connection drops, you SSH again and attach to the tmux session you started earlier. Everything you ran in that session keeps running.
The problem I had was simple: sometimes I would forget to start tmux and work in a normal terminal session — which defeats the point. To avoid that, I added tmux to “autostart” by making a small change in .bashrc.
There are many files that can be executed when a session starts:
.bashrc,.bash_profile,.profile, etc. In future posts I’ll cover the nuances and differences.
If you just add tmux to .bashrc, you may see an error like sessions should be nested with care, unset $TMUX to force. This happens because when tmux starts, .bashrc gets executed again and tries to start tmux a second time. tmux prevents this (unless you explicitly unset $TMUX). After tmux starts, it sets the $TMUX variable:
mdanshin:~$ echo $TMUX
/tmp/tmux-1000/default,32666,7
So you can check whether you’re already inside tmux and only start it when $TMUX is empty. I did it like this:
if [ -z $TMUX ]; then
tmux
fi
In Linux there is a handy utility called
test. If you runman test, you’ll see what-zmeans:-z STRING the length of STRING is zero
In our case, if the variable is empty, the condition is true — so tmux starts only when $TMUX is empty (i.e., when tmux has not been started yet).
As a result, tmux starts automatically when you log in to the server.