Zum Inhalt springen

Unix-Shell

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 16. März 2005 um 12:24 Uhr durch 217.184.41.175 (Diskussion) (Weitere Shells). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Das Betriebssystem Unix erlaubt verschiedene Kommandozeileninterpreter, die unter Unix Shells genannt werden. Als Kommandozeileninterpreter ist eine solche Shell daher ein wichtiges Bindeglied zwischen dem Anwender und Unix (welches unter Unix nur langsam und nur teilweise von graphischen Benutzeroberflächen abgelöst wird). Technisch ist eine Shell ein ganz normales Programm ohne besondere Privilegien. Unter Unix kann ein Anwender (oder der Systemverwalter) daher unter verschiedenen Shells wählen. Manche Unix-Versionen stellen dazu ein chsh (Change Shell) Kommando zur Verfügung. Unix-Shells implementieren eine Skriptsprache und können so zur Programmierung und zur Automatisierung von Aufgaben eingesetzt werden.

Allgemeines

Nach dem Einloggen ist die Shell das Programm, das vom login-Prozess gestartet wird und Kommandos entgegennimmt. Die Kommandos werden dann ausgeführt. Die Shell enthält eingebaute Kommandos wie 'cd'. Andere Kommandos werden im Dateisystem gesucht und dann gestartet.

Jede gängige Unix-Shell enthält die folgenden Möglichkeiten:

  • Starten von Kommandos
  • Dateinamen-Wildcards (globs) als Kommandoargumente
  • Ausführung von Kommandos in Dateien, so genannte Skripte.
  • Bedingungen (if, case) und Schleifen (while, for)
  • Eingebaute Kommandos (cd, read)
  • interne Variablen
  • Manipulation der Umgebungsvariablen für die neuen Prozesse
  • Ein-/Ausgabeumlenkung
  • Starten mehrerer Prozesse, Verkettung über Pipes
  • Starten von Prozessen im Hintergrund
  • Definition des Eingabe-Aufforderungsstrings (Prompt)
  • Definition der Suchreihenfolge externer Kommandos

Moderne Shells können darüber hinaus

  • Editierung der Kommandozeile (command line editing)
  • Wiederholung und Editieren früherer Kommandos (command history)
  • Stoppen und erneutes Starten von Prozessen (Job Control)
  • Verschieben von Prozessen aus Vorder- in den Hintergrund und umgekehrt (Job Control)
  • Eingebautes Kommando zur Durchführung von Berechnungen (expr)
  • Eingebautes Kommando zum Testen von Dateieigenschaften (test)

Hinsichtlich dem Abbruch eines Kommandos machen sich die Shells die Eigenschaften des zugrundeliegenden Terminal-Gerätetreibers zunutze. Die Shell wartet normalerweise auf das Ende eines Kommandos. CTRL-C bewirkt unter Unix einen Kommandoabbruch, den der Gerätetreiber auslöst.

Unix-Werkzeuge

Unix-Shells machen sich die Eigenschaften des zugrundeliegenden Betriebssystems zunutze. Sie implementieren nur das Nötigste. Externe Unix-Kommandos ergänzen über die leistungsfähige Ein-/Ausgabe und Pipeimplementierung alles weitere. Unix enthält z.B. spezielle Kommandos für die Textdateimanipulation, wie Suchen, Editieren, Ersetzen, Worte zählen, Zeichenübersetzung, Abschneiden von Zeilen usw.

Skripte

Der Urvater der heutigen Shells, die Bourne Shell, enthält nicht einmal eingebaute Kommandos für die Dateieigenschaften und für einfache Berechnungen. Auch die Ausgabe einer Variablen ist nicht möglich. Damit wäre nicht einmal ein einfacher Zähler zu implementieren.

Über die externen Kommandos expr, test und echo wird dies möglich. Ein Skript, das von 1 bis 100 zählt, kann wie folgt realisiert werden:

