CSH(1) MUTOS 1700 CSH(1) NAME csh - Kommandointerpreter mit C-ähnlicher Syntax ÜBERSICHT csh [ -cefinstvVxX ] [ arg ] ... BESCHREIBUNG Die Cshell (csh) ist eine erste Implementierung eines Kommandointerpreters, der einen History-Mechanismus, Job-Steuerfähigkeit und eine C-ähnliche Syn- tax enthält. Wird die Shell aktiviert, führt sie zuerst die Kommandos in dem File .cshrc in der Home-Directory des Aufrufers aus. Falls csh eine Login-Shell ist, werden auch die Kommandos in dem File .login ausgeführt. Im Normalfall beginnt csh nach der Eingabeanforderung "%", die Kommandos vom Terminal zu lesen. Die Verarbeitung der Argumente und die Benutzung der Shell zur Verarbeitung von Files, die in Kommandoskripten enthalten sind, wird später beschrieben. Die Shell führt dann wiederholt folgende Aktionen aus: Eine Zeile der Kommandoeingabe wird gelesen und in Worte geteilt. Diese Folge von Worten wird in der History-Liste abgelegt und zergliedert. Schließlich wird jedes Kommando der laufenden Zeile ausgeführt. Wenn eine Login-Shell endet, führt die Shell die Kommandos des Files .logout aus. _L_e_x_i_k_a_l_i_s_c_h_e _S_t_r_u_k_t_u_r Die Shell zerlegt die Eingabezeile in Worte, wobei Leerzeichen und Tabula- toren als Trennzeichen verstanden werden. Dabei gibt es folgende Ausnah- men. Die Zeichen &, |, ;, <, >, ( und ) bilden getrennte Worte. Die Zei- chenpaare &&, ||, << und >> bilden einzelne Worte. Diese Parser- Metazeichen können Teil eines anderen Wortes sein, oder ihre Sonderbedeu- tung ist durch ein vorangestelltes Backslash aufgehoben. Ein Newline mit einem vorangestellten Backslash ist äquivalent zu einem Leerzeichen. Zeichenketten, die in entsprechenden Zeichen zur Apostrophierung (', `, " ) eingeschlossen sind, bilden einen Teil eines Wortes. Metazeichen in sol- chen Zeichenketten, einschließlich Leerzeichen und Tabulatoren, bilden keine separaten Worte. Die Semantik dieser Apostrophierungszeichen wird später beschrieben. Ein Newline mit vorangestelltem Backslash, das in Apo- strophe oder in Anführungszeichen eingeschlossen ist, ergibt ein echtes Newline. Falls die Shell-Eingabe nicht über ein Terminal erfolgt, kenn- zeichnet ein "#" einen Kommentar, der sich bis zum Ende der Eingabezeile erstreckt. Die Sonderbedeutung von "#" wird durch ein vorangestelltes Backslash, durch den Einschluß in Apostrophe oder in Anführungszeichen auf- gehoben. 3/89 - 1 - CSH(1) MUTOS 1700 CSH(1) _K_o_m_m_a_n_d_o_s Ein einfaches Kommando ist ein Folge von Worten, wobei das erste Wort das auszuführende Kommando kennzeichnet. Ein einfaches Kommando oder eine Folge von einfachen Kommandos, die durch "|" getrennt sind, bilden eine Pipeline. Die Ausgabe jedes Kommandos einer Pipeline wird mit der Eingabe des nächsten Kommandos verbunden. Folgen von Pipelines, die durch Semiko- lon getrennt sind, werden nacheinander ausgeführt. Durch ein nachgestell- tes "&" kann eine Folge von Pipelines ausgeführt werden, ohne daß auf das jeweilige Ende zu warten ist. Jedes beliebige Kommando kann in runde Klam- mern eingeschlossen werden, um ein einfaches Kommando zu bilden, das eine Komponente einer Pipeline sein kann. Es ist auch möglich, Pipelines mit "||" oder "&&" zu trennen, was, wie in C, bewirkt, daß das zweite Kommando auszuführen ist, wenn das erste mißlingt bzw. erfolgreich ist (siehe Aus- drücke). _S_u_b_s_t_i_t_u_t_i_o_n Im weiteren werden die verschiedenen Transformationen der Eingabe beschrie- ben, die die Shell in der Reihenfolge ihres Auftretens ausführt. _H_i_s_t_o_r_y-_S_u_b_s_t_i_t_u_t_i_o_n Die History-Substitution ordnet Worte einer früheren Kommandoeingabe als Teil eines neuen Kommandos ein, erleichtert es, Kommandos zu wiederholen, wiederholt Argumente eines früheren Kommandos im aktuellen Kommando oder behebt Rechtschreibefehler mit geringem Eingabeaufwand. Diese Substitution beginnt mit einem Ausrufezeichen und kann irgendwo im Eingabestrom stehen (vorausgesetzt, er ist nicht geschachtelt). Ist dem Ausrufezeichen ein Backslash vorangestellt, wird dessen Sonderbedeutung aufgehoben. Ein Aus- rufezeichen bleibt auch dann unverändert, wenn nachfolgend ein Leerzeichen, ein Tabulator, ein Newline, ein Gleichheitszeichen oder eine öffnende runde Klammer steht. Eine beliebige Eingabezeile, die History-Substitutionen enthält, wird vor der Ausführung so auf dem Terminal ausgegeben, als wäre das Kommando ohne Substitutionen eingegeben worden. Alle Kommandoeingaben vom Terminal, bestehend aus einem oder mehreren Worten, werden in der History-Liste gerettet. Durch die History-Substitution werden gerettete Wortfolgen aus der History-Liste in den Eingabestrom eingebaut. Die Größe der Liste wird durch die Variable history festgelegt. Das vorhergehende Kommando wird immer aufbewahrt, ohne Beachtung des Wertes dieser Variablen. Die Kommandos werden fortlaufend, bei 1 beginnend, numeriert. Zum Beispiel zeigt die folgende Ausgabe der History-Liste die Kommandos mit ihren Ereignisnummern. 9 write michael 10 ex write.c 11 cat oldwrite.c 12 diff *write.c Gewöhnlich ist es nicht notwendig, die Ereignisnummern zu verwenden. Die Ereignisnummern können aber Teile der aktuellen Eingabe werden, indem die gewünschten Ereignisnummern mit vorangestelltem Ausrufezeichens in die Zei- chenfolge der neuen Eingabe eingesetzt werden. Bei dem laufenden Ereignis 13 erfolgt die Bezugnahme auf die vorangegangenen Ereignisse durch die Ereignisnummer direkt (z.B. !11) oder relativ (!-2). Eine weitere Möglich- keit der Bezugnahme ist die Verwendung eines Präfixes (z.B. entspricht "!d" Ereignis 12 oder "!w" entspricht Ereignis 9) oder einer Zeichenfolge, die 3/89 - 2 - CSH(1) MUTOS 1700 CSH(1) in einem Wort eines Kommandos enthalten ist (z.B. bezieht sich "!?mic?" auf Ereignis 9). Diese Formen ohne weitere Modifikationen stellen nur ein einfaches Wiedereinbringen von Kommandoworten dar, die durch Leerzeichen getrennt sind. Durch die Eingabe von "!!" wird auf das letzte Ereignis Bezug genommen. Die Worte eines Ereignisses werden bei Null beginnend numeriert und können bei einem Ereignis durch Doppelpunkt, gefolgt von einem Wortkennzeichner ausgewählt werden. Die Hauptwortkennzeichner sind: 0 erstes (Kommando) Wort n n-tes Wort ^ erstes Argument, d.h. 1 $ letztes Argument x-y Bereich der Worte -y Abkürzung für "0-y" * Abkürzung für "^-$" oder nichts, wenn nur ein Wort im Ereignis x* Abkürzung für "x-$" x- wie "x*", aber ohne letztes Wort Die Trennung mit Doppelpunkt bei der Ereigniszuordnung zu den Wortkenn- zeichnern kann weggelassen werden, wenn der Argumentenauswähler mit einem ^, $, *, - oder % beginnt. Nach den optionalen Wortkennzeichnern kann eine Folge von Modifikatoren auftreten, die durch Doppelpunkt getrennt sind. Folgende Modifikatoren sind definiert: h löscht die letzte Pfadnamenkomponente, der Stamm bleibt erhalten. r löscht die letzte .xxx Komponente, der Wurzelname bleibt übrig. t löscht alle führenden Pfadnamenkomponenten, das Ende bleibt übrig. & wiederholt die vorangegangene Substitution. g wendet die Änderung global an; Vorsetzen des Vorangegangenen, wie z.B. "g&". e löscht gesamten Pfadnamen außer ".xxx" s/l/r/ ersetzt _l durch _r, der letzte "/" kann entfallen, wenn ein New- line folgt. p gibt das neue Kommando ohne Ausführung aus. q apostrophiert die substituierten Worte, um weitere Substitutionen zu verhindern. x wie q,aber trennt Worte von Leerzeichen, Tabulatoren und New- lines. Sofern nicht ein g vorangestellt ist, wird die Modifikation nur auf das erste modifizierte Wort angewendet. Ein Fehler tritt auf, wenn die Substi- tution auf kein Wort anwendbar ist. Die linke Seite von Substitutionen ent- spricht keinem regulären Ausdruck im Sinne von Editoren, sondern eher einer Zeichenkette. Jedes beliebige Zeichen kann anstelle von "/" als Begrenzer verwendet werden. Ein Backslash apostrophiert den Begrenzer in der linken und rechten Zeichenfolge. Das Zeichen "&" auf der rechten Seite wird durch den Text der linken Seite ersetzt. Ein Backslash apostrophiert dieses Zei- chen. Eine leere Zeichenfolge _l benutzt eine vorhergehende Zeichenfolge entweder von einem _l oder von einem Textsuchen _s in ?_s?. Der abschließende Begrenzer einer Substitution, wie auch ein abschließendes "?" können beim Textsuchen entfallen, wenn unmittelbar ein Newline folgt. Eine History-Bezugnahme kann ohne eine Ereignisbestimmung angegeben werden, z.B. "!$". In diesem Fall erfolgt die Bezugnahme auf das vorangegangene 3/89 - 3 - CSH(1) MUTOS 1700 CSH(1) Kommando, wenn keine vorangegangene History-Bezugnahme auf der gleichen Zeile vorkam. In einem solchen Fall wird die vorangegangene Bezugnahme wie- derholt. Somit gibt "!?fix?^!$" das erste und letzte Kommando an, dem "?fix?" entspricht. Wenn das erste Nichtleerzeichen einer Eingabezeile ein "^" ist, so ist es äquivalent zu "!:s^", was damit eine geeignete Abkürzung für die Substitution des Textes der vorangegangenen Zeile liefert. So legt "^lb^lib^" die Rechtschreibung von "lib" im letzten Kommando fest. Eine History-Substitution kann in geschweiften Klammern eingeschlossen sein, um sie von den nachfolgenden Zeichen zu isolieren. So ergibt nach dem Kommando "ls -ld paul", die History-Substitution "!{l}a" das Kommando "ls -ld paula", während "!la" nach einem Kommando sucht, das mit "la" beginnt. _M_ö_g_l_i_c_h_k_e_i_t_e_n _d_e_s _A_p_o_s_t_r_o_p_h_i_e_r_e_n_s Das Apostrophieren von Zeichenfolgen durch Apostrophe oder Anführungszei- chen kann benutzt werden, um alle oder einige der restlichen Substitutionen zu verhindern. Zeichenfolgen, die in Apostrophe eingeschlossen sind, werden vor weiterer Interpretation geschützt. In Anführungszeichen eingeschlos- sene Zeichenfolgen sind Variable und erweiterte Kommandos, die in den nach- folgenden Abschnitten beschrieben werden. In beiden Fällen wird der resul- tierende Text (alles oder Teile) zu einem einzelnen Wort. In Spezialfällen (siehe Kommandosubstitution) liefert eine in Anführungszeichen eingeschlos- sene Zeichenfolge Teile von mehreren Wörtern, was bei Zeichenfolgen, die in Apostrophe eingeschlossen sind, niemals auftritt. _A_l_i_a_s-_S_u_b_s_t_i_t_u_t_i_o_n_e_n Die Shell unterhält eine Liste von Alias-Vereinbarungen, die durch die Kom- mandos alias bzw. unalias festgelegt, angezeigt und modifiziert werden können. Nachdem eine Kommandozeile geprüft wurde, wird sie in einzelne Kommandos aufgeteilt, und das erste Wort jedes Kommandos (links beginnend) wird daraufhin untersucht, ob es eine Alias-Vereinbarung enthält. Ist eine Alias-Vereinbarung enthalten, dann wird der Text, d.h. die Alias- Vereinbarung für dieses Kommando, nochmals mit dem vorhandenen History- Mechanismus gelesen. Die resultierenden Worte ersetzen die Kommando- und Argumentenliste. Wird kein Bezug auf die History-Liste genommen, bleibt die Argumentenliste unverändert. Falls "ls" die Alias-Vereinbarung für "ls -l" ist, so ergibt das Kommando "ls /usr" das Kommando "ls -l /usr". Die Argumentenliste bleibt unverän- dert. Ist "lookup" die Alias-Vereinbarung für "grep !^ /etc/passwd", so würde "lookup Otto" das Kommando "grep Otto /etc/passwd" ergeben. Wird eine Alias-Vereinbarung gefunden, wird die Worttransformation des Eingabe- textes ausgeführt und der Alias-Prozeß beginnt erneut auf der umgestalteten Eingabezeile. Falls das erste Wort des neuen Textes mit dem ersten Wort des alten Textes identisch ist, wird das weitere Wiederholen durch Kenn- zeichnung dieses Wortes verhindert, um einer weiteren Alias-Erzeugung vor- zubeugen. Alle anderen Wiederholungen werden ausfindig gemacht und ver- ursachen einen Fehler. Dieser Mechanismus erlaubt, für die Alias- Vereinbarungen eine strukturierte Metasyntax einzuführen. So überträgt die Anweisung alias print 'pr \!*|lpr' die Argumente auf den Zeilendrucker. 3/89 - 4 - CSH(1) MUTOS 1700 CSH(1) _V_a_r_i_a_b_l_e_n_s_u_b_s_t_i_t_u_t_i_o_n Die Shell unterhält eine Reihe von Variablen, die als Wert eine Liste von keinem oder mehreren Worten besitzen. Einige dieser Variablen werden durch die Shell gesetzt oder die Shell nimmt nur Bezug auf sie. Zum Beispiel ist die Variable argv ein Abbild der Shell-Argumentenliste. Die Bezugnahme auf den Wert dieser Variablen erfolgt auf besondere Art und Weise. Die Werte der Variablen werden mit den Kommandos set und unset festgelegt, angezeigt oder geändert. Ein Teil der Variablen, auf die die Shell Bezug nimmt, sind "Begleitvariablen". Bei diesen Variablen ist es für die Shell nur von Bedeutung, ob sie gesetzt sind oder nicht. Zum Beispiel ist die Variable verbose eine solche "Begleitvariable". Ist sie gesetzt, werden alle Kommandoeingaben vor ihrer Ausführung ausgegeben. Diese Variablen können auch beim Aufruf der Shell in der Kommandozeile mit der Option -v gesetzt werden. Andere Operationen bearbeiten die Variablen numerisch. Das Kommando @ erlaubt, numerische Berechnungen auszuführen, deren Ergebnisse Variablen zugewiesen werden. Jedoch werden Variablenwerte immer als Zeichenfolgen (null oder mehr) dargestellt. Für den Zweck der numerischen Berechnung wird die leere Folge als Null betrachtet und das zweite Wort bzw. die nach- folgenden Worte eines Mehrfachwortes werden ignoriert. Nachdem in jeder Eingabezeile die Alias-Substitution ausgeführt wurde, wird diese zerteilt. Vor jeder Kommandoausführung erfolgt die Variablensubstitution, die durch ein "$" verschlüsselt ist. Die Substitution kann durch Voranstellen eines Backslash verhindert werden, jedoch nicht innerhalb von Anführungszeichen, wo sie immer vorkommt und innerhalb von Apostrophen, wo sie niemals vorkommt. Zeichenfolgen, die in Apostrophe eingeschlossen sind, werden im Abschnitt Kommandosubstitutionen erläutert, so daß Substitutionen mit "$" bis dahin nicht vorkommen. Ein "$" wird unverändert übertragen, wenn ein Leerzeichen, ein Tabulator oder ein Newline folgt. Ein- und Ausgabeumkehrungen werden vor der Variablenerweiterung erkannt, und die Variablen werden separat erweitert. Andererseits werden der Kom- mandoname und die gesamte Argumentenliste gemeinsam erweitert. Es ist folg- lich möglich, für das erste Wort (Kommando) dieses Punktes mehr als ein Wort zu generieren. Das erste Wort wird zum Kommandonamen und die rest- lichen Worte werden zu Argumenten. Sofern sie nicht in Anführungszeichen eingeschlossen sind oder der Modifikator :q angegeben ist, können die Ergebnisse der Variablensubstitution eventuell substituierte Kommandonamen oder File-Namen sein. Innerhalb von Anführungszeichen erweitert sich eine Variable, deren Wert aus mehreren Worten besteht, zu (einem Teil) einem einzelnen Wort, wobei die Worte der Variablen durch Leerzeichen getrennt sind. Wenn der Modifkator :q bei einer Substitution angewendet wird, erwei- tert sich die Variable zu mehreren Worten, wobei jedes Wort durch Leerzei- chen getrennt und apostrophiert ist, um späteren Kommandosubstitutionen oder File-Namen-Substitutionen vorzubeugen. Die nachfolgenden Metafolgen sind für das Einführen variabler Werte in Shell-Eingaben vorgesehen. Es ist ein Fehler, auf eine Variable Bezug zu nehmen, die nicht gesetzt ist. $name ${name} wird ersetzt durch die Worte des Wertes der Variablen _n_a_m_e, jedes durch Leerzeichen getrennt. Geschweifte Klammern 3/89 - 5 - CSH(1) MUTOS 1700 CSH(1) trennen _n_a_m_e von nachfolgenden Zeichen, die sonst Teil von _n_a_m_e sein würden. Die Variablen bestehen aus bis zu 20 Buch- staben, Ziffern und dem Unterstrich. Der Variablenname muß mit einem Buchstaben beginnen. Falls _n_a_m_e keine Shell- Variable ist, aber in der Umgebung gesetzt ist, dann wird der Wert zurückgegeben (aber Modifikationen mit ":" und andere Formen, die im weiteren angegeben werden, sind in diesem Falle nicht verfügbar). $name[selector] ${name[selector]} Wählt nur einige Worte aus dem Wert von _n_a_m_e aus. Der Selektor ist abhängig von der Substitution mit "$" und kann aus einer einzelnen Zahl oder zwei Zahlen bestehen, die durch "-" getrennt sind. Das erste Wort eines Variablenwer- tes wird mit 1 numeriert. Wird der erste Wert eines Berei- ches weggelassen, so ist 1 Standard. Wird das letzte Glied eines Bereiches weggelassen, so ist "$#name" Standard. Der Selektor "*" wählt alle Werte aus. Es ist kein Fehler, wenn ein Bereich leer ist, wenn das zweite Argument weggelassen oder im Bereich ist. $#name ${#name} Gibt die Anzahl der Worte in der Variablen an. Das ist für eine weitere Verwendung in [_s_e_l_e_c_t_o_r] nützlich. $0 Substituiert den Namen des Files, von dem die Kommandoeingabe gelesen werden soll. Es wird ein Fehler angezeigt, wenn der Name unbekannt ist. $number ${number} Äquivalent zu $_a_r_g_v[_n_u_m_b_e_r] $* Äquivalent zu $_a_r_g_v[*] Die Modifikatoren :h, :t, :r, :q und :x können auf diese Substitution angewendet werden, ebenso :gh, :gt und :gr. Wenn geschweifte Klammern bei der Kommandogestaltung auftreten, so müssen die Modifikatoren innerhalb der Klammern stehen. Die laufende Anwendung erlaubt nur ein Modifikator in jeder Erweiterung mit "$". Die nachfolgenden Substitutionen können nicht mit ":" modifiziert werden. $?name ${?name} Substituiert die Zeichenfolge 1, wenn _n_a_m_e gesetzt ist; 0 wenn nicht. $?0 Substituiert 1, wenn der laufende Eingabe-File-Name bekannt ist, sonst 0. $$ Substituiert die Prozeßnummer (dezimal) der Parent-Shell. _K_o_m_m_a_n_d_o- _u_n_d _F_i_l_e-_N_a_m_e_n-_S_u_b_s_t_i_t_u_t_i_o_n Die verbleibenden Substitutionen, Kommando- und File-Namen-Substitutionen werden nacheinander auf die Argumente der Einbaukommandos angewendet. Das bedeutet, daß Teile des Ausdruckes, die nicht ausgewertet werden, dieser Erweiterung nicht unterworfen sind. Bei Kommandos, die nicht innerhalb der 3/89 - 6 - CSH(1) MUTOS 1700 CSH(1) Shell liegen, werden die Kommandonamen getrennt von der Argumentenliste substituiert. Das erfolgt erst sehr spät, nachdem Ein- und Ausgabe umge- lenkt wurde und in Child-Shells. _K_o_m_m_a_n_d_o_s_u_b_s_t_i_t_u_t_i_o_n Eine Kommandosubstitution wird durch ein Kommando angezeigt, das in Apo- strophe eingeschlossen ist. Die Ausgabe von einem solchen Kommando ist normalerweise in einzelne Worte geteilt, die durch Leerzeichen, Tabulatoren oder Newline getrennt sind, wobei Leerworte weggelassen werden. Die resul- tierende Zeichenfolge ersetzt die originale Zeichenfolge. Innerhalb von Anführungszeichen erzwingt nur Newline neue Worte. Leerzeichen und Tabula- toren bleiben erhalten. Ein einzelnes abschließendes Newline erzwingt kein neues Wort. Es ist so möglich, für eine Kommandosubstitution nur einen Teil eines Wortes zu liefern, sogar wenn das Kommando eine komplette Zeile ausgibt. _F_i_l_e-_N_a_m_e_n-_S_u_b_s_t_i_t_u_t_i_o_n Wenn ein Wort eines der folgenden Zeichen *, ?, [ oder { enthält oder mit ~ beginnt, dann ist das Wort ein Kandidat für eine File-Namen-Substitution. Dieses Wort wird dann als Kennzeichen betrachtet und durch eine alphabeti- sche Liste von File-Namen ersetzt, die diesem Kennzeichen entsprechen. In einer Liste von Worten, die File-Namen-Substitutionen angeben, ist es ein Fehler, wenn kein Kennzeichen einem existierenden File-Namen entspricht. Es ist nicht erforderlich, daß jedes Kennzeichen eine Entsprechung findet. Nur die Metazeichen. "*", "?" und "[" bedeuten eine Vergleichsfolge, dem- gegenüber entsprechen die Zeichen "~" und "{" eher einer Abkürzung. In vergleichenden File-Namen müssen sowohl der Punkt am Anfang eines File- Namens oder unmittelbar nach einem "/" als auch das Zeichen "/" explizit eine Entsprechung finden. Das Zeichen "*" ist eine beliebige Vergleichsfolge, die einer beliebigen Zeichenfolge, einschließlich der lee- ren Zeichenfolge entspricht. Das Zeichen "?" entspricht einem einzelnen Zeichen. Die Folge "[...]" entspricht irgendeinem Zeichen der eingeschlos- senen Zeichenfolge. Zwei Zeichen können durch ein Minus getrennt sein, um irgendeinem Zeichen der lexikalischen Folge zwischen ihnen zu entsprechen. Das Zeichen "~" am Anfang eines File-Namens wird benutzt, um sich auf die Home-Directory zu beziehen. Steht dieses Zeichen allein, wird es zur Ho