GästebuchIhr Eintrag in unser Gästebuch KontaktNehmen Sie Kontakt mit den Autoren auf ArchivAlle Unixwerk- Artikel seit 2003
18. Juli 2007

Session-Management mit »screen«

Inhalt

  1. Einleitung
  2. »screen« installieren
  3. Grundlegende Kommandos
  4. Session Management

 

1. Einleitung

»screen« ist ein kleines Programm, das es ermöglicht, mehrere Sitzungen (Sessions) von einem einzigen Terminal laufen zu lassen. Es baut zu jeder Session ein virtuelles Fenster auf und verbindet sie zu einem tty. Die Session kann auch gänzlich vom Terminal getrennt werden (detach).

Im Zeitalter von grafischen Oberflächen ist es nicht mehr so interessant zwischen verschiedenen Sitzungen innerhalb eines Terminals wechseln zu können - das Starten eines zweiten Terminalfensters (xterm, putty, ...) tut es auch. Darum soll es in diesem Artikel daher auch gar nicht gehen. Vielmehr soll ein Session Management mit Hilfe von »screen« aufgebaut werden.

 

2. »screen« installieren

Wer Linux nutzt, wird screen im Allgemeinen bereits vorfinden und es nicht installieren müssen. Falls es doch nicht installiert ist, findet sich ein Paket »screen« sicher auf der CD.

Bei proprietären Unix-Derivaten sieht die Sache anders aus, hier muss screen möglicherweise aus fremden Quellen installiert werden. Bei fehlender root-Berechtigung können Sie screen auch in Ihrem Heimatverzeichnis installieren. Dies soll am Beispiel AIX 5.3 exemplarisch durchgeführt werden:

Unter aixpdslib.seas.ucla.edu/packages/screen.html habe ich mir die entsprechende Version heruntergeladen und in meinem Heimatverzeichnis entpackt:

