[Next] [Previous] [Top]

UNIX-Lehrtext

6. Arbeiten mit der Shell


6.1 Standard-Eingabe und Standard-Ausgabe

Viele Programme lesen Eingabeparameter, verarbeiten diese und liefern eine Ausgabe. Daher gibt es in Unix je einen vordefinierten Standard-Eingabe- und Ausgabekanal, die stdin und stdout genannt werden. Beide sind lediglich vordefinierte Dateien. Der Eingabekanal wird i.d.R. mit der Eingabe über die Tastatur identifiziert, der Ausgabekanal mit dem Bildschirm. In einer Umgebung mit verschiedenen logischen Terminals, wie etwa in einer Fensterumgebung, wo jedes Fenster ein eigenes logisches Terminal darstellt, sind stdin und stdout für jedes Fenster extra definiert.

Es gibt noch ein weiteres solches File, das stderr genannt wird und an das Fehlermeldungen weitergegeben werden. Es wird ebenfalls mit dem Terminal identifiziert, ist aber dennoch vom stdout zu unterscheiden. Deswegen können stdout und stderr in verschiedene Dateien umgeleitet werden, wenn man die Ausgabe nicht auf dem Bildschirm wünscht. Verschiedene Dateien sind oft praktisch, wenn die eigentlichen Ergebnisse nicht mit den Fehlermeldungen vermischt werden sollen.

6.2 Umleitung der Standard-Dateien

Umleitung bedeutet, dass den Standard-Dateien eine andere Datei zugeordnet wird, z.B. dass die Eingabeparameter aus einer normalen Datei gelesen werden oder die Ausgabe in eine normale Datei erfolgt. Standard-Eingabe wird mittels des Zeichens "<" umgeleitet.

Kommando < Eingabedatei
liest die Eingabe für Kommando aus der Datei Eingabedatei. Standard-Ausgabe wird durch ein ">"-Zeichen umgeleitet:

Kommando > Ausgabedatei
schreibt die Ausgabe von Kommando in die Ausgabedatei. Eine eventuell bereits existierende Ausgabedatei wird überschrieben.

Um die Ausgabe an eine Datei anzuhängen statt diese Datei vorher zu löschen, ersetzt man das ">"-Zeichen durch ">>". In sh und ksh kann stderr mit "2>" umgeleitet werden. Falls stdout bereits umgeleitet wurde und die Fehlermeldungen in der gleichen Datei gewünscht werden, verwendet man "2>&1". Beispiele:

Kommando < infile > outfile 2> errfile
verwendet die Eingabedaten aus infile, schreibt die Ergebnisse nach outfile und die Fehlermeldungen nach errfile. Die Reihenfolge der Umleitungen der Standard-Dateien kann ausgetauscht werden.

Kommando > outfile 2>&1
schreibt die Ergebnisse und Fehlermeldungen nach outfile. In diesem Fall ist die Reihenfolge der Umleitungen wichtig. Stdout muss umgeleitet werden, bevor stderr in dasselbe File umgeleitet werden kann.

In csh wird ">&" verwendet, um stdout und stderr in eine Datei umzuleiten:

Kommando >& outfile
Getrennte Umleitung von stderr und stdout ist in csh nicht möglich.

6.3 Pipes

Pipes ermöglichen, dass die Standard-Ausgabe eines Kommandos als stdin eines anderen Kommandos fungiert. Das Symbol für eine Pipe ist "|". Im folgenden Beispiel will man wissen, ob der Benutzer "volli" im AIX-Cluster eingeloggt ist. Man kann dazu die Ausgabe des fwho-Kommandos verwenden, das alle im Cluster eingeloggten Benutzer auflistet. Diese Ausgabe verwendet man dann als Eingabe für das grep-Kommando (grep sucht nach einem Muster und zeigt alle Zeilen an, die dieses Muster enthalten):

fwho | grep volli
zeigt alle Logins von "volli" im Cluster.

Ein anderes Beispiel ist ein ausführliches Listing (ls -l) eines umfangreichen Verzeichnisses. Um sich so eine Liste seitenweise ansehen zu können, wird die Ausgabe des "ls -l" in das Kommando more umgeleitet:

ls -l | more

6.4 Umgebungsvariablen

Während der Login-Prozedur setzt die Shell verschiedene Umgebungsvariablen. Einige wichtige davon haben wir unten aufgelistet.

Um den Wert von VARIABLE angezeigt zu bekommen, verwendet man "echo $VARIABLE". echo kopiert seine Argumente auf stdout und das $-Zeichen referenziert VARIABLE, d.h. es setzt deren Wert ein.

TERM
Der verwendete Terminaltyp, z.B. xterm oder vt220. Diese Variable wird von vielen Programmen verwendet, um die richtigen Kontrollzeichen etc. benutzen zu können.
DISPLAY
Das Display; diese Variable ist wichtig, wenn X11 verwendet wird (siehe Kapitel 11, Seite 50) .
PRINTER
Der voreingestellte Drucker; wird etwa von lpr verwendet.
PATH
Liste von Verzeichnissen, in denen die Shell nach Kommandos sucht.
PS1
Der Ausdruck, der in sh und ksh als (primärer) Prompt verwendet wird.
prompt
Der Ausdruck, der in csh als (primärer) Prompt verwendet wird.
HOME
Das Home-Verzeichnis, in dem man nach dem Login landet.
Um Shell-Variablen zu ändern, verwende man