#!/bin/sh                
I=1                      # Variable I auf 1 setzen
while test $I -le 100    # While-Schleife, externes Kommando test I<100
do 
    echo $I              # externes Kommando echo, gibt I aus
    I=`expr $I + 1`      # externes Kommando expr, Ausgabe von expr nach I
done

Bei moderneren Shells sind die Kommandos expr, test und echo intern, da sie sehr häufig benötigt werden und die Shell auch nicht wie bei sehr frühen Systemen klein gehalten werden muss.

Der Text eines Skripts kann in eine Datei geschrieben und mit dem Kommando chmod +x ausführbar gemacht werden. Es verhält sich dann wie jedes andere Kommando, allerdings ist der Start von privilegierten Skripts oft eingeschränkt.

Systemstart

Beim Hochfahren des Unix-Systems werden auch Shell-Skripte eingesetzt. Die BSD-Varianten starten dazu einfach das Skript /etc/rc, das dann alle Systeminitialisierungen wie Dateisystemüberprüfung, Hintergrundprozesse usw. durchführt. System V Unix-Varianten verwenden sysinit, das aus mehreren Shell-Skripten besteht.

Kommandos, die eigentlich Shellskripte sind

Skripte sind von normalen Programmen in der Anwendung nicht zu unterscheiden. Manche Unix-Versionen liefern sogar einige Kommandos mit, die als Shellskripte realisiert sind. Insbesondere Kommandos wie man (Online-Manual) und cc (Aufruf von C-Compiler, Assembler und Linker) sind bei vielen Unix-Varianten Shell-Skripte.

Die frühen Shells

Die Bourne Shell – sh

Der Ahne aller heutigen Shells ist die Bourne Shell (sh) von Stephen Bourne, die 1977/1978 zusammen mit Unix V7 erschien. Sie ist die ursprünglichste und auf allen Systemen vorhandene Unix-Shell. Diese Shell hat bereits alle wesentlichen Eigenschaften wie Ein-/Ausgabeumlenkung, Pipes, Hintergrundprozesse, Kontrollstrukturen. Bezüglich der Kommandozeileneditierung verlässt sich die Shell auf den Terminaltreiber, der nur das Löschen der ganzen Zeile (CTRL-U) und des letzten Zeichens (DEL) erlaubt.

Die Bourne Shell ist Grundlage der meisten modernen Unix-Shells, die im Wesentlichen eine Erweiterung dieser Shell darstellen. Skripte für die Bourne-Shell sind ohne Änderung auch auf diesen Shells lauffähig. Die Skriptfähigkeiten der Bourne-Shell sind richtungsweisend. sh bleibt die beliebteste Skriptsprache für Unix. Das Programm liegt generell als /bin/sh vor.

Seit dem Erscheinen von der csh mit 4.1BSD wird die Bourne Shell meist nurmehr für Skripte, insbesondere solche, die Aufgaben des Systems erledigen, verwendet, weil sie bei der interaktiven Bedienung keine Editiermöglichkeiten und keine Prozesskontrolle vorsieht. Hierfür eignet sich die Weiterentwicklung bash wesentlich besser, welche der Standard-Kommandozeileninterpreter unter GNU/Linux und zur Bourne Shell kompatibel ist.

Beispielprogramm

Obwohl der Funktionsumfang der Bourne Shell verhältnismäßig gering ist, können mit Hilfe der Standard-Unix-Programme alle für Kommandozeileninterpreter typische Aufgaben übernommen werden. Die Syntax der Bourne Shell ist etwas eigenwillig. Beispiel:

#!/bin/sh

tageszeit=`date +%H`
if [ $tageszeit -lt 10 ]; then
  echo "Guten Morgen."
else
  echo "Guten Tag."
fi

