SSH 세션에서 tmux를 자동으로 시작하는 방법은 무엇입니까?


92

정기적으로 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 구성 파일에서 해당 서버의 라인에 추가됩니다.

1
이것은 계속해서 인기있는 질문이며 구체적으로 언급하고 있습니다 ~/.ssh/config. 여기에 오는 대부분의 사람들은 아마도 처음 5 개 답변 중 하나를 찾지 않고 6 번째 답변을 찾고있을 것입니다 ( stackoverflow.com/a/52838493/5354137 ). 합리적으로 최신 tmux버전을 사용하면 작업을 수행하는 가장 합리적인 방법이기도합니다.
Sixtyfive

답변:


90

서버 측 구성 :

일반적으로 SSH (및 SSH 만)를 통해 로그인 할 때 원격 서버에서 tmux를 자동으로 시작하려면 원격 서버에서 ~/.bashrc사용자 또는 루트 (또는 둘 다)를 적절히 편집합니다.

if [[ -n "$PS1" ]] && [[ -z "$TMUX" ]] && [[ -n "$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.


4
나는이 찾고 있었다, 또한 내가 몇 시간 전에 당신과 매우 비슷한 코드의 조각을 사용하지만 세션은 사용자 이름이었다 (변화 ssh_tmux$USER)
Iacchus

3
vs too 에 대한 유용한 의견 은 moneytoo의 답변 을 참조하십시오 . $SSH_TTY$SSH_CONNECTION
Mr. Tao

2
좀 더 혼란 스러울 경우 훨씬 더 짧게 tmux new-session -A -s ssh_tmux바꾸는 tmux attach-session -t ssh_tmux || tmux new-session -s ssh_tmux데 사용할 수 있습니다. -A이미 존재하는 경우 세션을 연결하도록 tmux에 지시합니다.
Gradient

3
"scp"가 깨지지 않도록하려면 이것이 대화 형 쉘인지 확인해야합니다.if [[ -n "$PS1" ]] && [[ -z "$TMUX" ]] && [[ -n "$SSH_CONNECTION" ]];
janfrode

2
@janfrode는에 의존하지 않고 대신 $PS1사용 [[ $- == *i* ]]합니다. PS1은 대화 형 쉘이 아닌 경우에도 정의 될 수 있기 때문입니다.
Enrico

53

좋습니다. 대부분 만족스러운 해결책을 찾았습니다. 내 로컬 ~/.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 Forcetmux 명령과 동일하며 필수입니다.)


22
tmux사용 tmux new -A foo중인 버전에서 지원하는 foo경우 가능한 경우 이름이 지정된 기존 세션에 첨부되는 사용 을 고려 하고 필요한 경우 작성하십시오. 이렇게하면 함수를 다음 /usr/bin/ssh -t "$@" tmux new -A과 같이 단순화 할 수 있습니다 (그리고 반드시 인용하십시오 $@!).
chepner

1
참고 : 정기적으로 연결하는 일부 컴퓨터에 tmux가 설치되어 있지 않은 경우 function ssht계속해서 ssh정상적으로 사용할 수 있도록 등 을 말할 수 있습니다 . 그렇지 않으면, 단지 입력 /usr/bin/sshTMUX :)없이 시스템에 연결할 때마다 명령 프롬프트에서
알렉스 라이언

1
게으르다면 ssht 를 사용하여 원격 tmux 세션에 연결할 수 있습니다. OS X 사용자 수 양조를 통해 그것을 탭 및 리눅스 사용자를 통해 패키지를 만들 수 있습니다 FPM 이와 메이크 하거나 복사 ssht~/bin.
brejoc

1
하하! Makefiles 및 brew 등을 사용하여 전체 Github 리포지토리 에이 bash one-liner를 감싸는 것은 약간의 과잉처럼 보이지만 헤이, 더 쉬울수록 좋습니다!
Alex Ryan

1
해결 :ssh -t user@hostname "LANG=$LANG tmux attach || tmux new"
alecdwm

23

잇다:

ssh user@host -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} $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

추가 팁 :

당신이 사용하려는 경우 일시적으로 세션 ID 와 같은 지역의 bash 세션 사용에 해당 TMUX ID를 :

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

1
깔끔한 트릭는 것을 방지하기 위해 ||일부 사용 사례에 포함하는 것입니다 new-session.tmux.conf그냥 항상 사용합니다 tmux a -t 0.
Florian Wendelborn

4
최신 버전의 tmux tmux new-session -A에서는 존재하는 경우 첨부 할 수도 있습니다. 그렇지 않으면 새 버전 이 생성됩니다.
dragon788

15

@kingmeffisto의 줄을 사용했으며 (그 대답에 대해 주석을 달 수 없습니다) 종료를 추가하여 tmux를 종료하면 ssh 연결도 종료됩니다. 그러나 이것은 SFTP 세션을 깨뜨 렸으므로 $SSH_TTY대신 확인해야했습니다 $SSH_CONNECTION.

2018 년 4 월 수정 : [[ $- =~ i ]]Ansible과 같은 도구가 작동 할 수 있도록을 통한 대화 형 터미널 테스트가 추가되었습니다 .

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

14

이 블로그 게시물에 설명 된대로 ssh를 수행 한 다음 단일 명령으로 기존 tmux 세션에 연결할 수 있습니다.

