Есть ли более элегантный способ разорвать связь между двумя клиентами tmux, совместно использующими сеанс изнутри tmux?

Есть ли более элегантный способ разорвать связь между двумя клиентами tmux, совместно использующими сеанс изнутри tmux?

Это почтиобзор кодавопрос, но очень *nixy и больше о конфигурации, чем о коде. Годами с тех пор, как я перешел на , tmuxу screenменя было несколько надоедливых проблем, которые я не мог заставить работать так, как хотел. С тех пор, как я настроил свою оболочку на exec в сеанс tmux, я наконец решил, что пора это исправить.

По умолчанию, когда вы подключаете двух клиентов tmux к одному сеансу, они блокируются вместе. Переключите панели в одном, и оба переключатся синхронно. Это отличается от screen, где поведением по умолчанию был общий набор панелей, но сам клиент был независимым.

Я хотел найти способ отвязать два клиента tmux, прикрепленных к одному сеансу. Это достаточно просто сделать, если вы находитесь вне tmux и запускаете новый клиент. Просто начните новый сеанс со ссылкой на родительский:

tmux new-session -t original_session -s new_session

Однако попробуй сделать этопослевы находитесь в клиенте и хотите отвязать его от любого другого клиента, который разделяет эту сессию, и все становится сложнее. Я перепробовал десятки способов и так и не нашел тот, который работал бы хорошо. Самое близкое, что я получил, это использование bind <key> prompt-command ...для запроса как старого, так и нового имени сессии.По какой-то причине tmux не расширяет #{session_name}переменную внутри аргументов для a new-sessionили prompt-command.Он делает это в аргументах для многих других команд (например, я использую его runниже), но без этого расширения эта конкретная задача становится внезапно сложной. Даже при ручном вводе значений это только как-то работало.

Сегодня я наконец-то заставил его работать. Однако результат оказался более уродливым, чем мне бы хотелось. Для выполнения большей части магии требуется функция оболочки. Чтобы ограничить это только файлом конфигурации без привлечения внешних скриптов (для переносимости dotfile), я использую хак. Конфигурация, если вы обрежете первые два столбца, на самом деле исполняется как скрипт оболочки. Поскольку все обернуто в функции, вы можете вызывать только нужную часть скрипта из любой комбинации клавиш. Биты скрипта оболочки являются комментариями в конфигурации, в то время как в скрипте оболочки бит конфигурации отбрасывается с помощью here-doc.

Сегодняшнее решениеполучилось что-то вроде этого (мой полный .tmux.confфайл):

# : << ENDOFCONF

# Clear the default binding
unbind C-c
# Pass the name of the current session to a function to clone it
bind C-c run "cut -c3- ~/.tmux.conf | sh -s clone #S"

# ENDOFCONF
# clone () {
#   orig=${1%-*}
#   copy="$orig-$(($( tmux list-sessions -F '#S' | sed -nE "/^${orig}-[0-9]+$/{s/[^0-9]//g;p}" | tail -n1 )+1))"
#   TMUX= tmux new-session -d -t $orig -s $copy
#   tmux switch-client -t $copy
#   tmux set -q -t $copy destroy-unattached on
# }
# $@

Заметьте, это работает. Из работающего клиента tmux Ctrl+ B Ctrl+ Cсоздает новый сеанс с номером, добавленным к имени текущего, использует текущий как цель для панелей и переключается на него.

Я доволен этим, за исключением назойливой мысли, что я только что сделал что-то простое гораздо более сложным, чем оно должно быть. Есть ли более простой способ добиться этого?

решение1

Вот что я сделал:

alias ta='export NEW_SESSION=\$(uuidgen) ; tmux new-session -t 0 -s \$NEW_SESSION ; tmux kill-session -t \$NEW_SESSION'

Это создает новый сеанс из сеанса с именем «0» (так будет называться первый сеанс, если вы не укажете другое), называет его как-то уникально и случайно (используя uuidgen), а затем уничтожает его при отсоединении.

Обратите внимание, что я использую zsh. «ta» — это сокращение от «tmux attach».

Связанный контент