web-dev-qa-db-ja.com

SSHセッションでtmuxを自動的に開始する方法は?

定期的にSSHで接続するサーバーが10台ほどあります。それぞれ、ローカルコンピューターの~/.ssh/configファイルにエントリがあります。

インターネット接続が必然的に切断されたときに実行中のプロセスの制御が失われないようにするために、私は常にtmuxセッション内で作業します。 SSH接続が開始されるたびにtmuxが自動的に接続されるようにしたいので、SSHを入力した後にtmux attach || tmux newを入力する必要はありません。

残念ながら、これは私が当初望んでいたほど単純ではないことがわかりました。

  • サーバー上の~/.bashrcにコマンドを追加したくないのは、ローカルセッションではなくSSHセッションにのみ必要だからです。
  • サーバーのtmux attach || tmux new~/.ssh/rcを追加すると、接続後にnot a terminalオプションがそのサーバーの行に追加された場合でも、接続後にエラーRequestTTY forceがスローされます。ローカルSSH構成ファイル。
58
Alex Ryan

さて、私はほとんど満足のいく解決策を見つけました。ローカル~/.bashrcで、関数を作成しました。

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

これは基本的にssh端末関数を上書きし、指定された引数に"tmux attach || tmux new"を続けて組み込みsshプログラムを呼び出します。

$@はコマンドラインで提供されるすべての引数を示すため、ssh -p 123 user@hostnamessh -t -p 123 user@hostname "tmux attach || tmux new"に展開されます)

-t引数はRequestTTY Forceと同等であり、tmuxコマンドに必要です。)

43
Alex Ryan

サーバー側の構成:

通常、SSH(およびSSHのみ)を介してログインするときにリモートサーバーでtmuxを自動的に開始するには、それに応じてリモートサーバーのユーザーまたはルート(または両方)の~/.bashrcを編集します。

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

このコマンドは、ssh_tmuxというtmuxセッションを作成します(存在しない場合)、またはその名前の既存のセッションに再接続します。接続が切断された場合、または数週間前にセッションを忘れた場合、SSHログインごとに、残されたtmux-sshセッションに自動的に戻ります。

クライアントから接続します。

特別なものは何もありません、ただssh user@hostname

61
kingmeffisto

@kingmeffistoの行を使用し(その答えをコメントすることはできません)、出口を追加して、tmuxを終了するとssh接続も終了するようにしました。ただし、これによりSFTPセッションが中断されたため、$SSH_TTYではなく$SSH_CONNECTIONを確認する必要がありました。

EDIT 4/2018:[[ $- =~ i ]]を介した対話型ターミナルのテストを追加して、Ansibleなどのツールが動作できるようにしました。

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

接続:

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

セッション中:

Ctrl+dを使用してセッションの終了(tmuxウィンドウを閉じる)またはCtrl+b dを使用して一時的なデタッチからセッションに再接続します。

覚えておいてください!サーバーがセッションを再開した場合、セッションは失われます!

Tmux内にいるときはいつでもCtrl+b sを使用してsessions listを表示し、現在のものを別のものに切り替えることができます。

。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キーを生成して自動的にログインにします。

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

公開鍵をリモートホストに配置します。

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

追加のヒント:

ローカルbashセッションに対応するtemporary session-idを使用する場合は、tmux idとして使用します。

SID=$USER-$BASHPID
ssh user@Host -t "tmux new-session -s $SID || tmux attach-session -t $SID"
10
DenisKolodin

このブログ投稿 で説明されているように、単一のコマンドで既存のtmuxセッションにsshしてから接続できます。

ssh hostname -t tmux attach -t 0
9

私見では、回答のリストに2つの解決策がありません:

  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)のリスクを考慮すると、これがより良い解決策かもしれません。問題が発生した場合は、2行をコメントアウトするだけで済みます。

3

byob は、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
Sandeep

これは便利かもしれません-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
Neil McGill

私は古いスレッドを復活させていることを知っていますが、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
Brydon Gibson