Если вы попробуете найти сведения об открытии рабочих пространств tmux, то почти гарантированно обнаружите советы по использованию программы-обёртки вроде tmuxinator, tmux-resurrect или tmux-continuum. Эти программы, возможно, хороши, но я предпочитаю что-нибудь попроще.
***
Вот небольшая справка по терминологии tmux:
- Панель (pane) — это область, в которой выводится содержимое терминала.
- Окно (window) — это набор, состоящий из одной или большего количества панелей. Окно всегда занимает весь экран.
- Сессия (session) — это набор окон.
Каждая клавиатурная привязка в tmux, за исключением префиксной комбинации
<C-b> (Ctrl-b)
, реализована путём отправки команды tmux. Например, сочетание <C-b>c
отправляет команду new-window
, а сочетание <C-b>n
— команду next-window
.Сделать то же самое можно, используя эти команды в командной оболочке, или в командном режиме tmux:
$ tmux new-window
<C-b>:new-window
Многие команды принимают параметры, например, с командой
new-window
можно использовать ключ -t
, позволяющий указать индекс целевого окна. Можно воспользоваться сочетанием клавиш <C-b>?
(команда list-keys
) для вывода списка стандартных клавиатурных привязок.Это — мощная концепция, существование которой означает, что всё, что при работе с tmux делается в интерактивном режиме, можно описать в скриптах. Мы, вооружённые этой информацией, можем создать скрипт командной оболочки для открытия нужного рабочего пространства.
Тут я, в качестве примера, рассматриваю скрипт, созданный для открытия рабочего пространства, предназначенного для работы с моим сайтом. Мне для этого надо три окна: в одном открывается командная оболочка, в другом — веб-сервер, а в третьем Jekyll.
Сначала надо начать новую сессию:
$ tmux new-session -d -s site
Флаг
-d
сообщает tmux о том, что ему не нужно входить в новую сессию, подключаться к ней. В большинстве команд этот флаг играет ту же роль, поэтому многократно описывать его я не буду. Ключ -s
позволяет дать сессии имя. Нельзя создать сессию без окна, в результате команда new-session
создаёт ещё и окно. Если нужно, имя этому окну можно дать с помощью ключа -n
.Создать новое окно можно так:
$ tmux new-window -d -t '=site' -n server -c _site
$ tmux send-keys -t '=site:=server' 'python -mhttp.server' Enter
Ключ
-t
позволяет установить целевое окно: в данном случае тут указывается имя сессии, поэтому tmux использует следующий неиспользуемый индекс. Знак =
позволяет обеспечить точное совпадение имени. Ключ -n
задаёт окну имя, а ключ -c
задаёт директорию.Я не выполняю команду для запуска программы, пользуясь возможностями
new-window
, так как мне не нужно, чтобы панель закрылась бы в том случае, если я остановлю или перезапущу эту команду. Поэтому я выполняю команду с помощью send-keys
.По той же схеме можно действовать и создавая следующее окно:
$ tmux new-window -d -t '=site' -n jekyll
$ tmux send-keys -t '=site:=jekyll' 'JEKYLL_NO_BUNDLER_REQUIRE=1 jekyll build -w' Enter
И, наконец, войдём в новую сессию:
$ [ -n "${TMUX:-}" ] &&
tmux switch-client -t '=site' ||
tmux attach-session -t '=site'
Эта конструкция позволяет обеспечить работоспособность кода как при его запуске за пределами tmux, так и при запуске из другой сессии tmux.
Соберём всё вместе:
#!/bin/sh
set -euC
cd ~/code/arp242.net
att() {
[ -n "${TMUX:-}" ] &&
tmux switch-client -t '=site' ||
tmux attach-session -t '=site'
}
if tmux has-session -t '=site' 2> /dev/null; then
att
exit 0
fi
tmux new-session -d -s site
tmux new-window -d -t '=site' -n server -c ~/code/arp242.net/_site
tmux send-keys -t '=site:=server' 'python -mhttp.server' Enter
tmux new-window -d -t '=site' -n jekyll
tmux send-keys -t '=site:=jekyll' 'JEKYLL_NO_BUNDLER_REQUIRE=1 jekyll build -w' Enter
att
Обратите внимание на то, что tmux подключится к сессии
site
в том случае, если она уже существует.***
Я обнаружил эти команды, воспользовавшись командой
tmux list-keys -T prefix
. Так я понял, какие команды отправляются tmux, а потом нашёл их в документации tmux(1).Единственное, что меня несколько раздражает — это то, что tmux поддерживает только короткие имена опций (например —
-s
), но не длинные (вроде -session-name
). Короткие имена хорошо подходят для ввода с клавиатуры в командной строке. Собственно — из-за того, что они короткие. Но опции с длинными именами гораздо удобнее использовать в скриптах, особенно в тех случаях, когда речь идёт об опциях, применяемых редко. Сравните:$ tmux new-session -d -s site -n server
$ tmux new-session -detached -session-name site -window-name server
Вторая строчка включает в себя самодокументирующиеся свойства, а вот в первой их нет. Полагаю, что это — одна из важных причин существования скриптов-обёрток для tmux, в которых используются конфигурационные YAML-файлы или нечто подобное.
Пользуетесь ли вы tmux?
Комментарии (9)
skymal4ik
01.11.2021 12:34+1Спасибо за информацию, это полезно знать.
Сам первым делом на своих серверах ставлю tmux и заливаю свой (.tmux.conf) ручками или через Ansible.
По мне, так tmux куда удобнее screen. Единственное, что в своём конфиге меняю ctrl-b на ctrl-a, ибо тянуться к b неудобно.
Terol
02.11.2021 07:34Пользуюсь. Единственная проблема, в новой версии tmux что то изменилось и теперь мои комбинации клавиш с Ctrl, прописанные в старом конфиге не работают. Когда скачешь между разными версиями это доставляет неудобства
AlexVPetrov
02.11.2021 11:07tmux attach -t mysession || tmux new -s mysession
amurchick
05.11.2021 15:46можно и изящнее:
tmux new -As mysession
The -A flag makes new-session behave like attach-session if session-name already exists
mpa4b
02.11.2021 17:17Использую и screen и tmux потому что можно один в другом открыть и ctrl-a не пересекается с ctrl-b. Но предпочитаю screen, т.к. он поддерживает консольную мышку и может разные сессии отдавать в разные подключения. Может и tmux так умеет, не разбирался. Из коробки вроде не умеет.
Self_Perfection
03.11.2021 13:33echo 'set -g mouse on' >> ~/.tmux.conf
ArtyL
06.11.2021 14:59для себя пришел к мысли что режим tmux поддержки мыши мне не всегда удобен, поэтому сделал 2 макроса для переключения:
alias tmuxmouse='tmux set-option mouse on'
alias tmuxmouseoff='tmux set-option mouse off'
majorius
del