Automatisch tmux session start/attach nach einem SSH Login

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Automatisch tmux session start/attach nach einem SSH Login

Beitrag von pangu » 05.11.2012 12:36:09

Hi Leute,

oft logge ich mich über SSH auf einem Host ein, und vergessen tmux zu starten. Dann passiert ist es nicht wenige Male, dass ich mit irgendwelchen Prozessen beginne, die länger dauern. Erst spät bemerke ich dann, dass ich gar keine tmux session gestartet hatte. Es gibt kein zurück mehr :evil: Jetzt frage ich mich gerade, ob ihr Möglichkeiten kennt oder sogar evtl. fertige Skripts, um nach einem ssh Login automatisch zu prüfen:

ist eine einzige tmux session unter den angemeldeten User aktiv, soll automatisch attached werden (tmux attach)

sind nach dem login mehrere tmux sessions aktiv, sollen diese session aufgezeigt werden und anschließend abgefragt werden, an welche session man attachen möchte. Keine Eingabe (=leer, oder Enter) soll die letz gestartete Session wieder aufnehmen.

ist keine einzige tmux session aktiv, soll automatisch eine tmux session erzeugt werden (für Leute wie mich, die das ständig vergessen *g*)

Oder ist das generell aus bestimmten Gründen nicht empfehlenswert? unter /usr/local/share/examples/tmux konnte ich zwar einige Konfigurationen von diversen Leuten finden, aber leider kein Script für die shell (bash,tcsh, oder was auch immer. X interessiert mich nicht, da ich es nicht nutze). Freue mich auf euer feedback.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

uname
Beiträge: 12406
Registriert: 03.06.2008 09:33:02

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von uname » 05.11.2012 12:53:30

In z.B. ~/.bash_profile:

Code: Alles auswählen

if [ -z $TMUX ];   then                 
  /usr/bin/tmux attach || /usr/bin/tmux new
fi  
Hiermit wird immer wieder dieselbe TMUX-Sitzung gestartet. Sollte keine vorhanden sein wird eine neue erzeugt. Mag bei einer anderen Shell anders sein.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von pangu » 05.11.2012 13:16:02

Danke. Habe HIER noch einige Anregungen gefunden...
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von pangu » 08.07.2013 10:35:19

Könnte man das noch etwas umschreiben, damit folgendes passiert:

wenn man sich einloggt und irgendwelche tmux-sessions bereits bestehen, soll dem user eine Liste mit den vorhandenen sessions angezeigt werden (natürlich nur die, die mit seinem Benutzernamen gemacht wurden). Er soll dann entscheiden dürfen, ob er an eine dieser sessions "attachen" möchte, oder ob er eine neue shell haben möchte (normal, oder tmux session).

momentan habe ich in meiner /etc/bash.bashrc lediglich folgendes stehen:

Code: Alles auswählen

if which tmux 2>&1 >/dev/null; then
    test -z "$TMUX" && (tmux attach || tmux new-session)
fi
damit prüfe ich ob es das Programm tmux überhautp gibt, und falls es TMUX sessions gibt dann wird automatisch auf diese attached, ansonsten eine new-sessions erstellt. Ich würde aber gerne diese Abfrage da eingebaut haben. Aber nicht die übliche Abfrage wo man abshcließend die ENTER Taste betätigen muß, sondern so dass quasi ständig eingelesen wird, und sobald man die Taste J oder N drückt, soll eben attached werden oder nicht (Ja/Nein). Wenn innerhalb 10sek keine Eingabe erfolgt, so soll automatisch per default attached werden.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von Cae » 08.07.2013 15:10:04

Wie mir gerade auffaellt, es ist nich nach Debianscreen gefragt, sondern nach Debiantmux... ;) naja, hier ist eine Loesung fuer screen:

Code: Alles auswählen

#!/bin/bash

list="$(screen -ls | grep 'ched)$' | cat -n)"

if [ -z "$list" ]; then
	screen;
	exit $?;
fi

echo "$list";
read -p 'attach to one of them? [number/s/y/n] ' -n 1 choice
echo;

case "$choice" in
s)
	screen;
	;;
n)
	exit 0;
	;;
y)
	screen -D -r
	;;
[0-9])
	screen -D -r "$(echo "$list" | awk '/^ *'"$choice"'/{ print $2; }')";
	;;
