SSH सत्र पर स्वचालित रूप से tmux कैसे शुरू करें?


101

मेरे पास दस या इतने सर्वर हैं जिन्हें मैं नियमित आधार पर एसएसएच के साथ जोड़ता हूं। मेरे स्थानीय कंप्यूटर की ~/.ssh/configफ़ाइल में प्रत्येक की प्रविष्टि है ।

जब मेरा इंटरनेट कनेक्शन अनिवार्य रूप से गिर जाता है, तो मैं अपनी चल रही प्रक्रिया पर नियंत्रण खोने से बचने के लिए, मैं हमेशा एक tmuxसत्र के अंदर काम करता हूं । मुझे लगता है कि SSH कनेक्शन शुरू tmux attach || tmux newहोने के बाद मैं हर बार tmux को स्वचालित रूप से कनेक्ट करने का एक तरीका चाहूँगा, इसलिए मुझे IH के बाद हमेशा टाइप नहीं करना होगा ।

दुर्भाग्य से यह उतना आसान नहीं है जितना कि मैं मूल रूप से आशा करता था।

  • मैं ~/.bashrcसर्वर पर कोई कमांड जोड़ना नहीं चाहता , क्योंकि मैं केवल एसएसएच सत्रों के लिए चाहता हूं, स्थानीय सत्रों के लिए नहीं।
  • सर्वर पर जोड़ने tmux attach || tmux newसे कनेक्शन के बाद फेंकी जा रही ~/.ssh/rcत्रुटि के परिणामस्वरूप not a terminal, यहां तक ​​कि जब RequestTTY forceविकल्प मेरे स्थानीय एसएसएच कॉन्फ़िगरेशन फ़ाइल में उस सर्वर के लिए लाइन में जोड़ा जाता है।

यह एक लोकप्रिय प्रश्न बना हुआ है। मैं बताना चाहता हूँ कि पाँच साल पहले से tmux बहुत बदल गया है; उच्चतर उत्तर शेल के माध्यम से ऐसा नहीं करने के सर्वोत्तम अभ्यास को प्रतिबिंबित नहीं करते हैं, बल्कि इसके माध्यम से करते हैं ~/.ssh/config। अधिकांश लोगों को उत्तर की आवश्यकता होगी, इसलिए stackoverflow.com/a/52838493/5354137 है
सिक्सफाइव

जवाबों:


95

सर्वर-साइड कॉन्फ़िगरेशन:

जब आप 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

यह कमांड एक tmux सेशन बनाता है जिसे कहा जाता है ssh_tmuxकि कोई मौजूद नहीं है या उस नाम के पहले से मौजूद सत्र में reattaches है। यदि आपका कनेक्शन गिर गया है या जब आप एक सप्ताह पहले सत्र को भूल गए हैं, तो हर SSH लॉगिन स्वचालित रूप से आपके द्वारा छोड़े गए tmux-ssh सत्र में वापस लाता है।

अपने ग्राहक से कनेक्ट करें:

कुछ खास नहीं, बस ssh user@hostname


4
मैं इस के लिए देख रहा था, मैं भी कुछ समय पहले आप के लिए बहुत ही कोड के एक टुकड़े का इस्तेमाल किया था, लेकिन सत्र उपयोगकर्ता नाम था (बदलने के ssh_tmuxलिए $USER)
Iacchus

4
बनाम पर उपयोगी टिप्पणी के लिए भी मनीटू का जवाब देखें । $SSH_TTY$SSH_CONNECTION
श्री ताओ

2
यदि आप पहले से मौजूद हैं तो सत्र को संलग्न करने के लिए tmux को बताता है कि यदि आप पहले से मौजूद हैं , तो थोड़ा कम tmux new-session -A -s ssh_tmuxबदलने के लिए उपयोग कर सकते हैंtmux attach-session -t ssh_tmux || tmux new-session -s ssh_tmux-A
ग्रेडिएंट

3
"एससीपी" को तोड़ने से बचने के लिए, आपको यह भी जांचना होगा कि क्या यह एक इंटरेक्टिव शेल है:if [[ -n "$PS1" ]] && [[ -z "$TMUX" ]] && [[ -n "$SSH_CONNECTION" ]];
जैनफ्रोड

