it-swarm.com.de

Wie starte ich tmux automatisch bei einer SSH-Sitzung?

Ich habe ungefähr zehn Server, die ich regelmäßig mit SSH verbinde. Jeder hat einen Eintrag in der ~/.ssh/config-Datei meines lokalen Computers.

Um zu vermeiden, die Kontrolle über den laufenden Prozess zu verlieren, wenn meine Internetverbindung unvermeidlich unterbrochen wird, arbeite ich immer in einer tmux-Sitzung. Ich möchte, dass tmux bei jedem Start einer SSH-Verbindung automatisch eine Verbindung herstellt, so dass ich nicht immer tmux attach || tmux new eingeben muss, nachdem ich SSH eingegeben habe.

Leider ist das nicht so einfach, wie ich ursprünglich gehofft hatte.

  • Ich möchte dem ~/.bashrc auf den Servern keine Befehle hinzufügen, da ich ihn nur für SSH-Sitzungen und nicht für lokale Sitzungen verwenden möchte.
  • Das Hinzufügen von tmux attach || tmux new zu ~/.ssh/rc auf den Servern führt einfach dazu, dass der Fehler not a terminal nach der Verbindung ausgegeben wird, selbst wenn die RequestTTY force-Option in die Zeile für diesen Server in meiner lokalen SSH-Konfigurationsdatei eingefügt wird.
50
Alex Ryan

Okay, ich fand eine meist befriedigende Lösung. In meinem lokalen ~/.bashrc habe ich eine Funktion geschrieben:

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

diese Funktion überschreibt grundsätzlich die ssh-Terminalfunktion, um das integrierte ssh-Programm mit den angegebenen Argumenten aufzurufen, gefolgt von "tmux attach || tmux new".

(Der [email protected] bezeichnet alle Argumente in der Befehlszeile, daher wird ssh -p 123 [email protected] zu ssh -t -p 123 [email protected] "tmux attach || tmux new" erweitert.)

(Das Argument -t entspricht RequestTTY Force und ist für den Befehl tmux erforderlich.)

38
Alex Ryan

Serverseitige Konfiguration:

Um tmux automatisch auf Ihrem Remote-Server zu starten, wenn Sie sich normalerweise über SSH (und nur über SSH) anmelden, bearbeiten Sie den ~/.bashrc Ihres Benutzers oder Root (oder beides) auf dem Remote-Server entsprechend: 

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

Dieser Befehl erstellt eine tmux-Sitzung mit dem Namen ssh_tmux, wenn keine vorhanden ist, oder fügt eine bereits vorhandene Sitzung mit diesem Namen wieder hinzu. Falls Ihre Verbindung abgebrochen wurde oder Sie vor Wochen eine Sitzung vergessen haben, werden Sie bei jeder SSH-Anmeldung automatisch zu der zurückgelassenen tmux-ssh-Sitzung zurückgeführt.

Verbinden Sie sich von Ihrem Kunden:

Nichts Besonderes, nur ssh [email protected].

50
kingmeffisto

Ich habe Zeilen von @kingmeffisto verwendet (ich darf diese Antwort nicht kommentieren) und ich habe einen Exit hinzugefügt, so dass das Beenden von tmux auch die SSH-Verbindung beendet. Dies brach jedoch die SFTP-Sitzungen, sodass ich statt $SSH_TTY nach $SSH_CONNECTION suchen musste.

EDIT 4/2018: Test für interaktives Terminal über [[ $- =~ i ]] hinzugefügt, damit Werkzeuge wie Ansible funktionieren können.

if [ -z "$TMUX" ] && [ -n "$SSH_TTY" ] && [[ $- =~ i ]]; then
    tmux attach-session -t ssh || tmux new-session -s ssh
    exit
fi
10
moneytoo

Wie in diesem Blogbeitrag beschrieben, können Sie ssh verwenden und dann mit einem einzigen Befehl an eine vorhandene tmux-Sitzung anschließen:

ssh hostname -t tmux attach -t 0
7

Verbinden:

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

Während der Sitzung:

Verwenden Sie Ctrl+d für finish session (tmux-Fenster schließt sich) oder Ctrl+b d für temporäres Trennen von der Sitzung und stellen Sie später erneut eine Verbindung her.

Merken! Wenn Ihre Server-Sitzung erneut gestartet wurde!

Wenn Sie sich innerhalb von tmux befinden, können Sie Ctrl+b s verwenden, um die sessions list anzuzeigen und die aktuelle Version zu wechseln.

Fix your .bashrc:

Ich empfehle Ihnen, die Universalfunktion in Ihrem .bashrc zu definieren:

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

Es verwendet standardmäßig 22 Port. Definieren Sie auch Ihre Fast-Connect-Aliase:

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

Login ohne Passwort:

Und wenn Sie nicht jedes Mal ein Kennwort eingeben möchten, generieren Sie automatisch .ssh-Schlüssel für login:

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

Legen Sie Ihren öffentlichen Schlüssel an den entfernten Host:

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

Zusätzliche Tipps:

Wenn Sie temporäre Sitzungs-ID verwenden möchten, die einer lokalen Bash-Sitzung entspricht, verwenden Sie tmux id:

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

byobu ist ein nützlicher Wrapper für tmux/screen. Stellt eine Verbindung zu einer vorhandenen Sitzung her, falls vorhanden, oder erstellt eine neue.

Ich verwende es mit autossh , wodurch die SSH-Sitzung wieder ordnungsgemäß verbunden wird. Sehr empfehlenswert bei intermittierenden Verbindungsproblemen.

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
Sandeep

Dies könnte nützlich sein - verwendet ssh in einer Schleife und stellt eine Verbindung zu einer vorhandenen tmux-Sitzung her oder stellt eine Verbindung zu einer vorhandenen tmux-Sitzung her

#!/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
Neil McGill

IMHO gibt es zwei mögliche Lösungen in der Liste der Antworten:

  1. Verwenden der ~/.ssh/authorized_keys-Datei des Hosts:
command="tmux attach-session -t mysession || tmux new-session -s mysession" ssh-ed25519 AAAAfoo23bar45foo23bar45foo23bar45foo23bar45foo23bar45foo23bar45foo23bar45 [email protected]

Dies funktioniert natürlich von allen Clients aus, auf denen der entsprechende private Schlüssel installiert ist. Dies kann je nach Vor- oder Nachteile erfolgen. Es besteht das Risiko, dass bei einem Fehler etwas nicht mehr auf den Server gelangt.

  1. Verwenden Sie den ~/.ssh/config file des Clients, den @op sowieso bereits verwendet:
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

In Anbetracht des Risikos mit Option (1) ist dies möglicherweise die bessere Lösung. Bei Problemen müssen die beiden Zeilen einfach auskommentiert werden.

0

Ich weiß, dass ich einen alten Thread wiederbelebe, aber ich habe ein bisschen an der bashrc-Lösung gearbeitet, und ich denke, es hat etwas Verwendung:

#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

Für 10 (11) Sitzungen gibt es jetzt eine Obergrenze - Ich wollte meinen Server nicht mit einer Endlosschleife in bashrc beenden. Es scheint ziemlich zuverlässig zu funktionieren, abgesehen von dem Fehler, dass tmux auf List-Clients fehlschlägt, wenn die Sitzung nicht vorhanden ist.

0
Brydon Gibson