*)
	echo "invalid choice '$choice'";
	exit 1;
	;;
esac
Falls es keinen screen gibt, wird kommentarlos einer erstellt, ansonsten wird eine Liste angezeigt, wo man per Nummer einen der bestehenden screens attachen kann, einen neuen erstellen oder das Skript beenden kann. Bash braucht das fuer read -n 1.

Gruss Cae

--Edit: Fuer tmux ist das sogar noch simpler, weil's u.a. schon die eingebaute nummerierte Liste hat:

Code: Alles auswählen

#!/bin/bash

list="$(tmux list-sessions)"

if [ -z "$list" ]; then
	tmux;
	exit $?;
fi

echo "$list";
read -p 'attach to one of them? [number/t/y/n] ' -n 1 choice
echo;

case "$choice" in
t)
	tmux;
	;;
n)
	exit 0;
	;;
y)
	tmux attach -d
	;;
[0-9])
	tmux attach -d -t "$choice"
	;;
*)
	echo "invalid choice '$choice'";
	exit 1;
	;;
esac
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von pangu » 08.07.2013 19:15:17

Hallo Cae und danke soweit.

Ich möchte das jedoch etwas umbauen und nicht case benutzen. Ich will das so ähnlich machen wie beim Befehl "choice" aus der Windowswelt (falls du den kennst). Da wird keine ENTER-Taste erwartet. Ich habe mich dazu etwas schlau gemacht wie das bei Linux gehen könnte und auch fündig geworden. Hier stößt man an das Problem dass bei einem Terminal eine Zeilenpufferung stattfindet, also dass man auf eine ENTER-Taste warten muss. Mit dem Kommando stty und der Option raw kann man das jedoch ausschalten und "raw" characters bearbeiten. Natürlich sollte man wenn man mit der gewünschten Verarbeitung fertig wird, diesen raw Modus wieder verlassen. Read kann man hier nicht verwenden, denn das kann kein einzelnes Zeichen lesen. Also verwendet man das bekannte Kommando dd als Trick. Das Kommando dd kann eine Datei einlesen und man kann die Blockgröße angeben wie gelesen und geschrieben werden soll.

Es klappt also wie folgt:

Code: Alles auswählen

stty raw -echo
char=`dd bs=1 count=1 2>/dev/null`
stty -raw echo
echo "Die Taste war $char"
Damit habe ich schonmal den Befehl "choice" aus der Windowswelt nachgeahmt. Nun möchte ich ja die aktiven tmux-sessions anzeigen lassen. Ich kann das mit dem Befehl

Code: Alles auswählen

tmux list-sessions
ausführen und als Output erhält man mit diesem Befehl folgendes:
0: 1 windows (created Mon Jul 8 17:23:22 2013) [100x59]
1: 1 windows (created Mon Jul 8 17:23:26 2013) [100x59]
2: 1 windows (created Mon Jul 8 19:10:35 2013) [100x59]
Ich möchte jetzt diese 0, 1 und die 2 als Variablen irgendwie speichern, so dass ich das mit dem oben gezeigten Schnipsel kombinieren kann. Wenn also die Taste 1 gedrückt wird, soll der Befehl "tmux attach -t1" ausgeführt werden.

Ich habs mal so versucht:

Code: Alles auswählen

 TMUXSESSIONS=$(tmux ls | cut -d: -f1)
das spuckt mir aber als Ergebnis aus:

Code: Alles auswählen

# echo $TMUXSESSIONS
0 1 2
Wie komme ich hier an mein Ziel. Sorry für diese vielleicht alberne Frage, weil das sicherlich zu den Basics von Shellscriptprogrammierung gehört, aber irgendwie hab ich hier grad nen Denkfehler vermute ich. Kann ich denn so nach diesem Vorgehen überhaupt diese drei Ziffern als Variablen irgendwie speichern? oder bin ich mit "cut" total falsch, und sollte lieber irgendwie "awk" mit dem Schalter -v verwenden ?
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von pangu » 08.07.2013 23:38:02

Hallo nochmal,

ich hab mich gegen diesen Terminal und dd-Trick entschiedn und arbeite nun mit dem "read -N" Befehl. Ich bin auch schon am Ziel eigentlich angekommen. Kleinigkeiten werden sich vllt. im Laufe der nächsten Wochen und Monate bemerkbar machen. Momentan schaut's ganz gut aus. Ich möchte meine Arbeit nicht vorenthalten und poste daher meinen wrapper, den ich als ausführbar gesetzt und als /usr/local/bin/tmuxsession gespeichert habe. Meine globale bash bzw. zsh Konfiguration (/etc/bash.bashrc, bzw. /etc/zsh/zshrc) ruft diesen wrapper auf, damit sowohl die bash- als auch die zsh-user in den Genuss von dieser tmux-Technik gelangen. Ich hab auch ein klein wenig Farbe reingebracht, damit das schöner ausschaut.

/usr/local/bin/tmuxsession:

Code: Alles auswählen

#!/bin/bash
# ------------------------/usr/local/bin/tmuxsession----------------------------------------------
# by Pangu, 08.07.2013

# Erklärung: Das Skript prüft, ob unter dem angemeldeten Usernamen bereits irgendwelche TMUX-sessions
# noch aktiv sind. Falls ja, dann kann mit einer Abfrage direkt gewählt werden, auf welche dieser
# aktiven Sessions man andocken möchte. Oder man erstellt einfach eine neue TMUX-session und arbeitet
# anschließend darin.

WARNHINWEIS="\n\n\n\033[01;41mHINWEIS!\033[00;00m Du befindest dich nicht mehr in einer TMUX-session. Es ist jedoch empfohlen immer innerhalb einer TMUX-session zu arbeiten. Beim nächsten Login wird standardmäßig TMUX wieder verwendet. Wenn du jedoch jetzt sofort wieder in TMUX arbeiten möchtest so gebe einfach den Befehl \e[00;33mtmuxsession\e[0m in der prompt ein."

if ! [ -z $TMUX ]; then
 exit 1
fi

if [ -z "`tmux ls 2>/dev/null`" ]; then
 tmux new-session
 echo -e $WARNHINWEIS
 exit 1
fi

inarray() {
        local n=$1 h
        shift
        for h; do
                [[ $n = "$h" ]] && return
        done

        return 1
}

while IFS=: read num rest
do
        sessions+=( "$num" )
        printf '%s: %s\n' "$num" "$rest"
done < <(tmux ls)

while :
do
        printf 'An welcher TMUX-session soll angedockt werden? '
        printf '[\033[01;32m%s\033[0m] ' "${sessions[@]}"
        printf 'oder [\033[01;34mN\033[0m]eue TMUX-session erstellen? '
        read -N 1 -s
        if inarray "$REPLY" "${sessions[@]}"; then
                tmux a -t "$REPLY"
                echo -e $WARNHINWEIS
                break
        elif [[ $REPLY = [Nn] ]]; then
               tmux new-session
                echo -e $WARNHINWEIS
                break
        else
                echo "Ungültige Eingabe!"
        fi
done
In meiner /etc/zsh/zshrc habe ich dann ganz am Anfang einfach die Zeile
/usr/local/bin/tmuxsession
reingeschrieben. So wird dieses Skript immer gestartet, nachdem sich der User anmeldet und von der globale zsh-Konfigurationsdatei verarbeitet wird. Da ja nach dem Starten von tmux nochmals das Loginskript /etc/zsh/zshrc ausgeführt wird (ist ja normal), habe ich deswegen extra ganz oben zu Beginn meines Skriptes die Abfrage eingebaut: falls Variable $TMUX keine leere Zeichenkette enthält, wird abgebrochen (mit exit 1).

Mit Sicherheit werden die Profis unter euch mehrere Fehler finden und anmeckern, und ich bin mir sicher dass man das auch mit weniger Zeilen und schönerem Code schreiben kann. Ich bin jedoch noch ein Anfänger was Scripting und Programmierung angeht, daher habe ich mich versucht soweit es geht mir zu behelfen. Ich bin natürlich trotzdem gerne dankbar, wenn ihr mich korrigieren oder ergänzen könnt. Der Lernfaktor ist mir immer von großer Bedeutung.
Zuletzt geändert von pangu am 09.07.2013 13:27:05, insgesamt 4-mal geändert.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Benutzeravatar
hupfdule
Beiträge: 1864
Registriert: 09.12.2002 15:04:37
Wohnort: Berlin
Kontaktdaten:

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von hupfdule » 09.07.2013 10:49:22

Ich hab mir dein Skript jetzt nicht angesehen, aber wenn du das in hübsch und bedienfreundlich gestalten willst, kannst du ja überlegen, ob du dafür Debiandialog oder Debianwhiptail benutzt.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von pangu » 09.07.2013 10:57:43

Danke für die Hinweise. Für diesen Zweck möchte ich versuchen auf extra Pakete zu verzichten, da ich dieses Skript auf verschiedenen Hosts nun anwende. Und um so kleiner meine Abhängigkeit, desto besser. Ich werde mir dennoch die Pakete näher anschauen und vielleicht Einsatz für weitere Projekte finden. Danke dir :THX:
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

uname
Beiträge: 12406
Registriert: 03.06.2008 09:33:02

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von uname » 09.07.2013 13:58:03

Vielleicht kann mir abschließend noch mal jemand erklären wie bei einem Aufruf von

Code: Alles auswählen

/usr/bin/tmux attach || /usr/bin/tmux new
jemals mehr als eine Sitzung existieren kann. Eigentlich unwahrscheinlich bis unmöglich.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von pangu » 09.07.2013 14:09:49

Richtig, das geht gar nicht. Entweder - Oder. Diesen Befehl hatte ich ganz am Anfang verwendet, als es mir egal war und ich nicht zwischen verschiedenen sessions switchen wollte. Daher verwende ich das nicht mehr in meinem finalen geposteten Skript.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

uname
Beiträge: 12406
Registriert: 03.06.2008 09:33:02

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von uname » 09.07.2013 14:29:57

Da ich in Debianscreen- bzw. Debiantmux-Sitzungen immer eine Vielzahl von "Fenstern" nutze sehe ich eigentlich keinen Grund diese noch zu wechseln. Wobei man wenn man diesen Anspruch schon hat wäre es eigentlich viel effektiver screen- bzw. tmux-Sitzungen generell zu schachteln. Meine tmux-Fernwartung nutze ich meist geschachtelt in Verbindung mit screen:
/usr/local/bin/restricted:

Code: Alles auswählen

#!/bin/sh
if [ -z $TMUX ];   then                 
  /usr/bin/tmux attach || /usr/bin/tmux new
else                                                                           
  /bin/echo -n "ssh localhost -l "
  read eingabe; 
  /usr/bin/ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost -l $eingabe;
fi  
Nicht schön aber effektiv. Zudem recht sicher und portabel. Wenn der Aufrufer gleichzeitig einen SSH-Remote-Port-Forwarding-Tunnel öffnet kann ich ganz nett beliebige Rechner administrieren. Unabhängig von jeder Firewall und vor allem auch hinter jedem DSL-Router ;-)

linuxCowboy
Beiträge: 287
Registriert: 05.02.2013 19:47:41

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von linuxCowboy » 10.07.2013 04:38:06

Code: Alles auswählen

/bin/echo -n "ssh localhost -l "
read eingabe; 
echo $eingabe
Das ist ja originell! :)

Nach kurzem nachdenken ging mir auf, du emulierst diesen:

Code: Alles auswählen

read -p "ssh localhost -l "
echo $REPLY
...und nach kurzem nachschlagen fand ich heraus, anno dunnemal Bourne-Shell selig konnte das wohl noch nicht... :cry:

(...aber inzwischen haben wir elektrisch Licht und essen mit Messer und Gabel :lol: )

:wink:

Ernsthaft. Wieso opfert ihr am Altar der Portabilität?

Einerseits sind da diese updates, die es angeblich ständig braucht und ohne die es ja gar nicht geht. Und dann nimmt man 30 Jahre alte Shells!??
-der_linux_cowboy --- Besser werden! ... f*** w$$

uname
Beiträge: 12406
Registriert: 03.06.2008 09:33:02

Re: Automatisch tmux session start/attach nach einem SSH Log

Beitrag von uname » 10.07.2013 08:22:34

Von der Shell-Variablen $REPLY hatte ich zuvor noch nichts gehört. Mit Dash scheint das auch nicht zu gehen ... also nichts mit Portabilität. Aber selbst mein altes Script funktionierte mit Dash nicht. Ich habe das Script geändert und nutze weiter Bash. Danke für den Tipp. Konnte somit eine Zeile einsparen.

Antworten