Um ein weiteres Verzeichnis dem Pfad anzugliedern, z.B. weil der Benutzer arthur sein Unterverzeichnis bin im Pfad haben möchte, verwendet man:

Im Pfad wird das aktuelle Verzeichnis durch einen Punkt angegeben. Derartige Erweiterungen zum Pfad können in eine der Startup-Dateien geschrieben werden, so dass sie bei jedem Einloggen ausgeführt werden. Damit spart man sich das Tippen ganzer Pfadnamen, sofern das Kommando, das man ausführen will, in einem der in PATH gelisteten Verzeichnisse auftaucht. Gibt man ein Kommando mit einem einfachen Pfadnamen an, so sucht die Shell in allen Verzeichnissen des Pfades nach diesem Kommando. Dies geschieht genau in der in PATH spezifizierten Reihenfolge. Falls die Shell in keinem dieser Verzeichnisse das gesuchte Kommando findet, so wird die Fehlermeldung command not found ausgegeben. Um ein Kommando aufzurufen, das sich in keinem der Pfadverzeichnisse befindet, muss der volle oder der relative Pfadname angegeben werden. Um alle Verzeichnisse zu sehen, die sich momentan im Pfad befinden, tippt man "echo $PATH".

6.5 Aliases

Häufig gebrauchte Shell-Kommandos will man gerne abkürzen. Zu diesem Zweck können Aliases definiert werden. Besonders bequem ist es, diese Aliases in eine der Startup-Dateien zu schreiben, z.B. in Ihr ".kshrc" im AIX. Im folgenden Beispiel definieren wir das Alias ll für das Kommando "ls -l".

alias ll 'ls -l' in csh 
alias ll='ls -l' in ksh 
Bourne Shell (sh) erlaubt keine Aliases. Die richtige Anwendung von Anführungszeichen in der Shell ist eine ziemlich nichttriviale Angelegenheit. Bei Problemen kann man alle notwendige Information in den Manualen finden (wenn auch oft nicht besonders übersichtlich). Die oben angegebenen Formen sollten in den meisten Fällen gut funktionieren.

6.6 Verwendung von Shell-Sonderzeichen als normale Zeichen

(Zitieren von Sonderzeichen)

Manchmal werden in den Argumenten einer Kommandozeile Zeichen benötigt, die für die Shell eine besondere Bedeutung haben. Da man aber nicht diese besondere Shellinterpretation wünscht, müssen diese Zeichen zitiert werden. Zum Beispiel taucht dieses Problem auf, wenn man in einer Datei namens Telefon nach "Huber&Sohn" suchen will.

grep Huber&Sohn Telefon
funktioniert aber nicht, da das &-Zeichen der Shell mitteilt, dass das Kommando hier zu Ende ist und im Hintergrund bearbeitet werden soll. Der Rest der Zeile, nämlich "Sohn Telefon" wird als ein weiteres Kommando interpretiert.

Um der Interpretation des &-Zeichens durch die Shell zu entkommen, kann man zwischen den folgenden Möglichkeiten wählen:

Damit das Beispiel von oben funktioniert, kann man demnach verwenden:

grep "Huber&Sohn" Telefon
grep 'Huber&Sohn' Telefon
grep Huber\&Sohn Telefon

6.7 Abhilfe in Notfällen

Wenn ein Prozess definitiv etwas ganz anderes tut, als eigentlich beim Start bezweckt, kann man

Falls sich das Terminal sehr eigenartig verhält, etwa Eingaben nicht anzeigt oder komische Zeichen ausgibt, muss man die Terminalparameter wieder richtig setzen. Ein derartiges Verhalten kann z.B. das Resultat eines vi-Absturzes sein. Man gebe dann "C-jstty saneC-j" ein. Es kann sein, dass diese Eingabe nicht am Bildschirm erscheint. Die beiden "C-j" ersetzen dabei RETURN. Einige Systeme wollen anstelle des "stty sane" ein reset sehen.

6.8 Shell-Skripts

Die Shell kann auch als Programmiersprache verwendet werden. Konstruktionen wie Schleifen, Bedingungen etc. sind dazu vorhanden. Die Kommandos sind für die einzelnen Shells verschieden, aber sh, ksh und csh haben eine ziemlich grosse gemeinsame Schnittmenge. Die exakte Syntax findet man in den Manualseiten zu den Shells. Falls man Shell-Skripts schreiben will, ist die Verwendung von sh in Betracht zu ziehen, da sh garantiert in der Minimalversion auf jeder Unix-Maschine vorhanden ist, so dass sh-Shell-Skripts meistens problemlos auf andere Maschinen portiert werden können.