3
@janfrode पर निर्भर नहीं है $PS1, [[ $- == *i* ]]बजाय PS1 के रूप में परिभाषित किया जा सकता है, भले ही यह एक इंटरैक्टिव खोल नहीं है।
एनरिको

56

ठीक है, मुझे ज्यादातर संतोषजनक समाधान मिला। मेरे स्थानीय में ~/.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(और उद्धृत करना सुनिश्चित करें $@!)।
चेंपनर

2
नोट: यदि आप नियमित रूप से कनेक्ट होने वाली कुछ मशीनों में tmux स्थापित नहीं करते हैं, तो आप कहना चाह सकते हैं function sshtया आप ऐसा कर सकते हैं ताकि आप sshसामान्य रूप से उपयोग करना जारी रख सकें । अन्यथा, /usr/bin/sshकमांड प्रॉम्प्ट पर टाइप करें जब भी बिना किसी मशीन से कनेक्ट किए tmux :)
एलेक्स रयान

1
यदि आप आलसी हैं, तो आप बस दूरस्थ tmux सत्र से कनेक्ट करने के लिए ssht का उपयोग कर सकते हैं । OS X उपयोगकर्ताओं कर सकते हैं काढ़ा के माध्यम से उसे टैप करें और लिनक्स उपयोगकर्ताओं के माध्यम से एक पैकेज बना सकते हैं एफ पी एम इस के साथ Makefile या बस कॉपी sshtकरने के लिए ~/bin
brejoc

1
हा हा बड़िया! मेकफाइल्स और काढ़ा के साथ पूरे गिथुब रेपो में इस बैश वन-लाइनर को लपेटने के लिए मुझे थोड़ा ओवरकिल जैसा लगता है और हे, लेकिन बेहतर है!
एलेक्स रयान

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

अतिरिक्त सुझाव:

यदि आप अस्थायी सत्र-आईडी का उपयोग करना चाहते हैं, जो स्थानीय बैश सत्र उपयोग के साथ 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
फ्लोरियन वेंडेलबोर्न

4
Tmux के नए संस्करणों में आप इसका उपयोग भी कर सकते हैं tmux new-session -Aजो कि अगर यह मौजूद है तो संलग्न हो जाएगा अन्यथा यह एक नया निर्माण करेगा।
ड्रैगन 788

18

दूरस्थ मशीन पर tmux 3.1 या new¹

अपने स्थानीय में ~/.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 या नए के साथ शिपिंग पहले से काफी लंबी है।

For के newलिए छोटा है new-session

For के atलिए छोटा है attach-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 मारने के बाद थोड़े लिम्बो अवस्था में चला जाता है Ctrl+A Ctrl+Z
एरिक

यह सिर्फ डिस्कनेक्ट करता है। जहां तक ​​मेरा सवाल है, वह व्यवहार है जिसकी मुझे उम्मीद है और मैं इससे खुश हूं।
साठ फेरे

1
Ctrl-B Dकी तुलना में काम करता है Ctrl-B Ctrl-Z। धन्यवाद!
एरिक

1
यह होना चाहिए, imho, सबसे अधिक मतदान का जवाब। मैं बिल्कुल (2) के लिए देख रहा था।
cduguet

17

मैंने @kingmeffisto से पंक्तियों का उपयोग किया (मुझे उस उत्तर पर टिप्पणी करने की अनुमति नहीं है) और मैंने एक निकास जोड़ा है ताकि tmux को समाप्त करना भी ssh कनेक्शन को समाप्त कर दे। हालांकि इसने SFTP सत्रों को तोड़ दिया इसलिए मुझे $SSH_TTYइसके बजाय जांच करनी पड़ी $SSH_CONNECTION

EDIT 4/2018: एंसिबल [[ $- =~ i ]]जैसे टूल को काम करने की अनुमति देने के लिए इंटरेक्टिव टर्मिनल के लिए जोड़ा गया परीक्षण ।

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

15

इस ब्लॉग पोस्ट में वर्णित के रूप में आप ssh कर सकते हैं और फिर एक एकल कमांड के साथ मौजूदा tmux सत्र में संलग्न कर सकते हैं:

