Подтвердить что ты не робот

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

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

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

К сожалению, это не так просто, как я надеялся.

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

Ответ 1

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

function ssh () {/usr/bin/ssh -t [email protected] "tmux attach || tmux new";}

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

([email protected] обозначает все аргументы, предоставленные в командной строке, поэтому ssh -p 123 [email protected] будет расширен до ssh -t -p 123 [email protected] "tmux attach || tmux new")

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

Ответ 2

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

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

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 [email protected].

Ответ 3

Connect:

ssh [email protected] -t "tmux new-session -s user || tmux attach-session -t user"

Во время сеанса:

Используйте Ctrl+d для завершить сеанс (закрытие tmux) или Ctrl+b d до временного отсоединения из сеанса и снова подключиться к нему.

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

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

Исправьте свой .bashrc:

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

function tmux-connect {
    TERM=xterm-256color ssh -p ${3:-22} [email protected]$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 для автоматического входа в систему:

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

Поместите открытый ключ на удаленный хост:

ssh-copy-id -p <port> [email protected]

Дополнительные советы:

Если вы хотите использовать временный идентификатор сеанса, который соответствует локальному сеансу bash, используйте как tmux id:

SID=$USER-$BASHPID
ssh [email protected] -t "tmux new-session -s $SID || tmux attach-session -t $SID"

Ответ 4

Я использовал строки из @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

Ответ 5

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

ssh hostname -t tmux attach -t 0

Ответ 6

ИМХО, в списке ответов отсутствуют два возможных решения:

  1. Использование файла хоста ~/.ssh/authorized_keys:
command="tmux attach-session -t mysession || tmux new-session -s mysession" ssh-ed25519 AAAAfoo23bar45foo23bar45foo23bar45foo23bar45foo23bar45foo23bar45foo23bar45 [email protected]

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

  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), это может быть лучшим решением. В случае каких-либо проблем, две строки должны быть просто закомментированы.

Ответ 7

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'
}

Ответ 8

Вы можете найти это полезным - использует 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

Ответ 9

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

#attach to the next available tmux session that 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 does not exist it will throw an error, but we don't care
            if [ -z "$SESH" ] #if there 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 на клиентах списка, если сеанс не существует.

Ответ 10

Самое простое решение (добавление в файл config руин rsync поверх ssh)

Подключается к последнему tmux или создает новый

ssh hostname -t tmux a || tmux