Как автоматически запустить tmux на сессии SSH?

У меня есть приблизительно десять серверов, с которыми я соединяюсь с SSH регулярно. У каждого есть запись в моем локальном компьютере ~/.ssh/config файл.

Чтобы постараться не терять контроль над моим рабочим процессом, когда мое Интернет-соединение неизбежно отбрасывает, я всегда работаю внутри a tmux сессия. Я хотел бы способ иметь tmux, автоматически соединяются каждый раз, когда соединение SSH запускается, таким образом, я не должен всегда вводить tmux attach || tmux new после того, как я SSH в.

К сожалению, это не оказывается столь простым, как я первоначально надеялся.

  • Я не хочу добавлять любые команды к ~/.bashrc на серверах, потому что я только хочу это для сессий SSH, не локальных сессий.
  • Добавление tmux attach || tmux new к ~/.ssh/rc на серверах просто приводит к ошибке not a terminal будучи брошенным после соединения, даже когда RequestTTY force опция добавляется к строке для того сервера в моем локальном файле конфигурации SSH.
62
задан 23 December 2014 в 05:18

9 ответов

Хорошо, я нашел главным образом удовлетворительное решение. В моем локальном ~/.bashrc, я записал функцию:

function ssh () {/usr/bin/ssh -t $@ "tmux attach || tmux new";}

, который в основном перезаписывает ssh терминальную функцию для вызова встроенной ssh программы с данными аргументами, сопровождаемыми "tmux attach || tmux new".

(Эти $@ обозначает все аргументы, обеспеченные на командной строке, таким образом ssh -p 123 user@hostname будет расширен до ssh -t -p 123 user@hostname "tmux attach || tmux new")

(-t аргумент эквивалентен RequestTTY Force и необходим для команды tmux.)

44
ответ дан 31 October 2019 в 13:28

Конфигурация серверной стороны:

Для автоматического запуска tmux на удаленном сервере при обычном входе на пути SSH (и только SSH) отредактируйте ~/.bashrc из пользователя или корня (или оба) на удаленном сервере соответственно:

if [[ -z "$TMUX" ]] && [ "$SSH_CONNECTION" != "" ]; then
    tmux attach-session -t ssh_tmux || tmux new-session -s ssh_tmux
fi

Эта команда создает tmux сессию, названную ssh_tmux, если ни один не существует или повторно прикрепляет к уже существующей сессии с тем именем. В случае, если Ваше отброшенное соединение или когда Вы забыли сессию несколько недель назад, каждый вход в систему SSH автоматически, возвращает Вас tmux-ssh сессии, Вы оставили позади.

Подключение от Вашего клиента:

Ничто специальное, всего ssh user@hostname.

69
ответ дан 31 October 2019 в 13:28

Подключение:

ssh user@host -t "tmux new-session -s user || tmux attach-session -t user"

Во время сессии:

Использование Ctrl+d к [1 128] сессия конца (tmux завершения окна) или Ctrl+b d к [1 129] временное отсоединение от сессии и подключения к нему снова позже.

Помнят! , Если Ваш сервер перезапустил проигранную сессию!

, Когда Вы внутри tmux каждый раз, когда можно использовать Ctrl+b s, чтобы видеть список сессий и переключиться текущий на другого.

Фиксируют Ваш .bashrc:

я рекомендую Вам определить универсальную функцию в Вашем .bashrc:

function tmux-connect {
    TERM=xterm-256color ssh -p ${3:-22} $1@$2 -t "tmux new-session -s $1 || tmux attach-session -t $1"
}

Это использует 22 порт по умолчанию. Определите свои псевдонимы быстрого подключения также:

alias office-server='tmux-connect $USER 192.168.1.123'
alias cloud-server='tmux-connect root my.remote.vps.server.com 49281'

Вход в систему без пароля:

И если Вы не хотите вводить пароль каждый раз, чем, генерируют .ssh ключи к [1 134] вход в систему автоматически :

ssh-keygen -t rsa
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_rsa

Помещенный Ваш открытый ключ в удаленный хост:

ssh-copy-id -p <port> user@hostname

Дополнительные подсказки:

, Если Вы хотите использовать временный идентификатор сессии , который соответствует локальному использованию сессии удара в качестве [1 137] идентификатор tmux :

SID=$USER-$BASHPID
ssh user@host -t "tmux new-session -s $SID || tmux attach-session -t $SID"
14
ответ дан 31 October 2019 в 13:28

Я использовал строки от @kingmeffisto (мне не разрешают прокомментировать, что ответ) и я добавил выход, настолько завершающийся tmux также завершает соединение SSH. Это однако повредило сессии SFTP, таким образом, я должен был проверить на $SSH_TTY вместо $SSH_CONNECTION.

РЕДАКТИРОВАНИЕ 4/2018: Добавленный тест для интерактивного терминала через [[ $- =~ i ]], чтобы позволить инструментам как Ansible работать.

