- PVSM.RU - https://www.pvsm.ru -

Написание скриптов для tmux

Мне, когда я пользуюсь tmux, часто надо открывать похожие рабочие пространства. Например, мне всегда нужно выводить последние строки пары файлов журналов в панели, или мне нужно открывать и vim, и mysql. Бывает, что мне нужно и что-то другое.

Написание скриптов для tmux - 1 [1]

Если вы попробуете найти сведения об открытии рабочих пространств tmux, то почти гарантированно обнаружите советы по использованию программы-обёртки вроде tmuxinator [2], tmux-resurrect [3] или tmux-continuum [4]. Эти программы, возможно, хороши, но я предпочитаю что-нибудь попроще.

***

Вот небольшая справка по терминологии 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) [5].

Единственное, что меня несколько раздражает — это то, что 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?

Автор:
ru_vds

Источник [6]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/razrabotka/369315

Ссылки в тексте:

[1] Image: https://habr.com/ru/company/ruvds/blog/586392/

[2] tmuxinator: https://github.com/tmuxinator/tmuxinator

[3] tmux-resurrect: https://github.com/tmux-plugins/tmux-resurrect

[4] tmux-continuum: https://github.com/tmux-plugins/tmux-continuum

[5] tmux(1): http://man.openbsd.org/OpenBSD-current/man1/tmux.1

[6] Источник: https://habr.com/ru/post/586392/?utm_source=habrahabr&utm_medium=rss&utm_campaign=586392