Shell-Skripts können auch einfach dazu dienen, häufig verwendete Kommandofolgen in eine Datei zu schreiben; denn alles, was in einer Kommandozeile stehen kann, kann auch in einem Shell-Skript stehen. Angenommen, man hat also nun so eine Datei, so gibt es zwei Möglichkeiten, diese als Kommando aufzurufen:

1.)

Man ruft das Skript explizit mit der zugehörigen Shell in der Kommandozeile auf:

 sh Skript
Dazu muss die Datei Skript lesbar sein.

2.)

Schreibe in Skript folgende erste Zeile:

 #!/bin/sh
Skript kann nun durch einfaches Angeben des Namens in der Kommandozeile aufgerufen werden. Dazu muss Skript allerdings ausführbar sein. Sind die ersten Zeichen einer Datei "#!", so erwartet das System als nächstes den Pfadnamen eines Interpreters, z.B. einer Shell, und verwendet diesen Interpreter, um die Datei abzuarbeiten.

Es folgen einige Beispiele. Das erste verwendet das find-Programm. Um dieses Skript zu verstehen, ist ein Blick auf die Manualseite für find sicher von Nutzen.

Das folgende Skript durchsucht das Homedirectory und dessen Unterverzeichnisse nach Dateien, die wahrscheinlich nicht mehr gebraucht werden, wie etwa Sicherungsdateien des emacs-Editors (diese enden auf eine Tilde "~"), ".aux" oder ".log" Dateien aus LaTeX-Läufen sowie core-Dateien. Core-Dateien werden erzeugt, wenn ein Programm wegen eines schwerwiegenden Laufzeitfehlers abgebrochen werden musste. Diese Dateien sind oft sehr gross und können daher viel Plattenplatz verbrauchen. Das gelegentliche Durchführen einer solchen Aufräumaktion hilft, weniger Plattenplatz zu brauchen.

#!/bin/sh
echo Beginne mit Aufräumen...
cd
find . \( -name '*~' -o -name '*.log' -o  \
       -name '*.aux' -o -name core \) -ok rm {} \;
echo Aufgeräumt!

Das erste cd stellt sicher, dass man sich zu Beginn des Kommandos im Homedirectory befindet. Das find-Kommando startet im aktuellen Arbeitsverzeichnis (also dem Homedirectory), das durch den Punkt dargestellt wird. Es sucht dort und in allen Unterverzeichnissen nach Dateinamen mit den Eigenschaften, die in Klammern in Anführungszeichen angegeben werden. Das "-name" bedeutet, dass nach dem entsprechenden Namen gesucht werden soll, das "-o" ist ein logisches Oder. Die Ausdrücke mit den Wildcards müssen in Anführungszeichen stehen, um einer Interpretation durch die Shell vorzubeugen. Das "-ok rm {} \;" bedeutet, dass find jede gefundene Datei löschen soll, aber vorher jeweils eine Bestätigung verlangen muss. Die beiden echo-Kommandos geben informative Meldungen aus.

Es folgt ein Skript, das eine Archivdatei der tex- und C-Unterverzeichnisse eines Homedirectories anlegen und komprimieren soll. Eine derartige Datei kann dann als Sicherungsdatei auf einer Diskette oder einem Streamerband gespeichert werden.

#!/bin/sh

cd
tar cvf - tex C | compress > backup.tar.Z
echo backup file: backup.tar.Z 

Derartige einfache Shell-Skripts sind besonders bei komplizierten Kommandos nützlich. Das letzte Beispiel fasst einige der typischen Morgenaktivitäten einer typischen Benutzerin zusammen und kommentiert diese mit aufmunternden Bemerkungen! Die #-Zeichen leiten Kommentare ein, d.h. der Rest der Zeile wird von der Shell ignoriert. Das Beispiel enthält auch eine for-Schleife.

#!/bin/sh

for i in 1 2 3   # eine for-Schleife in sh von 1 bis 3
do                  # gehoert zur for-Schleife
echo Guten Morgen!!!# gibt "Guten Morgen!!!" am 
                    # Bildschirm aus
sleep 2            # wartet 2 Sekunden (zum Aufwachen)
done                # beendet die for-Schleife
echo                # gibt eine Leerzeile aus
echo -n Heute ist   # das -n verhindert einen 
                    # Zeilenumbruch
date                # gibt Datum und Zeit aus
echo
echo Wer ist hier um diese fruehe Stunde ??
who | more          # zeigt andere Benutzer an
echo
echo Und wie geht es dieser Maschine ??
uptime               # zeigt den Status der Maschine
echo 
echo Was haben wir heute zu tun?
cat ~/TO_DO          # viele Leute schreiben ihre 
                     # Aufgaben in eine Datei wie TO_DO
echo Schau nicht so verschlafen aus der Waesche!! 

6.1 Standard-Eingabe und Standard-Ausgabe
6.2 Umleitung der Standard-Dateien
6.3 Pipes
6.4 Umgebungsvariablen
6.5 Aliases
6.6 Verwendung von Shell-Sonderzeichen als normale Zeichen
6.7 Abhilfe in Notfällen
6.8 Shell-Skripts

UNIX-Lehrtext - 23 SEP 94
[Next] [Previous] [Top]

Generated with WebMaker