Как мне узнать имя сеанса tmux?

13

Недавно я начал использовать tmux. Я нахожу это хорошим, но у меня все еще есть проблемы с пониманием этого приложения. Один из основных вопросов, которые у меня есть: Как узнать (из командной строки), как называется tmuxсеанс, в который я вошел? Если я вошел в какую-либо tmuxсессию, он скажет мне его имя. Но если я не вошел в tmuxсеанс, он выведет либо ничего, либо какую-то ошибку.

e271p314
источник

Ответы:

18

Имя сеанса хранится в переменной #S , для доступа к нему в вы можете сделать

tmux display-message -p "#S"

Если вы хотите использовать его .tmux.conf, это просто #S. Обратите внимание, что -pопция выведет сообщение на стандартный вывод, в противном случае сообщение отобразится в строке состояния .

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

tmux list-sessions | sed -n '/(attached)/s/:.*//p'

tmux list-sessionsпоказывает все сеансы, если один присоединен, он показывает (attached)в конце. С помощью мы подавляем все выходные данные (опция -n), кроме тех случаев, когда мы находим ключевое слово (attached), в этой строке мы вырезаем все после a :, что оставляет нас с именем сеанса. Это работает для меня внутри и вне сеанса, в отличие от tmux display-message -p "#S".

Конечно, это работает, только если в названии сессии нет :и нет (attached)имени.

Как прокомментировал Крис Джонсен , способ проверить, находится ли кто-то внутри сеанса состоит в том, чтобы увидеть, установлена ​​ли его переменная окружения:

[[ -n "${TMUX+set}" ]] && tmux display-message -p "#S"
pfnuesel
источник
1
Даже если это выглядит правильно, я должен признать, что это не сработало для меня. У меня есть две консоли, в одной у меня есть tmuxсессия, а в другой я вне tmuxсессии. Когда я набираю обе команды tmux display-message -p "#S", выводится один и тот же результат, а возвращаемое значение обеих команд одинаковое.
e271p314
Я вижу такое же поведение. Посмотрите на мой обновленный ответ для обхода.
pfnuesel
4
Вероятно, вы можете просто обойтись без проверки переменной среды TMUX (она обычно устанавливается для процессов внутри сеанса, а не устанавливается вне сеанса - это не «защита от дурака», поскольку что-то может установить или сбросить TMUX и привести к путанице, но это должно быть достаточно надежно). В ksh , bash , zsh , и так далее:[[ -n "${TMUX+set}" ]] && tmux display-message -p "#S"
Крис Джонсен
Спасибо за комментарий. Я считаю, что это действительно более элегантный и достаточно надежный способ. Я добавил ваш комментарий в свой ответ.
pfnuesel
Что если я нахожусь внутри двух сессий tmux с разными именами одновременно? Это работает?
Михай Данила
0

Посмотрите здесь , используя этот пост, я понял, что единственное, что отличает tmuxклиентов, это их ttyимена, но имена сессий являются tmuxсвойством сервера и одинаковы, когда мы смотрим на имя сессии изнутри или снаружи tmuxклиента. Далее мы можем использовать, tmux info | headкоторый отображает pid и tty клиента и pid сервера.

tmux info | grep $$ | grep -q `ps -p $$ -o tty=`

Следующая команда возвращает значение 0, если мы находимся внутри tmuxклиента, или ненулевое, если мы работаем за пределами tmuxклиента. Если вы запускаете его из скрипта, убедитесь, что вы используете ppid вместо $$, так как tty связан с процессом оболочки, а не со скриптом, который вы запускаете.

Один простой способ, но менее надежный, чтобы узнать, находимся ли мы внутри или снаружи tmuxклиента, - это посмотреть переменную среды TERM. Похоже, что вне клиента он говорит «xterm», но внутри он говорит «экран». Тем не менее, я нахожу первый способ намного лучше.

e271p314
источник
0

Вот скрипт на Perl; Создание сценария оболочки или функции сценария оболочки - упражнение, оставленное читателю.

#!/opt/local/bin/perl

use strict;
use warnings;

if (exists $ENV{'TMUX'}) {
    # session ID is the last element
    # /tmp/1s/ffkjhk76sdgn/T/tmux-771/default,16772,8
    my($id) = $ENV{'TMUX'};
    $id =~ s{^.*,(\d+)$}{$1};

    # get session name
    my($cmd) = q(tmux ls -F "#{session_name}: #{session_id}");
    open(IN, "$cmd |") || die qq([ERROR] Cannot open pipe from "$cmd" - $!\n);

    while (<IN>) {
        chomp;

        if (m{(^.*):\s+\$$id$}) {
            print "Session name: <$1>\n";
            exit 0;
        }
    }

    print "Unable to determine TMUX session name\n";
    exit 1;
}
else {
    print "Not in a TMUX session\n";

    exit 1;
}

Это производит следующий вывод в сеансе TMUX:

<~> $ tmuxsessionname
Session name: <1>

<~> $ tmux rename-session "foobar"

<~> $ tmuxsessionname
Session name: <foobar>

Вне сеанса TMUX он будет производить следующее:

<~> $ tmuxsessionname
Not in a TMUX session

Вы можете отказаться от printоператоров и просто использовать код завершения, если хотите использовать его в сценарии оболочки или в чем-то другом.

Джо Касадонте
источник