next | next | up | down | Inhalt | Uebungen | Complete | Kommentar

all, section 2.

2.  Terminal

Früher wurde ein Rechner von einem separaten Terminal aus benutzt, das über eine serielle Schnittstelle (wenigstens 3 Drähte für full-duplex Betrieb) angeschlossen war. Heute ist am PC oder an der Workstation der Bildschirminhalt meistens direkt im Hauptspeicher und wir verwenden ein Programm zur Terminal-Emulation, aber es gibt nach wie vor serielle Anschlüsse für Modems oder an Terminal-Servern:

Kommandos ruft man zunächst im Dialog auf. Dazu hat man entweder ein Terminal oder ein Fenster mit einer Terminal-Emulation. Letztlich holt das Betriebssystem Zeichen von der Tastatur ab und schreibt Zeichen auf den Bildschirm. Eine Shell, das heißt, ein Kommando-Interpreter, -- z.B. ksh(1), bash(1), sh(1), csh(1) oder ... -- liest Zeilen und führt die darin beschriebenen Kommandos meistens als eigene Prozesse aus. Siehe auch tty(4).

Eine primitive Shell könnte wie folgt aussehen:

 1      #include <stdio.h>
 2      
 3      int read_line(char * buf)
 4      {       char * help = buf;
 5              printf("$ ");
 6              while ( ( ( *help = getchar() ) != EOF ) && 
 7                      ( *help != '\n'                   )    
 8                    )         help ++;
 9      
10              *help = (char )'\0';
11              return ( help == buf ? 0 : 1 );
12      }
13      
14      int main(void)  {
15      char cmd[1024];
16              while ( read_line(cmd) )        {
17                      switch ( fork () )      {
18                              case    0:      execl(cmd, cmd,
19                                                 (char *) 0);         
20                                              exit(0);
21                              case    -1:     perror("fork failed.");
22                                              exit(-1);
23                              default:        wait(NULL);
24                      }
25              }
26              exit(0);
27      }

artemis Src 105 simple_shell
$ /bin/ls
hello           hello.c         simple_shell    simple_shell.c
$ /bin/date
Mon Apr  7 18:17:32 MET DST 1997
$ who
$ /bin/who
bischof  console Apr  7 15:17
bischof  ttyp1   Apr  7 17:14
bischof  ttyp3   Apr  7 17:44

Normalerweise kann man voraustippen und auch eine Zeile noch korrigieren, bevor sie ein Prozeß sieht. Bestimmte Tasten haben dabei meistens eine besondere Bedeutung, die über das Kommando stty gesteuert werden kann. Um das zu verstehen, muß man sich das Modell des Terminal-Treibers klarmachen:

RETURN
schließt einen Block in der raw queue ab und erscheint dem Prozeß als Zeilentrenner. Der Block wird in die cooked queue übertragen und kann von dort vom Prozeß gelesen werden. Siehe auch tty(4). Ein Prozeß erhält pro read-Systemaufruf(2) maximal einen Block aus der cooked queue.
$ sleep 10; dd bs=1024 count=1
hp
date
hp
0+1 records in
0+1 records out
$ date
Thu Mar 20 18:36:28 MET 1997
Siehe auch sleep(1), dd(1) und date(1). Vorsicht: aus einer Datei oder einer Pipeline liest der read-Systemaufruf(2) so viel wie möglich, deshalb kann man in einem Shell-Skript praktisch kaum die Standard-Eingabe zwischen Kommandos aufteilen:
$ { echo hpb
>   echo date
> } | dd bs=1024 count=1
hpb
date
0+1 records in
0+1 records out

CONTROL
gibt 32 Zeichen (ab @) Sonderbedeutung. Muß (wie SHIFT) gleichzeitig gedrückt werden.
    0     8    16    24    32     40   48   56   64   72   80    88   96    104   112   120
0   nul   bs   dle   can   leer   (    0    8    @    H    P     X    `     h     p     x
1   soh   ht   dc1   em    !      )    1    9    AQ   Y    a     i    q     y
2   stx   nl   dc2   sub   "      *    2    B    :    J    R     Z    b     j     r     z
3   etx   vt   dc3   esc   #      +    3    ;    C    K    S     [    c     k     s     {
4   eot   np   dc4   fs    $      ,    4    <    D    L    T     \    d     l     t     |
5   enq   cr   nak   gs    %      -    5    =    E    M    U     ]    e     m     u     }
6   ack   so   syn   rs    &      .    6    >    F    N    V     ^    f     n     v     ~
7   bel   si   etb   us    '      /    7    ?    G    O    W     _    g     o     w     del
------------------------------------------------------------------------------------------------
    1     2    3     4     ...                   i    ii   iii   iv   ...

Siehe auch ascii(7).

ctl-d
Abschluß einer Eingabe: Vorher kann man die Eingabe ändern, damit geht die Eingabe an das/ein Programm. ctl-d erscheint nicht beim Programm. Nach Konvention gilt eine Eingabe der Länge Null als Eingabe-Ende (also schließt ctl-d am Zeilenende typischerweise die Eingabe ab).
ctl-s
Anhalten der Ausgabe. Weiter geht's mit ctl-q oder auch mit einer beliebigen Taste. ctl-s und ctl-q erscheinen nicht beim Programm.
\
nimmt (manchem) nächstem Zeichen bei Erzeugen der Eingabe die Sonderbedeutung.
erase-Taste
löscht das vorhergehende Zeichen in der gleichen Eingabe. Kann eingestellt werden:

$ stty -crterase -crtbs		# am NeXT
$ stty erase X
$ dudXXate
Thu Apr 19 05:46:07 MEZ 1990

kill-Taste
löscht alle vorhergehenden Zeichen in der gleichen Eingabe. Kann eingestellt werden:

$ stty -crtkill			# am NeXT
$ stty kill Y
$ dateY
date
Thu Apr 19 05:46:27 MEZ 1990

interrupt-Taste
schickt interrupt-Signal an alle Programme, die dieses Terminal ``kontrolliert''. Oft brechen Programme dadurch ab. Kann eingestellt werden:

$ stty intr A
$ dd
A0+0 records in
0+0 records out
$ dudeAdate
Mon Apr  7 18:23:50 MET DST 1997

quit-Taste
schickt quit-Signal an alle Programme, die dieses Terminal ``kontrolliert''. Häufig brechen Programme dadurch ab. Meistens erhält man einen Speicherauszug core. Kann eingestellt werden:

$ stty quit B
$ dudeBdate
Mon Apr  7 18:24:22 MET DST 1997

stop-Taste
(Berkeley) normalerweise ctl-z. Hält Programm an. Weiter mit fg oder bg.

back | next | up | down | Inhalt | Uebungen | Complete | Kommentar


Created by unroff & hp-tools. © by Hans-Peter Bischof. All Rights Reserved (1997).

Last modified 03/July/97