Druckversion | ||||||||||||||||||||||||||||||||
Was ist die Tenex-C-Shell?Verbreitung erfuhr die C-Shell vor allem durch ihre enge Bündelung mit den BSD-Unix-Systemen. In ihre Entwicklung flossen all die nützlichen Dinge der Bourne Shell ein, garniert mit einigen neuen Eigenschaften. Herausragend war sicher die Verwendung einer History. Die C-Shell erbte von der Bourne Shell zwar das Konzept, die Realisierung orientierte sich jedoch an der Programmiersprache C. Daher auch ihr Name. Im interaktiven Umgang ist von der Nähe zur Programmiersprache C nichts zu merken. Erst der Shellprogrammierer wird mit der Syntax konfrontiert, die vor allem dem Programmierer entgegen kommen wird. Im Vergleich zur Bourne Shell agiert die C-Shell recht schwerfällig. Auf heutigen Megahertz-Boliden mag das kein Kriterium Für oder Wider einer Shell zu sein, aber in den Anfängen von Linux verfügten die Rechner über weitaus weniger Leistung. Vielleicht ist hier ein Grund für die geringe Akzeptanz der (Tenex-)C-Shell unter Linux zu suchen. Während die C-Shell einem kommerziellen Lizenzmodell unterliegt, ist die Weiterentwicklung in Form der Tenex-C-Shell (Tcsh) frei und damit unter Linux verfügbar. Im Wesentlichen unterscheidet sich die Tcsh von ihrem Ahnen durch die verschiedenen Mechanismen zur Vervollständigung nach so genanntem Tenex-Stil. Aber nicht nur dem C-Programmierer kommt die C-Shell entgegen. Auch wer in der Solaris-Ecke heimisch ist und nur hin und wieder mit Linux in Berührung kommt, muss die vertraute Shell nicht missen. Csh vs. TcshNur kurz sollen die wesentlichen Unterschiede zwischen den beiden Shells aufgezählt werden. Die Tenex-C-Shell erweitert die Fähigkeiten der C-Shell um:
Nur das Unterbinden des Einlesens von Benutzer definierten Startdateien wurde in der Tcsh im Unterschied zur C-Shell nicht implementiert. Und zahlreiche Fehler, die die Implementierungen der C-Shell in sich bergen, sind in der Tcsh ausgemerzt. Leider noch nicht alle, wobei Kenner das für unmöglich halten, da Designfehler manche Ungereimtheiten bedingen. Gliederung dieses Abschnitts
Wichtige FähigkeitenIn obigem Vergleich zwischen Csh und Tcsh finden Sie die wichtigsten Argumente für die Verwendung der Tcsh. Etwas präziser soll die folgende Aufzählung ihre Stärken untermauern:
Einige DefinitionenDie folgenden Begriffe werden im Laufe des Textes wiederholt benötigt. Ihre Definitionen sind sicher nicht vollständig, sollten aber zum Verstehen ihrer Bedeutung genügen. Kommentare Siehe unter Syntax der Tcsh, Kommentare.
Kommando-Trennzeichen Das Semikolon oder der Zeilenumbruch begrenzt ein Kommando.
Operatoren
Zusammenfassung von Zuweisungs-, arithmetische, logische und Vergleichsoperatoren. Ein Operator
besteht aus ein oder zwei Zeichen mit Sonderbedeutungen (bspw. +, ++, -, ||, +=, <). Wir werden
im Laufe des Textes auf die verschiedenen Operatoren genauer eingehen.
Whitespace Steht für Leerzeichen und Tabulatoren und ggf. dem Zeilenumbruch.
Wort
Ein Wort ist eine Folge von Zeichen, die entweder von Whitespaces, von Kommando-Trennzeichen oder
von Operatoren umgeben ist. Beachten Sie, dass obige Worttrenner auch Bestandteil eines Wortes
sein können, wenn diese gequotet sind.
Abbildung 1: Unterteilung der Tcsh Interaktive und Nicht-Interaktive TcshIst die Tenex-C-Shell mit der Standardein- und Standardausgabe (sprich »mit einer (virtuellen) Konsole«) verbunden, so handelt es sich um eine interaktive Shell. Die interaktive Bash teilt sich wiederum ein in die Login Tcsh und die Nicht-Login Tcsh. Eine Shell mit eingeschränkten Nutzungsbefugnissen wie in der Bash gibt es nicht. Die Tcsh fungiert als Login-Shell, wenn sie entweder explizit mit der Option »-l« ([kleines »L«] und keiner weiteren Option!) gestartet wurde oder wenn das erste Argument (Argument 0) »-« ist. Die Login-Shell führt zunächst Kommandos aus den System weiten Dateien »/etc/csh.cshrc« und »/etc/csh.login« aus. Die Reihenfolge der Betrachtung der Nutzer definierten Startdateien ist abhängig von der konkreten Version. Meist wird die Datei »~/.tcshrc« betrachtet und nur falls diese nicht existiert die Datei »~/.cshrc«. Falls vorhanden, werden der Reihe die Dateien »~/.history«, »~/.login« und »~/.cshdirs« eingelesen. Jede Nicht-Login-Shell führt nur Kommandos der Dateien »/etc/csh.cshrc« und »~/.tcshrc« bzw. »~/.cshrc« aus. Optionen beim StartWir beschränken uns hier auf die wichtigsten Optionen. -c Kommando Die Tcsh führt das angegebene Kommando aus und endet anschließend. Das Kommando muss ein einzelnes Argument sein; umfasst es Optionen, ist der gesamte Ausdruck zu quoten:
-d
Die Shell lädt den Verzeichnisstack aus »~/.cshdirs«; sinnvoll nur bei einer
Nicht-Login-Tcsh.
-e
Die Tcsh endet sobald eines der in ihr ausgeführten Kommandos mit einem Fehler zurückkehrt;
nützlich in Shell-Skripten.
-f Ignoriert die Datei »~/.tcshrc«.
-i Die Shell ist interaktiv selbst dann, wenn ihre Ein- und Ausgabe nicht mit einem Terminal verbunden ist.
-l Die Tcsh arbeitet als Login-Shell. Die Option wird ignoriert, wenn außer ihr weitere Argumente angegeben werden.
-n Die Shell parst Kommandos ohne sie auszuführen; sinnvoll bei der Fehlersuche in Shell-Skripten.
-v Die Shellvariable verbose wird gesetzt. Jedes Kommando wird nach der History-Substitution nochmals angezeigt.
-x
Die Shellvariable echo wird gesetzt. Jedes Kommando wird unmittelbar vor seiner
Ausführung (also nach Vollzug sämtlicher Substitutionen) nochmals angezeigt.
-V
Wie »-v«, nur wird die Variable bereits vor der Verarbeitung der Datei
»~/.tcshrc« gesetzt.
-X
Wie »-X«, nur wird die Variable bereits vor der Verarbeitung der Datei
»~/.tcshrc« gesetzt.
Tcsh als Login-ShellIn den meisten Konfigurationen, die die Distributoren ausliefern, dürfte die Bash als Login-Shell voreingestellt sein. Bemühen Sie das Kommando chsh, um die Tcsh in der Passwortdatei als Default-Shell einzutragen. Dies funktioniert jedoch nur, wenn die Tcsh in der Datei /etc/shells eingetragen ist. Ist dem nicht so, könnte Ihnen entweder der Administrator aus der Patsche helfen, indem er den Eintrag in obiger Datei ergänzt oder Sie bauen in einem der Startup-Skripte Ihrer bisherigen Login-Shell den Aufruf »exec /usr/bin/tcsh -l« ein.
Zum Beenden stehen mehrere Möglichkeiten zur Verfügung. Ein [Ctrl]-[D] auf einer leeren Eingabezeile beendet sowohl die Login- als auch die Nicht-Login-Shell. Die Kommandos »logout« und »login« stehen allerdings nur in einer Login-Shell zur Verfügung. Letzteres ersetzt den Shellprozess durch das gleichnamige Kommando. Eine Besonderheit der Tcsh ist der Autologout-Mechanismus, der über die Belegung der Shellvariable autologout gesteuert wird. Mit dieser können Sie zwei verschiedene Zeiten (in Minuten) definieren. Zum einen die Zeitspanne, nach der die Shell bei Inaktivität automatisch abgemeldet wird und zum anderen (optional) die Dauer der Inaktivität, nach dem die Shell automatisch gesperrt wird. Eine gesperrte Shell kann nur durch Eingabe des Passworts reaktiviert werden. Fünfmalige falsche Passworteingabe führt automatisch zu einem Autologout.
Beim Beenden der Tcsh setzt diese in Abhängigkeit vom verwendeten Mechanismus die »logout« Shellvariable auf »normal« oder »automatic«. Abschließend führt sie Kommandos aus den Dateien »/etc/csh.logout« und »~/.logout« aus.
Der weitere Text erklärt: KommentareNormalerweise leitet das Doppelkreuz # in der Tcsh einen Kommentar ein. Alles, was diesem Zeichen folgt, wird von der Tcsh ignoriert bis zum nächsten Zeilenumbruch. Dies gilt sowohl für die interaktive als auch für die nicht-interaktive Tcsh. Eine Ausnahme sind Shellskripte, in denen die erste Zeile mit #!... beginnt. Für die Tcsh ist es die Anweisung, die nachfolgenden Zeilen mit dem hinter »#!« angegebenen Interpreter (eine Shell, Perl, awk, ...) auszuführen. Die Bedeutung von # kann durch Quoten (siehe später) aufgehoben werden. VariablenVariablennamen bestehen aus Buchstaben, Ziffern und dem Unterstrich, wobei ein Name nicht mit einer Ziffer beginnen darf. In der Tcsh existiert keine (praktische) Begrenzung der Länge von Variablennamen. Als Faustregel gilt, dass Umgebungsvariablen aus Groß- und lokale Variablen aus Kleinbuchstaben bestehen, aber die Shell selbst setzt diesbezüglich keine Vorschriften.
Quoting
Die InitialisierungsdateienDie ShellvariablenSpezielle ShellvariablenDie PromptsBei der interaktiven Arbeit mit der Tcsh zeigt die Shell ihre Bereitschaft zur Entgegennahme von Eingaben anhand eines Prompts (»Eingabeaufforderung«) an. Drei Prompts werden unterschieden, wobei zwei die Eingabeaufforderung symbolisieren:
Formatsequenzen: AliasseEingebaute Kommandos: Dieses »Kommando« tut nichts, außer einen Rückgabewert »0« zu erzeugen (»0« ist der übliche Rückgabewert eines Kommandos unter Unix, wenn seine Ausführung erfolgreich war). Nützlich ist es in Shellskripten, falls Sie in Bedingungen einen wahren Wert (»true«) benötigen oder an Positionen, wo syntaktisch ein Kommando erwartet wird, Sie aber keines benötigen:
Der KommandozeilenspeicherDer Kommandozeilenspeicher (History) verwaltet die Liste vormals eingegebener Kommandos. Sie kann sowohl als Referenz der bisherigen Kommandofolge als auch als eine Art Baukasten zur komfortablen Zusammenstellung neuer Kommandozeilen dienen. Zum Betrachten des aktuellen Inhalts des Kommandozeilenspeichers steht das eingebaute Kommando history zur Verfügung:
In der Voreinstellung werden die letzten 100 Kommandos aufgelistet. Durch Angabe der Anzahl als letztes Argument von »history« kann die Länge der Ausgabe variiert werden. Des Weiteren versteht »history« folgende Optionen: -c
Löscht den Inhalt des Kommandozeilenspeichers.
-h [n]
Unterdrückt die Ausgabe der Zeilenummerierung. Normalerweise sind alle
Einträge nummeriert, wobei der älteste Eintrag die Nummer 1 trägt.
Anhand solcher Nummern kann gezielt auf einen Eintrag des Kommandozeilenspeichers
zugegriffen werden. Die Angabe von n spezifiziert die Anzahl auszugebender
Einträge.
-r [n]
Schreibt die n letzten Einträge in umgekehrter Reihenfolge aus (den Ältesten zuletzt).
-T [n]
In Verbindung mit »-h« wird der Zeitstempel der Einträge auf einer extra
Zeile vor dem jeweiligen Eintrag ausgegeben. Die Zeitstempel sind als Kommentare markiert.
Diese Ausgabe entspricht dem Format einer History-Datei.
-S [Dateiname]
Speichern der History. Ist ein Dateiname angegeben, wird die History dorthin geschrieben, ansonsten
landet sie in der »normalen« History-Datei (Spezifiziert durch die Shellvariable
»histfile» oder, falls diese nicht gesetzt ist »~/.history«). Wie viele
Zeilen geschrieben werden und ob der Inhalt einer vorhandene Datei mit den neuen Einträgen
gemischt wird, hängt von der Belegung der Shellvariablen savehist ab (siehe nachfolgend).
-L Dateiname
Lädt die angegebene Datei und hängt die Einträge an den Kommandozeilenspeicher an.
Die Datei sollte also im History-Format vorliegen (vergleiche Option »-T«).
-M Dateiname
Wie »-L«, jedoch wird der Inhalt mit dem existierenden anhand der Zeitstempel gemischt
anstatt ihn »hinten« anzuhängen.
History-VariablenZahlreiche Shellvariablen beeinflussen den Kommandozeilenspeicher. Dazu zählen: histchars
Mit dieser Variablen kann die Vorbelegung des »History-Substitutionszeichens« (!)
und des Ersatzzeichens für das erste Argument (^) modifiziert werden. Weisen Sie hierzu
die beiden neu zu verwendenden Zeichen ohne Leerreichen der Variablen zu.
histdup
Die Variable steuert den Umgang mit identischen Einträgen im Kommandozeilenspeicher.
Steht ihr Inhalt auf »all«, wird das aktuelle Kommando nur in die History aufgenommen,
wenn noch kein identischer Eintrag existiert. Steht er auf »prev«, wird ein
Kommando nur aufgenommen, wenn es nicht dem letzten Eintrag entspricht. Mit »erase«
wird ein vorhandener identischer Eintrag entfernt und das aktuelle Kommando landet am Ende
des Speichers. Bei jedem anderen Wert oder falls die Variable nicht gesetzt ist, wird jede
Kommandozeile in die History eingetragen.
histfile
Enthält den Namen der Datei zum Abspeichern der History-Einträge. Ist die
Datei leer, wird »~/.history« angenommen, was der üblichen Verfahrensweise
entspricht.
histlit
????
history
Die Variable enthält einen oder zwei Werte. Der erste Wert gibt die Anzahl der
Einträge an, die im Kommandozeilenspeicher gehalten werden sollen. Der zweite
optionale Wert ist eine Formatzeichenkette, die angibt, wie Einträge der History
für die Ausgabe zu formatieren sind. Als Formatierer kommen die unter
Prompts genannten Zeichen in Frage.
savehist
Sobald die Variable gesetzt ist, ruft eine Shell, bevor sie endet, »history -S« auf,
womit der aktuelle Zustand des Kommandozeilenspeichers in die durch Datei »histfile«
sichert wird. »savehist« kann zwei Werte enthalten. Der erste gibt an, wie viele
Einträge des Kommandozeilenspeichers in die Datei zu sichern sind. Dieser Wert muss
kleiner oder maximal gleich dem ersten Wert der »history«-Shellvariable sein.
Ein optionaler zweiter Wert »merge« bewirkt, dass die aktuellen Werte der History
mit dem Inhalt einer existierenden Datei (bezeichnet durch »histfile«) gemischt werden,
wobei der Zeitstempel der Einträge als Kriterium der Sortierung dient.
Navigation in Einträgen des KommandozeilenspeichersDurch die Liste der Kommandos in der History und innerhalb einer Kommandozeile können Sie komfortabel mit Hilfe der Pfeiltasten und von Tastenkombinationen navigieren: , [Ctrl][P] Geht zum vorhergehenden Eintrag.
, [Ctrl][N] Geht zum nachfolgenden Eintrag.
Ein Zeichen nach links in der aktuellen Zeile.
Ein Zeichen nach rechts in der aktuellen Zeile.
[Home] Beginn aktuellen Zeile.
[End] Ende aktuellen Zeile.
Obige Tastenkombinationen beschreiben die Voreinstellung. Mittels dem eingebauten Kommando bindkey ist eine Änderung der Belegung möglich. Eine Suche im Kommandozeilenspeicher wird ebenso angeboten: Muster[Alt][p] Sucht rückwärts nach einem mit dem Muster beginnenden Eintrag.
Muster[Alt][n] Sucht vorwärts nach einem mit dem Muster beginnenden Eintrag.
Das Muster kann die Metazeichen »*«, »?«, »[]« und »{}« umfassen, allerdings betrifft dann die Suche nicht den Zeilenanfang sondern die gesamte Zeile. »echo« und »echo*« führen bspw. beide zur letzten Kommandozeile, die mit »echo« startete. »*echo« listet jedoch einzig eine Zeile auf, die mit »echo« endete. Um die Kommandozeile zu finden, die »echo« an beliebiger Position enthielt, ist folgende Eingabe erforderlich:
Zugriff über die History-SubstitutionEine History-Substitution wird mit dem so genannten »Bang-Operator« (!) eingeleitet. Die Art der Substitution schreiben die nachfolgenden Zeichen vor. Um keine History-Substitution handelt es sich jedoch, wenn dem »Bang-Operator« ein Whitespace, ein Gleichheitszeichen oder eine öffnende runde Klammer folgt (dann handelt es sich um einen unären Operator [Negation]). Folgende Ausdrücke gestatten die Ausführung von Kommandozeilen aus der History ohne deren vorherige Manipulation: !! Startet das vorhergehende Kommando (letzter Eintrag im Kommandozeilenspeicher).
!n Startet das Kommando von Zeile n der History.
!-n
Startet das Kommando der n-letzten Zeile des History (es wird also
von »hinten« gezählt; »!-1« entspricht »!!«).
!Präfix
Startet das aktuellste in der History eingetragene Kommando, das mit dem Präfix
beginnt.
!?Muster?
Startet das aktuellste in der History eingetragene Kommando, das das Muster
enthält.
Einige Beispiele dazu:
Die Wiederverwendung alter Kommandos nach obigem Substitutionsschema reißt sicher niemanden vom Hocker. Worin sollte der Vorteil gegenüber der Navigation im Kommandozeilenspeicher bestehen, die sogar das Editieren alter Einträge ermöglicht? Die weit reichenden Möglichkeiten der Substitution nutzen erst die Erweiterungen zum Bang Operator - so genannte Wortselektoren. Sie gestatten die Verwendung von Teilen eines vorherigen Kommandos in der aktuellen Kommandozeile. Eingeleitet wird eine solche Erweiterung durch einen Doppelpunkt, der dem Bang Operator und dem Muster, das das alte Kommando referenziert, folgt. Ein Beispiel ist hoffentlich verständlicher als meine Umschreibung:
Der Ausdruck »!!:3« wurde durch das dritte Argument des vorhergehenden Kommandos substituiert. Zugegeben... es ist kein sinnvolles Beispiel. Aber es ist einfach und sollte leicht zu verstehen sein. Der Zweck heiligt die Mittel. Folgende Aufzählung benennt sämtliche Erweiterungen, mit denen Bestandteile von History-Einträgen extrahiert werden können. n
Nummer des Arguments. »0« steht für das erste Wort der Kommandozeile
selbst, was i.d.R. der Kommandoname ist.
-n Argumente 0 bis n.
n- Argumente von n bis zum Vorletzten (!).
m-n Argumente von m bis n (m und n eingeschlossen).
^ Kurzform für das erste Argument (wie »:1«).
$ Das letzte Argument.
* Alle Argumente ab dem ersten (also ohne den Kommandonamen).
%
Nur in Verbindung mit »!?Muster?« erlaubt. »%« enthält
das Wort, das das Muster enthielt.
Hierzu wieder einige Beispiele:
Ganz schön verwirrend... oder? Aber es kommt noch besser! Sie sind nicht einmal darauf angewiesen, die Argumente in ursprünglicher Form zu verwenden, sondern Sie können diese mit verschiedensten Modifizierern auch noch zuvor bearbeiten. Vorab die Liste der Modifizierer: :e
Betrachtet das Argument als Dateiname und liefert - falls vorhanden - dessen Suffix.
:h
Entfernt in Pfadangaben die letzte Komponente, »:h:h« würde die
beiden letzten Komponenten entfernen usw.
:p
Unterdrückt nach einer History-Substitution die Ausführung des Kommandos. Der Modifizierer
eignet sich also zum Testen des korrekten Substitutionsausdrucks. Allerdings taucht das resultierende
Kommando trotzt Nichtausführung anschließend als eigenständiger Eintrag in der History auf.
:q Quotet im Ergebnis das substituierte Wort (schützt somit vor weiteren Expansionen).
:r
Entfernt den Suffix von Dateinamen. Der trennende Punkt bleibt erhalten. Mehrere Suffixe können
durch entsprechend viele Angaben des Modifizierers abgeschnitten werden.
:s/x/y/
Ersetzt im substituierten Wort die Zeichenkette x durch die Zeichenkette y. x darf
kein Regulärer Ausdruck sein. In y steht & zur Verfügung,
um auf die substituierte Zeichenkette zugreifen zu können. Anstatt dem Trennzeichen / kann
jedes beliebige andere Zeichen, welches nicht in den beiden Zeichenketten vorkommt, Verwendung finden.
:t Entfernt in Dateinamen den kompletten Pfadanteil.
:x Trennt das substituierte Wort an jedem Whitespace.
:& Verwendet den zuletzt genutzten Zeichenkettenmodifizierer erneut.
Und zum Abschluss wiederum einige Anwendungsbeispiele obiger Modifizierer:
Für die Zeichenkettenersetzung im vorhergehenden Kommando existiert ein spezieller Modifizierer. Roots Kopieroperationen in obigem Beispiel hätten auch wie folgt substituiert werden können:
Diese Kurzform eignet sich also wirklich nur, wenn das vorherige Kommando mit genau einem geänderten Argument zu wiederholen ist. |
||||||||||||||||||||||||||||||||
Korrekturen, Hinweise? |