ssh hostname -t tmux attach -t 0

그것이 내 대답이하는 일입니다 ( tmux attach || tmux new모든 연결에 대해 새로운 tmux 세션이 생성되지 않도록 사용하지만 ). 까다로운 부분은 올바른 명령이 ssh -t user@host tmux attach || tmux new있고 명령 문자열 내에서 인수가 필요한 항목의 별칭을 지정하는 유일한 방법은 위에서했던 것처럼 새 함수를 만드는 것입니다.
Alex Ryan

나는 알고 있지만, (나 같은) 어떤 사람들은 함수를 정의 포함하지 않는 한 줄 선호 할 수
파비안 Pedregosa

3
이것은 '0'이라는 세션에 연결됩니다. 즉, 일반적인 형태는ssh [hostname] -t tmux attach -t [sessionName]
데이비드 도리아

1
이것은 나를 위해 정말 잘 작동했습니다 .. 결합하면 unix.stackexchange.com/a/116674 .. 그래서 이제 퍼티 GUI는 다음과 같습니다 .. imgur.com/uFhxN30 . Cntrl + b + d로 세션 연결을 끊을 수 있습니다. 매우 간단하고 편리합니다 ..
alpha_989 aug

14

원격 시스템의 tmux 3.1 이상 ¹

현지 ~/.ssh/config, put² :

Host myhost
  Hostname host
  User user
  RequestTTY yes
  RemoteCommand tmux new -A -s foobar

관련이 없지만 ASCII가 아닌 문자를 다루는 경우 tmux -u …적절한 환경 변수가 설정되지 않은 컴퓨터에서도 유니 코드 지원을 명시 적으로 활성화하기 위해 로 변경하는 것이 좋습니다 .

원격 컴퓨터의 tmux 3.0a 이상

위와 거의 동일하지만 마지막 줄을 ³ :

  RemoteCommand tmux at -t foobar || tmux new -s foobar

¹ 2020 년 10 월 29 일 현재 tmux 3.1 이상과 함께 제공되는 배포 목록 이미 상당히 깁니다.

² newnew-session.

³ atattach-session.


원격 authorized_keys파일을 사용하는 다른 방법 :

~/.ssh/config어떤 이유로 든 파일을 갖고 싶지 않거나 원격 시스템이 연결 시스템이 세션에 연결 / 열도록 강제하려면 다음을 원격 장치에 추가하십시오 ~/.ssh/authorized_keys.

command="tmux at -t foobar || tmux new -s foobar" pubkey user@client

물론 이것은 해당 개인 키가 설치된 모든 클라이언트 에서 작동하며 원하는 항목에 따라 위 또는 아래가 될 수 있습니다. 문제가 발생하면 더 이상 연결할 수없는 위험이 있습니다.


tmux at대신 tmux a? 또한이 세션에 대해 명명 된 세션을 사용하는 것이 현명합니다. 그렇지 않으면 tmux가 호스트에 로그인 할 때 "무작위"기존 세션에 연결됩니다.
에릭

tmux 세션을 어떻게 일시 중단합니까? ssh는을 누른 후 kindda 림보 상태로 들어갑니다 Ctrl+A Ctrl+Z.
Eric

연결이 끊어집니다. 내가 생각하는 한, 그것이 내가 기대하고 만족하는 행동이다.
Sixtyfive

1
Ctrl-B D작품은 Ctrl-B Ctrl-Z. 감사!
에릭

1
이것은, imho, 가장 많이 득표 한 대답이어야합니다. 나는 정확히 (2)를 찾고 있었다.
cduguet

1

byobu TMUX / 화면을위한 좋은 유용한 래퍼입니다. 존재하는 경우 기존 세션에 연결하거나 새 세션을 만듭니다.

ssh 세션을 정상적으로 다시 연결하는 autossh 와 함께 사용합니다 . 간헐적 인 연결 문제가있는 경우 적극 권장됩니다.

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

이것이 유용하다는 것을 알 수 있습니다-루프에서 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

이것은 실제로 훌륭한 사용자 경험을 생성하는 것입니다. 터미널을 열 때마다 자동으로 tmux를 시작합니다 (물리적으로 및 ssh 모두). 한 장치에서 작업을 시작하고 터미널을 종료 한 다음 다른 장치에서 다시 시작할 수 있습니다. 세션에 이미 연결된 누군가를 감지하면 새 세션을 생성합니다. 넣어 서버에서 쉘에 따라, ~/.zshrc또는 ~/.bashrc.

 if [[ -z "$TMUX" ]] ;then
     ID="$( tmux ls | grep -vm1 attached | cut -d: -f1 )" # get the id of a deattached session
     if [[ -z "$ID" ]] ;then # if not available attach to a new one
         tmux new-session
     else
         tmux attach-session -t "$ID" # if available attach to it
     fi
fi

0

나는 오래된 스레드를 되 살리고 있다는 것을 알고 있지만 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

이렇게하면 ssh 세션이 중단되는 경우 이전 tmux 인스턴스에 다시 연결할 수 있습니다. 는 exec물론 포크를 저장합니다.

if [ -z "$TMUX"  ]; then
  pid=$(tmux ls | grep -vm1 "(attached)" | cut -d: -f1)
  if [ -z "$pid" ]; then
    tmux new -d -s $pid
  fi

  exec tmux attach -t $pid
fi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.