ssh hostname -t tmux attach -t 0

1
यही मेरा जवाब है (हालांकि मैं इसका उपयोग करता हूं tmux attach || tmux newताकि हर कनेक्शन के लिए एक नया tmux सत्र नहीं बनाया जाए)। मुश्किल हिस्सा यह है कि सही कमांड है ssh -t user@host tmux attach || tmux newऔर कुछ को उर्फ ​​करने का एकमात्र तरीका है कमांड कमांड के अंदर एक तर्क की आवश्यकता है एक नया फ़ंक्शन बनाने के लिए, जैसे मैंने ऊपर किया था।
एलेक्स रयान

मुझे पता है, लेकिन कुछ लोग (मेरे जैसे) एक लाइनर को पसंद कर सकते हैं, जिसमें एक फ़ंक्शन को परिभाषित करना शामिल नहीं है
फैबियन पेड्रिगोसा

3
यह '0' नामक सत्र से जुड़ता है। यही है, सामान्य रूप हैssh [hostname] -t tmux attach -t [sessionName]
डेविड डोरिया

1
यह मेरे लिए वास्तव में अच्छी तरह से काम किया .. संयुक्त यह unix.stackexchange.com/a/116674 होगा .. तो अब मेरा पोटीन GUI इस तरह दिखता है .. imgur.com/uFhxN30 । मैं Cntrl + b + d के साथ सत्र डिस्कनेक्ट कर सकता हूं। बहुत ही सरल और सुविधाजनक ..
अल्फा_ 989

2

byobu tmux / स्क्रीन के लिए एक अच्छा उपयोगी आवरण है। मौजूदा सत्र से जुड़ता है यदि वर्तमान या एक नया बनाता है।

मैं इसे ऑटोसह के साथ उपयोग करता हूं जो सुशोभित रूप से 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'
}

2

आपको यह उपयोगी लग सकता है - एक पाश में 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

2

यह वह है जो वास्तव में एक महान उपयोगकर्ता-अनुभव बनाता है। जब भी आप टर्मिनल खोलते हैं तो यह स्वचालित रूप से शुरू हो जाता है (शारीरिक रूप से और 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) सत्रों में एक टोपी है - मैं अपने सर्वर को बैशकेन में एक अनंत लूप के साथ नहीं मारना चाहता था। अगर यह सत्र मौजूद नहीं है, तो यह सूची-ग्राहकों पर विफल 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

0

संलग्न अपने दूरस्थ सर्वर के की तह तक~/.bashrc , (या संभवतः अपनी /etc/.bashrc.shared(1)) :

# ======================== PUT THIS LAST IN .BASHRC ==========================
# --- If we're run by SSH, then auto start `tmux` and possibly re-attach user.
#       $-         interactive only via current option flags
#       -z $TMUX   no tmux nesting
#       $SSH_TTY   SSH must be running, and in a shell
#
if [[ $- == *i* ]] && [[ -z "$TMUX" ]] && [[ -n "$SSH_TTY" ]];  then
  tmux attach-session -t "$USER"  || tmux new-session -s "$USER" && exit
fi

ऊपर दिए गए कई अच्छे सुझाव यहां दिए गए हैं , उदाहरण के लिए $-और $SSH_TTYबेहतर है कि मुझे लगता है।

और मुझे इस बूढ़े आदमी को याद रखने में मदद करने के लिए कुछ टिप्पणियां जोड़ना पसंद है कि यह क्या हो रहा है।

और अंत में, मैं अंत में एक exitघर में आने पर सफाई से रहना पसंद करता हूं।

सबको धन्यवाद।


नोट I स्रोत और साझा /etc/.bashrc.sharedदोनों के अंत में एक साझा स्रोत है .bashrc, दोनों में इस्तेमाल होने वाले सामान्य सामान के लिए, जैसे कि रंगीन ls, विभिन्न उपनाम, फ़ंक्शन और पथ एक्सटेंशन, अर्थात मैं अपने रूट / .bashrc में न तो अनावश्यक कोड चाहता हूं और न ही उपयोगकर्ता। /.bashrc।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.