if [ -z "$TMUX" ] && [ -n "$SSH_TTY" ] && [[ $- =~ i ]]; then
    tmux attach-session -t ssh || tmux new-session -s ssh
    exit
fi
14
ответ дан 31 October 2019 в 13:28

Как описано в это сообщение в блоге Вы можете ssh и затем присоединять к существующей tmux сессии с единственной командой:

ssh hostname -t tmux attach -t 0
11
ответ дан 31 October 2019 в 13:28

По моему скромному мнению, существует два возможных решения, отсутствующие в списке ответов:

  1. Используя хост ~/.ssh/authorized_keys файл:
command="tmux attach-session -t mysession || tmux new-session -s mysession" ssh-ed25519 AAAAfoo23bar45foo23bar45foo23bar45foo23bar45foo23bar45foo23bar45foo23bar45 user@client

Это будет, конечно, работать от всех клиентов, устанавливающих соответствующий закрытый ключ, который мог или быть - или оборотная сторона, завися. Существует некоторый риск, который должен что-либо идти не так, как надо, не могло бы быть возможно войти в сервер больше.

  1. Используя клиент ~/.ssh/config file, который @op уже использует так или иначе:
Host myhost
  Hostname host
  User user
  RequestTTY yes # tmux needs a tty and won't work without one!
                 # sometimes requires "force" instead of "yes".
  RemoteCommand tmux attach-session -t mysession || tmux new-session -s mysession

Рассмотрение риска с опцией (1), это могло бы быть лучшим решением. В случае любых проблем эти две строки должны просто быть прокомментированными.

3
ответ дан 31 October 2019 в 13:28

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

я использую его с autossh, который корректно повторно подключает ssh сессию. Настоятельно рекомендованный в случае неустойчивых проблем возможности соединения.

function ssh-tmux(){
  if ! command -v autossh &> /dev/null; then echo "Install autossh"; fi
  autossh -M 0 $* -t 'byobu || {echo "Install byobu-tmux on server..."} && bash'
}
1
ответ дан 31 October 2019 в 13:28

Вы могли бы найти, что это полезное - использует ssh в цикле и снова соединяется с или соединяется с существующей tmux сессией, таким образом, у Вас есть хороший легкий надежный способ снова соединиться после сетевого отключения электричества

#!/bin/bash
#
# reconnect to or spawn a new tmux session on the remote host via ssh.
# If the network connection is lost, ssh will reconnect after a small
# delay.
#

SSH_HOSTNAME=$1
TMUX_NAME=$2
PORT=$3

if [[ "$PORT" != "" ]]
then
    PORT="-p $PORT"
fi

if [ "$TMUX_NAME" = "" ]
then
    SSH_UNIQUE_ID_FILE="/tmp/.ssh-UNIQUE_ID.$LOGNAME"

    if [ -f $SSH_UNIQUE_ID_FILE ]
    then
        TMUX_NAME=`cat $SSH_UNIQUE_ID_FILE`
        TMUX_NAME=`expr $TMUX_NAME + $RANDOM % 100`
    else
        TMUX_NAME=`expr $RANDOM % 1024`
    fi

    echo $TMUX_NAME > $SSH_UNIQUE_ID_FILE

    TMUX_NAME="id$TMUX_NAME"
fi

echo Connecting to tmux $TMUX_NAME on hostname $SSH_HOSTNAME

SLEEP=0
while true; do

    ssh $PORT -o TCPKeepAlive=no -o ServerAliveInterval=15 -Y -X -C -t -o BatchMode=yes $SSH_HOSTNAME "tmux attach-session -t $TMUX_NAME || tmux -2 -u new-session -s $TMUX_NAME"
    SLEEP=10
    if [ $SLEEP -gt 0 ]
    then
        echo Reconnecting to session $TMUX_NAME on hostname $SSH_HOSTNAME in $SLEEP seconds
        sleep $SLEEP
    fi
done
1
ответ дан 31 October 2019 в 13:28

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

#attach to the next available tmux session that's not currently occupied
if [[ -z "$TMUX" ]] && [ "SSH_CONNECTION" != "" ];
then
    for i in `seq 0 10`; do #max of 10 sessions - don't want an infinite loop until we know this works
            SESH=`tmux list-clients -t "$USER-$i-tmux" 2>/dev/null` #send errors to /dev/null - if the session doesn't exist it will throw an error, but we don't care
            if [ -z "$SESH" ] #if there's no clients currently connected to this session
            then
                tmux attach-session -t "$USER-$i-tmux" || tmux new-session -s "$USER-$i-tmux" #attach to it
                break #found one and using it, don't keep looping (this will actually run after tmux exits AFAICT)
            fi #otherwise, increment session counter and keep going
    done

fi

существует ограничение в 10 (11) сессии на данный момент - я не хотел уничтожать свой сервер с бесконечным циклом в bashrc. Это, кажется, работает довольно надежно кроме ошибки tmux, переставшего работать на клиентах списка, если сессия не существует.

0
ответ дан 31 October 2019 в 13:28

Другие вопросы по тегам:

Похожие вопросы: