Statt die Fenster einer Entwicklungsumgebung manuell zurechtzuzupfen, kann der Terminal-Multiplexer tmux sie aus Konfigurationsdateien restaurieren.
Wer keine Entwicklungsumgebung wie Eclipse zum Programmieren nutzt, sondern
viel auf der Kommandozeile eines Terminalfensters tippt, dem
ist sicher screen
nicht fremd, eine uralte und in Insiderkreisen
wohlbekannte Terminal-Utility. Sie stellt unter anderem
sicher, dass man eine wegen
eines Netzwerkproblems abgebrochene ssh-Session später genau dort problemlos
fortsetzen kann wo man aufgehört hat zu tippen.
Dabei stellt screen
sich zwischen Anwender und
im Terminal ablaufenden Applikationen und gaukelt letzteren deswegen
immer noch aufmerksame User vor, auch wenn diese schon längst ins
Wochenende abgezischt sind.
In den vergangenen zwanzig Jahren ist nun die Unix-Welt nicht stehen
geblieben und das Projekt tmux
hat sich vor einiger Zeit
angeschickt, screen
zu
verbessern und abzulösen. Wie screen
bietet tmux
dem User
verschiedene Sessions, die wiederum aus "Windows" bestehen, was im
Screen-Jargon keine Desktop-Fenster, sondern im gleichen Terminalfenster
umschaltbare Textoberflächen sind. Mit Tastatur-Shortcuts unterteilt
tmux
diese Fenster bei Bedarf noch weiter in vertikal oder horizontal
angeordnete "Panes", die alle gleichzeitig sichtbar sind (Abbildung 1).
Abbildung 1: Zwei tmux-Kommandos teilen das Window erst in zwei horizontale Panes, und die rechte Pane anschließend in zwei vertikale. |
Ein automatisch gestarteter tmux
-Server behält dabei den Überblick
über alle aktiven Sessions und der User kann diese von der Kommandozeile aus
fernsteuern. Mittels tmux
-Kommandos lassen sich so neue Sessions
anlegen oder zerstören, Fenster hinzufügen oder löschen, und Panes
ein- und ausbauen, vergrößern oder verkleinern.
So bietet es sich an, Entwicklungsumgebungen mit mehreren
Windows und Panes als Konfiguration im Source-Code-Repository abzuspeichern
und bei Bedarf mit einem einzigen Kommando abzurufen und anzuzeigen.
Tmux kann in den
Panes auch Applikationen wie den Lieblingseditor starten, der gleich
eine Projektdatei lädt. Eine andere Pane startet vielleicht schon mal
die Testsuite, und eine dritte zeigt mit tail
die letzten
Zeilen einer Logdatei an.
Tmux läuft auf allen gängigen Plattformen, wer also mal auf einem Linux Desktop und unterwegs auf einem Macbook arbeitet, findet in beiden Umgebungen die gleichen Windows und Panes vor.
Tmux kommt von Haus aus mit völlig unmöglichen Tastaturkombinationen daher. Um in einer Tmux-Session nicht die laufende Applikation wie den Editor anzusteuern, sondern den zwischengeschalteten Terminal-Multiplexer, tippt der User den sogenannten Prefix. In einer jungfräulich belassenen Tmux-Installation ist dafür Ctrl-B eingestellt, aber das verursacht nicht nur Sehnenscheidentzündungen beim Tippen sondern ist auch ein gängiges aber damit geblocktes vi-Kommando.
Glücklicherweise erlaubt es Tmux, alles umstellen, und so stückelt jeder
Nutzer im Vollbesitz seiner geistigen Kräfte
sofort nach der Installation seine eigene .tmux.conf
-Datei
zusammen. Meine eigene ist auf [4] und besteht letztendlich nur auf
allgemeinen Empfehlungen, wie den Prefix auf Ctrl-A zu stellen (genau
wie in screen
) und den Rest auf vim
-ähnliche Kombinationen
(h=links j=abwärts k=aufwärts l=rechts). So braucht man zum wechseln
zwischen den Panes keine Emacs-ähnlichen Textkommandos anzugeben, sondern
springt mit Prefix-Ctrl-h zum Beispiel in die Pane linker Hand.
Das Anpassen der Shortcuts
bringt natürlich gewissen Nachteile mit sich, wie zum
Beispiel, dass jeder einen anderen tmux-Dialekt versteht und in fremden
Umgebungen hilflos zappelt wie eine Schildkröte auf dem Rücken.
Jederzeit versteht Tmux aber ausgeschriebene Kommandos, die Tmux
auf die Tastenkombination Prefix-: (Prefix gefolgt von einem Doppelpunkt)
auf der Statuszeile entgegennimmt. Die
gleichen Kommandos akzeptiert tmux
auf der Kommandozeile, so dass
zusammengezimmerte Skripts zum Aufsetzen einer Fenstergruppe global
gültig sind. So setzt das Perl-Skript in Listing 1 in Zeile 19 den
Befehl "tmux kill-session" mit dem Namen der Session ("log4perl") ab,
falls der User es mit der Option -k
aufgerufen hat. Der Befehl nimmt
Verbindung vom Tmux-Server auf (falls dieser läuft), fragt nach der
Session und lässt sie zusammenfalten.
01 #!/usr/local/bin/perl -w 02 use strict; 03 use Sysadm::Install qw( tap cd sysrun ); 04 use Log::Log4perl qw(:easy); 05 use Getopt::Std; 06 sub tmux; # declare as function 07 08 my($home) = glob "~"; 09 my $session = "log4perl"; 10 11 getopts "vk", \my %opts; 12 13 my $loglevel = $INFO; 14 $loglevel = $DEBUG if $opts{ v }; 15 16 Log::Log4perl->easy_init( $loglevel ); 17 18 if( $opts{ k } ) { 19 tmux "kill-session", "-t", $session; 20 exit 0; 21 } 22 23 tmux "source", "$home/.tmux.conf"; 24 25 if( 0 == system "tmux", "has-session", 26 "-t", $session ) { 27 DEBUG "Session $session already exists"; 28 } else { 29 DEBUG "Creating session $session"; 30 tmux "new-session", "-s", $session, 31 "-d"; 32 tmux "split-window", "-h"; 33 tmux "split-window", "-v"; 34 tmux "send-keys", "-t", "$session:0.0", 35 "vim -p `find . -name '*.pm' | head -2`", 36 "C-m"; 37 tmux "send-keys", "-t", "$session:0.1", 38 "perl Makefile.PL; make test", "C-m"; 39 tmux "send-keys", "-t", "$session:0.2", 40 "vim t/*.t", "C-m"; 41 } 42 43 tmux "attach", "-t", $session; 44 45 ########################################### 46 sub tmux { 47 ########################################### 48 my( $stdout, $stderr, $rc ) = 49 tap "tmux", @_; 50 51 return $rc; 52 }
Die Option -v
(verbose) veranlasst Listing 1 dazu, die
Log4perl-Konfiguration auf den Loglevel $DEBUG zu stellen, während es
sonst mit $INFO
weit weniger geschwätzig ist. Damit das Skript nicht jedes
Tmux-Kommando ausschreiben muss, ruft die Funktion tmux()
ab Zeile
46 das Kommando tmux
über die Shell auf. Die Funktion tap()
aus
dem CPAN-Modul Sysadm::Install leitet dies in die Wege. Damit die Klammern
bei den Aufrufen von tmux()
wegfallen können, deklariert
Zeile 6 sie als Funktion im aktuellen Namespace.
Zeile 23 liest mit source
die Konfigurationsdatei .tmux.conf
im
Home-Verzeichnis des Users ein. Eigentlich sollte tmux
dies automatisch
tun, doch die beim Testen verwendete Version tat dies nicht -- wohl ein Bug.
Des weiteren prüft es in Zeile 25 mit dem Befehl "tmux has-session" ob die aufzusetzende Tmux-Session vielleicht schon läuft, und fällt durch bis zum Befehl "attach" in Zeile 43, falls die Session schon steht, um sich nur noch damit zu verbinden.
Falls die Session noch nicht bekannt ist, erzeugt der Befehl new-session
in Zeile 30 eine neue mit dem Namen "log4perl".
Der Name der
Session verweist auf das Log4perl-Projekt, in dessen Git-Repository
sie als Entwicklungsumgebung dient.
Der Parameter -d
("detach")
am Schluss des Tmux-Kommandos
bestimmt, dass das Skript nicht sofort in die Session
hineinspringt und die GUI darstellt, sondern brav bis zum Befehl attach
in Zeile 43 Ende rattert, bevor der User etwas sieht.
Die split-window
-Anweisungen ab Zeile 32 mit den Optionen -h
(horizontal)
und -v
(vertical) erzeugen zusätzliche Panes im Window, indem sie es
einmal horizontal und einmal vertikal teilen. Windows und Panes numeriert Tmux
von 0 her durch (aber Vorsicht, eine oft genutzte
Konfigurationsoption stellt dies auf 1 um).
Um also bei einem jungfräulichen Tmux die zweite Pane im ersten Window
der Session "log4perl" zu adressieren, notiert
Zeile 37 log4perl:0.1
und gibt mit send-keys
das Kommando
zum Ablaufen der Testsuite mit einem abschließenden C-m
(Return) an.
Genauso könnte man aber mit vagrant ssh
schon mal in eine Vagrant-VM
wechseln, wie im letzten Snapshot besprochen, um sicher zu stellen, dass
die Testsuite auch im staubfreien Reinraum abläuft.
Zeile 35 findet die ersten zwei .pm-Dateien in der Hierarchie des
gewählten Perl-Projekts und übergibt ihre Namen dem Editor vim
mit
der Option -p, der sie in sogenannten Tabs in der Pane auf der linke
Seite anzeigt (Abbildung 2).
Abbildung 2: Ein Tmux-Window mit Editor, Test Suite, und Testdatei. |
Tmux ist in den Repositories gängiger Repositories vorhanden, unter Ubuntu führt
sudo apt-get install tmux
direkt zum Ziel. Allerdings hat sich das Projekt in letzter Zeit stetig
weiter entwickelt und man sollte mindestens Version 1.7, wenn nicht gar
1.8 verwenden, um auch nur in den Genuss aller in diesem Artikel vorgestellten
Features zu kommen. Tüftler können
den Source-Code direkt von [2] herunterladen und
kompilieren. Als Abhängigkeiten sind nur libevent
(mindestens 1.4.14 oder 2.0) und ncurses
notwendig. Das Skript
auf [5] erledigt die Kompilationsschritte automatisch.
Im Tmux-Buch [3] gibt ein erfahrener Anwender nützlicher Tipps zum Bewältigen gängiger Aufgaben mit Tmux, von Entwicklungsumgebungen bis zum Pair-Programming, bei dem zwei Entwickler örtlich getrennt gleichzeitig in der gleiche Session in unterschiedlichen Panes tippen. Und das Beste: Ins Source-Control-System eingecheckt kann auch der nächste Entwickler sofort die Tool-Umgebung aufsetzen und verzögerungsfrei produktiv mitarbeiten.
Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2013/06/Perl
Projektseite des Tmux-Projektes: http://tmux.sourceforge.net/
Hogan, Brian: tmux: Productive Mouse-Free Development, Pragmatic Bookshelf, 2012
Michael Schillis Tmux-Konfiguration: http://github.com/mschilli/dotfiles/.tmux.conf
Skript zum statischen Kompilieren von Tmux auf schwierigen Plattformen: https://gist.github.com/ryin/3106801
CPAN-Modul Debug::Fork::Tmux Debugger-Fenster mit Tmux