$ cd
$ uncompress -c screen.4.0.2.tar.Z | tar xf -
$ mv usr/local/* .
$ rmdir usr/local
$ rmdir usr

screen findet sich nun unter ~/bin/screen.

 

3. Grundlegende Kommandos

Eine neue Session lässt sich mit

screen [Kommando]
starten. Für unsere Zwecke interessant ist der Aufbau einer ssh-Verbindung zu einem entfernten Rechner, also etwa

$ screen ssh barney

Eine so aufgebaute verbindung lässt sich mit der Tasten-Kombination <CRTL-A><D> vom Terminal abkoppeln, ohne dass die Shell dies bemerken würde.

Alle zur Zeit aktiven Sessions lassen sich mit dem Schalter »-list« anzeigen:

$ screen -list
There are screens on:
        401566.pts-18.darkstar  (Detached)
        159936.pts-12.darkstar  (Attached)
2 Sockets in /tmp/uscreens/S-armin.

Abgekoppelte Sitzungen werden als (Detached) angezeigt. Bei einer größeren Anzahl abgekoppelter Sessions ist es aber schwierig, die richtige aus der Liste zu finden, da man sich kaum PID und tty gemerkt hat (darkstar ist nicht etwa der Name des Systems, zu dem die ssh-Verbindung aufgebaut wurde, sondern der Rechner, auf dem ich »screen« aufgerufen habe - folglich also immer derselbe...)

Deshalb gibt es die Möglichkeit, der Session einen eigenen Namen zu geben, der dann hinter dem PID auftaucht, also etwa...

$ screen -S barney ssh barney
^AD
[detached]

$ screen -list
There are screens on:
        700572.pts-18.darkstar  (Detached)
        159936.pts-12.darkstar  (Attached)
        921688.barney   (Detached)
3 Sockets in /tmp/uscreens/S-armin.

Nun ist klar, welchen Screen wir gerade in den Hintergund geschickt haben. Mit dem Befehl

$ screen -r barney
wird die Session wieder mit dem Terminal verbunden.

 

4. Session Management

Mit den unter 3. erworbenen Mitteln wollen wir nun ein Session-Management aufbauen. Dazu erstellen wir drei Skripts. Die Beispiel-Skripts sind ksh-Skripts, sie sind aber kompatibel zur bash gehalten, tauschen Sie lediglich #!/bin/ksh gegen #!/bin/bash aus.

a. bin/screenwrapper

#!/bin/ksh
SESSION_ARGS="$@"
SESSION_NAME="$(echo $@ | awk '{print $NF}')"
SESSION_TERM=${TERM:-xterm}

if [ -z "$SESSION_ARGS" ]
then
  $SESSION_CMD

else

  case $SESSION_NAME in
    -*)
    $SESSION_CMD $SESSION_ARGS
    ;;
    ?*)
    exec $screen -T $SESSION_TERM -h 10000 -S $SESSION_NAME $SESSION_CMD $SESSION_ARGS
    ;;
  esac
fi

Dieses Skript baut eine Screen Session auf und übergibt das Kommando an die Session, der Name der Session ergibt sich aus dem Argument, also wenn wir

$ screenwrapper ssh homer

eingeben, sehen wir:

$ screen -list
There is a screen on:
        159936.homer  (Attached)
1 Socket in /tmp/uscreens/S-armin

Für "screenwrapper ssh" setzen wir einen Alias in der Initialisierungsdatei für die Shell (z.B. .login für Bourne-Shell und ksh oder .bash_login für die Bash):

alias s='~/bin/screenwrapper ssh'

so dass wir einfach

$ s homer

eingeben können.

b. bin/lsscreens

Als nächstes brauchen wir ein Skript, das die Ausgabe aller laufenden Sitzungen anzeigt. Dies nennen wir z.B. lsscreens:

#!/bin/ksh
screen=$HOME/bin/screen
screens="$($screen -ls | grep tach | sed -e 's/[        ]/#/g')"

if [ -n "$screens" ]
then
  printf "\n  PID    HOST             STARTED@   ( STATE  )\n"
  for screen in $screens
  do
    pid=$(echo $screen | cut -d . -f1 | cut -d\# -f2)
    stm=$(ps uax | egrep -w "$USER[ ]*$pid" | awk '{print $9}')
    hst=$(echo $screen | cut -d . -f2 | cut -d\# -f1)
    sta=$(echo $screen | cut -d\# -f3)
    printf "%8d %-16s %-10s %s\n" $pid $hst $stm $(echo $sta | sed -e "s/\(Detached\)/^[[32m\1^[[0m/")
  done
  echo
else
  printf "\n No screens in use.\n\n"
fi
Beachten Sie in diesem Skript, dass "^[" ein Zeichen, nämlich <ESC>, ist. Im vi erreichen Sie dies, indem Sie <Ctrl-V><ESC> eingeben. Beachten Sie ferner, dass in dem regulären Ausdruck "/[     ]/" einmal <SPACE> und einmal <TAB> stehen.

Die Ausgabe gibt uns einen schnellen Überblick über alle ssh-Sessions, wann sie gestartet wurden und ob sie aktuell in einem Fenster laufen oder vom Terminal abgekoppelt wurden:

$ lsscreens

  PID    HOST             STARTED@   ( STATE  )
 1110162 akira            10:01:46   (Detached)
  671902 homer            10:02:01   (Attached)
 1052876 barney           11:27:48   (Attached)
  970912 bart             12:53:50   (Detached)
 1048698 lisa             13:27:36   (Detached)
  188568 bart             12:53:50   (Detached)

c. bin/attach

Screens, die sich im Status Detached befinden, können dann mit dem folgenden Skript, das im Wesentlichen screen -r ausführt, wieder mit einem Terminal verbunden werden:

#!/bin/ksh
screen="$HOME/bin/screen"
SCREENARGS='-r'
ARGS=""

while (($#>0))
do
  case $1 in

    -f)
      SCREENARGS='-r -D'
      shift
      ;;

    *)
      HOSTNAME=$1
      ARGS=$1
      shift #must exit here
      ;;

  esac
done

$screen $SCREENARGS $ARGS

So verbinden Sie sich mit

$ attach akira

wieder mit der laufenden Verbindung zu akira. Haben Sie mehrer Sitzungen zum selben Rechner laufen, die sich im Status Detached befinden, würden Sie allerdings folgende Fehlermeldung bekommen:

$ attach bart
There are several suitable screens on:
        970912.bart     (Detached)
        188568.bart     (Detached)
Type "screen [-d] -r [pid.]tty.host" to resume one of them.

In diesem Fall müssen Sie den PID mit übergeben:

$ attach 188568.bart

Eine Verbindung, die in irgendeinem Terminal läuft, sich also im Status Attached befindet, lässt sich zunächst einmal nicht auf ein anderes Terminal bringen, weil sich mit attach bzw. screen -r nur solche Sitzungen an ein Terminal binden lassen, die nicht bereits anderswo verbunden sind. Doch unser Skript hat eine force-Option, die dies dennoch möglich macht:

$ attach -f barney

Nun wird die Session vom anderen Terminal getrennt und zu Ihrem aktuellen Terminal verbunden.