In der Bourne Shell ist kein Mechanismus implementiert, der das Kriterium z. B. für eine Fallunterscheidung auswerten könnte. Anstatt dessen muß dies von einem externen Programm erledigt werden. Hier wird das Programm /bin/[ mit den Argumenten 8 (wenn es denn 8 Uhr morgens ist), -lt (lower than - kleiner als), 10 und ] aufgerufen, wobei letzteres nur zur Wahrung der Symmetrie angegeben wird.

Die C-Shell – csh

Bill Joy entwickelte in Berkeley für die zweite BSD-Distribution (2BSD) von 1979 eine Shell, die sich mehr an der C-Syntax orientierte, die C-Shell (csh). Diese Shell erlaubt bereits eine Kommandozeileneditierung, allerdings nicht interaktiv, sondern über eine spezielle Syntax. Sie ermöglicht auch das Wiederholen (und Editieren) alter Kommandos. Außerdem wird erstmals die Job-Control-Möglichkeit implementiert: Über CTRL-Z lässt sich ein Kommando stoppen und später über die internen Kommandos fg (Foreground=Vordergrund) bzw. bg (Background=Hintergrund) fortsetzen.

Die C-Shell besitzt viele bekannte Features der bash, wie z.B. Aliase oder eine History. Heutzutage wird die C Shell nur noch wenig benutzt; sie wurde von anderen Shells wie der tcsh, der ksh (Korn Shell), der bash (Bourne again Shell) oder der zsh abgelöst.

Die Skriptfähigkeiten der C-Shell sind durch diverse Unzulänglichkeiten etwas eingeschränkt, z. B. kann die Fehlerausgabe nicht unabhängig von der Standardausgabe umgelenkt werden. Ein Anwender, der für die interaktive Eingabe die C-Shell verwendet, kann durch ein vorangestelltes #!/bin/sh in seinen Skripten das Betriebssystem veranlassen, die Standard-Shell (diese ist mindestens kompatibel zur Bourne Shell, auf modernen Systemen auch meist POSIX-konform) zu verwenden. Dies ist auch für alle anderen Shells möglich.

Weiterentwicklungen

Auf jedem Unix-System befindet sich eine zu der Bourne Shell kompatible Shell in /bin/sh. Die Verfügbarkeit weiterer Shells hängt von der jeweiligen Unix-Variante ab, eine C-Shell Version findet sich oft in /bin/csh. Wegen der unterschiedlichen Syntax unterscheidet man Bourne Shell und C-Shell Abkömmlinge. Da praktisch alle moderenen Shells in der Programmiersprache C geschrieben sind, lassen sich fehlende Shells leicht nachrüsten. Auch auf fremden Betriebssystemen kann man oft eine Unix-Shell, zumindest als Fremdsoftware, finden.

Die Job Control Shell – jsh

Die Job Control Shell ist eine Bourne Shell, die um Job-Control-Eigenschaften (wie sie mit der C-Shell bekannt wurden) erweitert ist. Häufig handelt es sich sogar um das selbe Programm, welches die zusätzlichen Eigenschaften (z.B. die Kommandos bg, fg, jobs, kill stop, suspend, wait) nur aktiviert, wenn es unter dem namen jsh statt sh aufgerufen wird.

Die Korn Shell – ksh

David Korn entwickelte für Unix System V von AT&T die Korn Shell (ksh). Diese orientiert sich an der Bourne Shell, übernimmt aber auch die Neuerungen der C-Shell wie Job-Control, eine weiter verbesserte Kommandozeileneditierung. Diese Shell (ksh88) ist Grundlage des POSIX-Standards. Die Korn-Shell war als Teil von Unix-System V lange Zeit nur kommerziell erhältlich. Seit dem 1. März 2000 ist der Quelltext von ksh93 frei verfügbar. Es existiert eine Version von 1988 (ksh88) und eine neuere von 1993 (ksh93). Viele kommerzielle Unix-Systeme verwenden die ksh als Standard-Shell (/bin/sh).

Die dtksh (Desktop Korn Shell) stellt eine Korn Shell mit zusätzlichen Kommandos für die Programmierung von Benutzeroberflächen unter X11/Motif dar.

Literatur

  • Arnold Robbins, Bill Rosenblatt: Learning the Korn Shell, 2nd Edition O'Reilly 2002, ISBN 0596001959

Die Public Domain Korn Shell – pdksh

Die Public Domain Korn Shell (pdksh) ist eine freie und nicht vollständig kompatible Kopie der AT&T Korn Shell. Viele Funktionen von ksh88 und wenige von ksh93 sind in ihr enthalten. Das OpenBSD-Projekt verwendet die pdksh als Standard-Shell (/bin/sh).

Die Bourne Again Shell – bash

bash steht für Bourne again shell. Diese Unix-Shell ist Teil des GNU-Projekts. Ihr Name ist ein absichtlich zweideutiges Wortspiel und kann sowohl als "Wiedergeborene (born again) Shell" als auch als "Wieder einmal (eine) Bourne Shell" verstanden werden. Geschrieben wurde die Bash größtenteils von Brian Fox und Chet Ramey.

Bash ist eine Bourne Shell mit vielen Erweiterungen. Die Bourne Again Shell ist POSIX-konform und enthält viele Funktionen der Korn Shell und der C-Shell. Sie ist die Standard-Shell (/bin/sh) auf vielen Linux-Systemen.

Die Bash ist voll kompatibel zur originalen Bourne Shell (sh), ist jedoch im Funktionsumfang erheblich erweitert. Vor allem beherrscht sie einen Großteil der Fähigkeiten der ksh, und sie versteht auch Teile der Syntax der csh wie zum Beispiel die Command-History, den Directory-Stack, die $RANDOM-Variable und die POSIX-Form der Command-Substitition '$(...)'. Daneben sind auch eine ganze Reihe eigene Erweiterungen implementiert.

Die Bash ist die Standard-Shell unter Linux und wurde auf fast alle Unix-Systeme portiert. Auch für Windows existiert ein Port in der Cygwin-Umgebung.

Literatur

  • Cameron Newham, Bill Rosenblatt: Learning the Bash Shell, 2nd Edition O'Reilly & Associates, Inc., 1998, ISBN 1565923472

Die TENEX-C-Shell – tcsh

Die TENEX-C-Shell (tcsh) stellt eine Erweiterung der C-Shell (csh) von Christos Zoulas dar. Sie enthält Verbesserungen der Kommandozeileneditierung und andere Erweiterungen wie einer (programmierbaren) Dateinamen-Vervollständigung, der Möglichkeit des Editieren von Dateien direkt in der Kommandozeile, und einigen anderen Dingen. Sie ist aber sonst vollständig kompatibel zur C-Shell.

Das 't' in tcsh stammt aus dem 'T' in TENEX ab, einem Betriebssystem, von dem sich der Autor der tcsh hat inspirieren lassen. Die tcsh ersetzt die csh auf vielen BSD-Systemen.

Literatur

Die Z-Shell – zsh

Die Z-Shell (zsh) ist eine moderne Shell mit sehr vielen Möglichkeiten. Sie ähnelt sehr der Korn Shell und übernimmt auch Funktionen der Bourne Again Shell und der TENEX-C-Shell. Sie geht aber in vieler Hinsicht eigene Wege und gilt als eine der leistungsfähigsten Unix-Shells. Sie kann als Loginshell, als interaktive Shell und als Interpreter für Shellscripte verwendet werden.

Die Zsh kann man als eine Zusammenstellung aller Verbesserungen und Features aus der bash, der csh und der tcsh betrachten. Zu einigen ihrer Features zählen:

  • Eine frei programmierbare TAB-Completion
  • Die Möglichkeit die History aus anderen - gleichzeitig laufenden - Shells zu nutzen
  • Rechtschreibüberprüfung
  • Nahezu vollständige Kompatibilität zur bash, ksh und tcsh
  • Starke Veränderbarkeit des Prompts durch Themes, u.a. die Möglichkeit den Prompt auf die rechte Seite des Terminals zu setzen
  • Erweiterte Globbing-Funktionalitäten

Die Almquist Shell - ash

Die Almquist Shell (ash) von Kenneth Almquist ist eine kleine und schnelle Neuimplementierung der Bourne Shell. Sie orientiert sich am POSIX-Standard und eignet sich sehr gut zur Ausfuehrung von Skripten. Zudem verzichtet sie auf viele Faehigkeiten wie Job Control, die fuer interaktive Benutzung hilfreich sind. Das FreeBSD- und NetBSD-Projekt verwenden eine weiterentwickelte Versionen der ash als Standard-Shell (/bin/sh).

Weitere Shells

Neben einer Neuimplementierung der letzten Thompson-Shell (osh = old shell), die unter Unix vor Einführung der Bourne-Shell in Gebrauch war, existiert eine Unix-Implementierung (Byron Rakitzis) des im Vergleich zur Bourne-Shell syntaktisch klareren Plan 9-Kommandointerpreters rc (run command) von Tom Duff, sowie die an die Syntax der rc anschließende, semantisch manipulierbare bzw. erweiterbare es (extensible shell) von Paul Haahr und Byron Rakitzis, in die Ideen der funktionalen Programmierung einflossen. Eine Shell, bei der der interaktive Aspekt zunächst bewusst zu Gunsten der Shell-Programmierung vernachlässigt wird, ist die Scheme-Shell (scsh) von Olin Shivers, mit der für die Shell-Programmierung eine genuine Programmiersprache (Scheme) zur Verfügung steht. Eine syntaktisch an der Programmiersprache Lisp orientierte Shell ist esh (easy shell) von Ivan Tkatchev.

Kompatibilität & Portabilität

Je nach Abstammung der Shell sind für sie geschriebene Scripte nicht oder nur bedingt kompatibel zu anderen Shells. Zum Beispiel lassen sich Bourne-Shell-Skripte nicht unter der C-Shell ausführen, aber es besteht eine gute Chance, das ein solches Skript unter einer Korn-Shell oder Job-Control-Shell läuft.

Neben diesen offensichtlichen Problem besteht aber auch das Problem, dass unterschiedliche Implementierungen der gleichen Shell existieren und dass Shells unter Beibehaltung ihres Names im Laufe der Zeit auch weiterentwickelt wurden und werden. Die gleichen (gleich genannten) Shells auf unterschiedlichen Unix-Varianten weisen unterschiedliche Entwicklungsstände, und somit sowohl unterschiedliche Eigenschaften als auch Fehler auf

Hinzu kommt, dass Shell-Skripte, wie bereits beschrieben, viele normale Unix-Kommandos aufrufen. Auch diese unterscheiden sich in ihrem Verhalten zum Teil von Unix zu Unix. Dadurch kann sich das Verhalten eines Shell-Scripts ebenfalls ändern, wenn es auf einem anderen Unix ausgeführt wird.

Eine gängige Strategie zum Schreiben von portablen Shell-Skripten ist es, sich nur auf den kleinsten gemeinsamen Nenner zu verlassen. Dies bedeutet in der Regel, dass man die Bourne-Shell verwendet und damit auf die bequemen Erweiterungen, wie sie zum Beispiel in der Korn-Shell oder bash zu finden sind, bewusst verzichtet. Je nachdem, wie groß die Bandbreite der abzudeckenden Systeme ist, verzichtet man auch auf die Benutzung neuerer, in POSIX standardisierter, Bourne-Shell Features.

Literatur

  • Helmut Herold: Linux-Unix-Shells, Bourne-Shell, Korn-Shell, C-Shell, bash, tcsh ISBN 3827315115
  • Alexander Mayer: Shell-Programmierung in Unix ISBN 3932311787