login:
Danach wird die Eingabe eines Kennwortes angefordert:
password:
Nach erfolgreichem Anmelden beim gewählten System erscheint das Prompt-Zeichen des UNIX-Systems. Das Prompt-Zeichen der meisten UNIX-Systeme ist das $-Zeichen. Im UNIX-Pool des Rechenzentrums erscheint als Prompt-Text in der Regel der Name des ausgewählten Computers gefolgt vom Pfadnamen des aktuellen Verzeichnisses.
Auf den am Rechenzentrum eingesetzten X-Terminals erscheinen die Felder
login:
und Password:
gleichzeitig.
Nach der Eingabe der Arbeitsnummer wird mit <CR> weitergeschaltet in das Feld Password. Die Eingabe des Kennwortes wird wiederum mit <CR> beendet und der Anmeldevorgang gestartet. Die Eingabe eines ungültigen Kennwortes oder einer ungültigen Arbeitsnummer wird durch die Meldung
Login incorrect
angezeigt.
Die Kennwortänderung geschieht mit dem Befehl:
kpasswd
Beim Ändern muß der Anwender sein neues Kennwort zweimal eingeben, um die Folgen eines Tippfehlers zu vermeiden. Den üblicherweise in UNIX gebräuchliche Befehl passwd gibt es zwar auch, er hat jedoch nicht die gewünschte Wirkung und sollte daher nicht benutzt werden.
u - login user
g - group
o - other
Mit Hilfe dieser Benutzereinordnung werden unter einem reinen UNIX-System (ohne AFS) die Rechte des einzelnen Benutzers gesteuert. Jeder Benutzer ist über eine UID (User IDentification Number), die eindeutig mit dem Benutzernamen (Arbeitsnummer) verknüpft ist, identifiziert. Außer dieser UID besitzt jeder Benutzer noch eine GID (Group IDentification Number), mit der seine Zugehörigkeit zu einer Gruppe festgelegt ist. Mit anderen Mitgliedern dieser Gruppe kann sich der Benutzer gewisse Rechte teilen. Alle anderen Benutzer, die nicht in derselben Gruppe Mitglied sind, gehören in die Klasse other.
exit
verlassen. Bei vielen Systemen ist die Eingabe von <Ctrl-D> zum Beenden der Sitzung möglich. An einem X-Terminal ist es nicht ausreichend, alle offenen Fenster mit exit zu schließen. Die Sitzung ist damit nicht beendet und es können unter der laufenden Sitzung wieder neue Fenster geöffnet werden. Zur vollständigen Beendigung wird mittels der linken Maustaste das Hauptmenü (root menu) des Terminals aufgerufen und das Feld "Quit" ausgewählt. Falls vorhanden kann auch das orangefarbene "Logout"-Fenster in der unteren rechten Bildschirmecke angeklickt werden. An einem direkt an einer Workstation (z.B. aixgraf1) angeschlossenen Bildschirm, der als X-Terminal betrieben wird, muß die Sitzung durch die Kommandofolge
<Ctrl-Alt-BS>
und anschließend exit
beendet werden.
Achtung:
Wird die Sitzung nicht auf diese Weise ordentlich beendet, bleibt sie u.U. ohne ein Fenster bestehen. Jedermann kann dann unter der bestehenden Sitzung wieder ein Fenster öffnen und somit unter fremder UID arbeiten.
Datenbestände
Verzeichnisse (directories)
Datenbestände:
Eine normale UNIX-Datei entspricht konventionellen, aus anderen Betriebssystemen bekannten Dateien. In diesem Sinn kann eine normale Datei beliebige Daten aufnehmen, beispielsweise Programme, Daten und Texte. UNIX erwartet keinerlei spezielle Strukturierung einer Datei in Sätze, Blöcke, Sektoren und entbindet den Anwender somit von der Berücksichtigung physikalischer Strukturen der benutzten Hardware. Verzeichnisse:
Verzeichnisse (directories) sind Dateien, die Verweise auf weitere Dateien, die selbst wieder Verzeichnisse sein können, enthalten. Verzeichnisse können leer sein, d.h. sie enthalten nur einen Verweis auf sich selbst und auf das übergeordnete Verzeichnis. Es ergibt sich somit eine hierarchische Verzeichnisstruktur. Die Anzahl der Einträge in einem Verzeichnis ist beliebig und nur durch die Größe des Datenträgers begrenzt. Der Eintrag einer Datei besteht aus der systeminternen Knotennummer (i-node-number) und dem Dateinamen. Jeder Benutzer besitzt mindestens ein Verzeichnis, sein sogenanntes Home-Verzeichnis, in dem er beliebig viele weitere Verzeichnisse einrichten kann.
.a für Objektbibliotheken
.c für C-Quelltextdateien
.f für Fortran-Quelltextdateien
.o für Objektdateien
.p für Pascal-Quelltextdateien
Für die meisten Compiler unter UNIX sind diese Endungen zwingend vorgeschrieben.
Ausschnitt aus dem Dateibaum von UNIX
/afs In diesem Verzeichnis beginnt der Dateibaum für die von AFS (Andrew File System) verwalteten Dateien.
/bin (binaries) In diesem Verzeichnis befinden sich die am häufigsten benutzten Dienstprogramme, z.B.: rm. Die seltener benutzten Dienstprogramme befinden sich in /usr/bin. Alle Dienstprogramme können einfach durch Eingabe ihres Namens ausgeführt werden, sofern dieses Verzeichnis sich im Zugriffspfad (siehe Kapitel 2.3.3) befindet.
/dev (devices) In diesem Verzeichnis stehen alle Geräteeinträge (special files) sowie die leere Datei /dev/null.
/etc In diesem Verzeichnis befinden sich Systemverwaltungsprogramme und die meisten Systeminformationsdateien.
/tmp (temporary) Dieses Verzeichnis wird systemseitig in regelmäßigen Abständen gelöscht. Es kann von jedem Anwender als temporärer Plattenplatz verwendet werden.
/lib (libraries) Dieses Verzeichnis enthält einen Teil der Systembibliotheken (seltener benötigte Bibliotheken befinden sich im Verzeichnis /usr/lib).
/usr (user) Dieses Verzeichnis verwaltet alle Daten und Programme, die für die Anwender des Systemes bereitgestellt werden sollen. Zur besseren Strukturierung werden in diesem Verzeichnis wiederum eine größere Anzahl von Unterverzeichnissen angelegt:
/usr/adm in diesem Verzeichnis werden Informationen zur Systemverwaltung gespeichert. /usr/bin siehe /bin. /usr/include in diesem Verzeichnis befinden sich die sog. Headerdateien, die zur Programmierung mit C benutzt werden. /usr/lib siehe /lib. /usr/man in diesem Verzeichnis ist i.a. die Online-Dokumentation von UNIX abgelegt. /usr/spool dies ist der Sammelkatalog für das UNIX-Spooling-System.
Zur Veränderung des Arbeitsverzeichnisses wird das Kommando cd (change directory) verwendet. Fall Sie nicht mehr wissen, welches Ihr gerade benutztes Arbeitsverzeichnis ist, können Sie sich informieren mit dem Kommando pwd (print working directory).
Bei der Eingabe des cd-Befehls ohne Angabe eines Argumentes wird das sogenannte Home-Verzeichnis eingestellt. Die Eingabe von zwei Punkten als Argument des cd-Befehls bewirkt den Wechsel zum übergeordneten Verzeichnis des aktuellen Kataloges.
Ein Verzeichnis wird mit dem Kommando rmdir (remove directory) gelöscht. Beim Löschen eines Verzeichnisses muß dieses leer sein, d.h. es dürfen keine Einträge im Verzeichnis mehr vorhanden sein.
Man kann überall dort, wo man Dateinamen verwendet, auch den absoluten oder einen relativen Pfadnamen angeben. Auf diese Weise kann ein Name mehrmals in verschiedenen Verzeichnissen verwendet werden, weil die zugehörige Datei eindeutig über den Pfad bestimmt ist.
- Dateiname
- Dateizugriffspfad (Pfadname)
- Dateityp
- Zugriffsrechte (protection bits)
- Dateilänge
- Knotennummer (i-node), eine eindeutige Nummer innerhalb eines Dateisystems
- Anzahl der Links (Aliasnamen) auf die Datei
- Datum der Erstellung, der letzten Änderung und des letzten Zugriffs
- Benutzernummer des Eigentümers und seiner Gruppe
Man kann sich über die Attribute mit dem ls-Kommando umfassend informieren.
Beispiel:
ls -l
total 139 drwxrwxrwx 5 x18 system 2048 Mar26 15:59 . drwxrwxrwx 2 root system 2048 Feb 10 11:12 .. -rw-r--r-- 1 x18 system 11088 Feb 26 21:14 XMdeskware.orig -rw-r--r-- 1 x18 system 7296 Feb 26 21:14 ae.job drwxr-xr-x 2 daemon system 2048 Feb 10 11:57 bin --rw-r--r-- 1 x18 system 0 Mar 26 15:59 ls.out -rwxr-xr-x 1 daemon system 1776 Jan 22 18:49 profile.etc -rw-r--r-- 1 x18 system 4996 Mar 26 12:06 ps.out -rwxrwxr-- 1 daemon system 1171 Nov 09 1990 rc.boot4 -r-xr-xr-x 1 daemon system 2879 May 21 1990 rc.install -rw-rwxr-- 1 daemon system 660 May 20 1990 rc.ncs -r-xr-xr-- 1 daemon system 6876 May 20 1990 rc.net -rwxr-xr-x 1 daemon system 1876 May 21 1990 rc.nfs -rwxrwxr-- 1 daemon system 2018 Feb 20 1991 rc.tape1 -rwxrwxr-- 1 daemon system 2838 Feb 20 1991 rc.tape2 drwxr-xr-x 2 x18 system 2048 Feb 14 12:55 supplies -rw-r--r-- 1 x18 system 43 Feb 26 21:14 test.nqs drwxr-xr-x 2 x18 system 2048 Feb 14 12:55 waste -rw-r--r-- 1 x18 system 104 Feb 14 12:55 xdefaults -rw-r--r-- 1 x18 system 138 Feb 26 21:14 xdtinitial.xde
Bedeutung der Angaben:
Die 10 Zeichen der ersten Spalte beschreiben in den Spalten 2 bis 10 die herkömmlichen Zugriffsrechte in einem UNIX-Dateisystem. Das erste Zeichen beschreibt die Art der Datei:
- normale Datei
d Verzeichnis (directory)
F Verzeichnis, das mittels NFS zu dem Verzeichnisbaum definiert wurde
Die Zahl in der zweiten Spalte gibt an, wieviele Namen für diese Datei existieren. Eine Datei kann nämlich durchaus mehr als einen Namen haben. Das heißt, die Daten sind physikalisch nur einmal vorhanden, aber unter Umständen unter mehreren verschiedenen Namen und Zugriffspfaden ansprechbar. Wie man für eine Datei weitere Namen vergibt, ist in Kapitel 2.4.2.7 nachzulesen.
In der dritten Spalte steht der Name (Arbeitsnummer) des Eigentümers, die vierte Spalte bezeichnet die Gruppenzugehörigkeit der Datei. Spalte fünf beinhaltet die Größe der Datei in Bytes. Danach folgen der Zeitpunkt der letzten Änderung der Datei. In der letzten Spalte steht der Dateiname.
- Lesen (r - read)
- Schreiben (w - write)
- Ausführen (x - execute)
Insgesamt können somit neun Zugriffsrechte (protection bits) für jede Datei gesetzt werden. Diese Zugriffsrechte gibt es für alle Dateien, also auch für "special files" und Verzeichnisse. Mit der Vergabe von Rechten sollte aus Gründen des Datenschutzes und der Datensicherheit sehr vorsichtig umgegangen werden. Achtung:Diese Zugriffsrechte gelten nur für Dateien, die von UNIX direkt verwaltet werden. Das am URZ eingesetzte Andrew File System (AFS) beinhaltet eine eigene anders organisierte Verwaltung der Zugriffsrechte. Die hier beschriebenen "protection bits" haben für von AFS verwaltete Dateien nahezu keine Bedeutung. An der Ausgabe des ls-Kommandos (ls -l) kann man die Zugriffsrechte ablesen.
Die Zeichen 2 bis 4 zeigen die Rechte des Eigentümers, die mittleren die Rechte der Gruppenmitglieder und die letzten drei Zeichen die Rechte aller anderen Benutzer an.
Die Zugriffsrechte auf Verzeichnisse stellen eine Besonderheit dar, die Zugriffsrechte besitzen hier eine etwas andere Bedeutung.
Um ein Verzeichnis ansehen oder durchsuchen zu können, benötigt man nicht nur das Leserecht auf diesem Verzeichnis, sondern auch das Ausführungsrecht, d.h. einer Benutzerklasse muß das r- und das x-Bit eines Verzeichnisses gesetzt sein, damit ein Mitglied dieser Klasse überhaupt auf Dateien dieses Verzeichnisses zugreifen kann.
Ist das w-Bit eines Verzeichnisses für eine Benutzerklasse gesetzt, so kann jedes Mitglied dieser Klasse eigene Dateien in dieses Verzeichnis eintragen. Eigentümer dieser neuen Dateien ist der Benutzer, der die Datei anlegt. Es ist gefährlich, diese Schreibberechtigung zu vergeben, da jeder, der das Schreibrecht auf ein Verzeichnis besitzt, auch Dateien aus diesem Verzeichnis löschen kann, und zwar unabhängig davon, ob er irgendwelche Zugriffsrechte auf diese Datei besitzt oder nicht.
Mit dem Kommando chmod (change mode) kann der Eigentümer einer Datei die Zugriffsrechte einer Datei ändern.
Die Gruppenzugehörigkeit einer Datei kann vom Eigentümer mit dem Befehl chgrp (change group) geändert werden. Voraussetzung dazu ist allerdings, daß der Eigentümer auch Mitglied der neuen Gruppe ist.
Jedem Prozeß ist eine eindeutige Nummer, PID (Process IDentification), zugeordnet.
Nach erfolgreicher Anmeldung (login) startet der init-Prozeß für jeden Benutzer einen eigenen Prozeß, nämlich die systemseitig definierte login-Shell. Mit dem login wird der Benutzer Eigentümer genau dieses Prozesses und damit aller von diesem erzeugten Tochterprozesse. Verläßt der Benutzer die login-Shell (exit), so ist seine Sitzung beendet.
Einen Überblick über die laufenden Prozesse kann mit dem Kommando ps (process status) erhalten.
Beispiel:
ps
PID TTY TIME CMD 4712 pts/0 0:00 ps 4711 pts/0 0:01 /bin/bash
Zwei Prozesse werden angezeigt, nämlich die login-Shell mit der PID 4711 und der dem Kommando ps entsprechende Prozeß mit der PID 4712.
Will man alle im System laufenden Prozesse sehen, so muß man die Option -a (alle an ein Terminal gebundenen Prozesse) und -x (alle nicht an ein Terminal gebundenen Prozesse) benutzen.Mit dem Kommando who kann man sich anzeigen lassen, welche Benutzer momentan an welchem Gerät arbeiten.
Beispiel:
who
x18 pts/2 Mar 26 11:26 (vulcan.urz.uni-h) x41 pts/3 Mar 26 10:23 (guenther.urz.uni) b09 pts/0 Mar 26 13:09 (xst0.urz.uni-hei) b09 pts/4 Mar 13 13:39 (xst0.urz.uni-hei) x13 pts/5 Mar 26 14:45 (xst1.urz.uni-hei) b09 pts/1 Mar 18 15:50 (xst0.urz.uni-hei) x13 pts/7 Mar 26 14:47 (xst1.urz.uni-hei)
Manchmal ist es auch notwendig, den Namen der eigenen Sitzung zu erfragen mit dem Kommando:
who am i
x18 pts/1 Mar 27 10:09
oder mit
id
uid=1018(x18) gid=0(system)
Mit Hilfe dieses Skripts kann jeder Anwender seine Umgebung nach seinen persönlichen Präferenzen einrichten und z.B. die Umgebungsvariablen definieren, die von den nachfolgend verwendeten Kommandos benutzt werden.
Die sogenannten Umgebungsvariablen können bereits während des login-Vorganges gesetzt werden. Bei einer Umgebungsvariablen handelt es sich um eine Zeichenfolge im Format name=wert, wobei name eine Folge von beliebigen Zeichen, mit Ausnahme des Dollarzeichens und des Leerzeichens, sein kann. Jedem Benutzer sind in der Regel eine Reihe von Umgebungsvariablen zugeordnet. Ihre Definition hängt vom benutzten System, der installierten Software und den Anforderungen des Anwenders ab.
Die Werte aller Umgebungsvariablen können mit dem Kommando
env
abgerufen werden. Das Kommando env gibt eine vollständige Auflistung aller definierten Umgebungsvariablen aus.
Die UNIX-Shell ist kein Bestandteil des Betriebssystemkerns, sondern ein eigenes Programm, das wie jedes andere UNIX-Kommando aufgerufen werden und auch ausgetauscht werden kann.
Auf den unterschiedlichen UNIX-Implementierungen existiert eine Reihe verschiedener Shell-Programme. Die Bourne-Shell, benannt nach ihrem Autor Steve Bourne, ist auf praktisch allen Systemen vorhanden. Sie ist, was Komfort und Bedienerfreundlichkeit angeht, nicht mehr zeitgemäß. Allerdings hat sich ihre Skriptsprache als Quasistandard etabliert: Die meisten Shellskripte werden in der Skriptsprache der Bourne-Shell geschrieben und sind so auf allen Unix-Rechnern lauffähig.
Eine zweite, ebenfalls sehr weit verbreitete Shell, die C-Shell, entwickelt an der Universität von Kalifornien in Berkeley, stellt eine beträchtliche Erweiterung der Bourne-Shell dar, ist aber nicht auf allen UNIX-Systemen vorhanden.
Die Shell, welche nach dem Login eines Benutzers gestartet wird, wird zunächst vom Systemverwalter festgelegt, sie kann vom Benutzer nachträglich mit dem Kommando chcs geändert werden. Man kann auch während einer Sitzung jederzeit eine Unter-Shell aufrufen, indem man z.B. das Kommando
/bin/sh
für eine Bourne-Shell eingibt. Im Unix-Pool des URZ sind unter anderem folgende Shells aufrufbar:
Kommando Name der Shell /bin/sh Bourne-Shell /bin/csh C-Shell /bin/ksh Korne-Shell /bin/tcsh tcsh-Shell /bin/bash bash-Shell
Normalerweise steht das Verzeichnis /bin im Suchpfad, sodaß die Pfadangabe entfallen kann.
Mit dem Kommando
exit
wird diese Unter-Shell wieder verlassen und in die aufrufende Shell zurückgekehrt. Man kann die aufrufende Shell auch ganz durch eine neue Shell ersetzen, in dem man die neue Shell mit dem Befehl exec aufruft, z.B. für die C-Shell den Befehl
exec /bin/csh
benutzt. Jetzt würde aber der Befehl exit nicht nur die Shell, sondern die ganze Dialogsitzung (bzw. an einem X-Terminal zumindest das Fenster) schließen.
Die Bash-Shell ist ein sog. Public-Domain-Programm und als Erweiterung der Bourne-Shell zu dieser aufwärtskompatibel. Sie bietet zudem wesentliche Erweiterungen gegenüber der Bourne-Shell und viele nützliche Funktionen der C-Shell. Die Skriptsprache ist identisch mit der der Bourne-Shell, sodaß dafür geschriebene Shell-Skripte unverändert ablauffähig sind. All diese Tatsachen haben zu dem inzwischen recht hohem Verbreitungsgrad der Bash-Shell beigetragen, weshalb die Bash-Shell auch im Unix-Pool des URZ die standardmäßige Login-Shell ist.
Die Aufwärtskompatibilität zur Bourne-Shell bedeutet auch, daß alles, was in der Standardliteratur über diese zu finden ist, auch für die Bash-Shell gilt. Daher wird im folgenden auch in erster Linie auf die Erweiterungen der Bash-Shell eingegangen.
Sofern die Bash-Shell nicht schon als Login-Shell eingetragen ist, erfolgt ihr Aufruf durch:
/bin/bash
alias, bg, bind, break, builtin, bye, cd, command, continue, declare, dirs, echo, enable, eval, exec, exit, export, fc, fg, getopts, hash, help, history, jobs, kill, let, local, logout, popd, pushd, pwd, read, readonly, return, set, shift, suspend, test, times, trap, type, ulimit, umask, unalias, unset, wait.
Selbstverständlich braucht man im Normalfall nur einige wenige Befehle aus dieser Liste. Die Befehle wurden jedoch aus folgendem Grund vollständig aufgelistet: Bei der Benennung eigener Programme oder Shell-Skripte ist darauf zu achten, daß man den Namen dafür von denen interner Befehle verschieden wählt, da sonst ohne besondere Vorkehrungen der entsprechende interne Befehl anstelle des eigenen Programms aufgerufen wird.
Eine Liste der internen Befehle mit deren Syntax erhält man über den Bash-Shell-internen Befehl help. Eine ausführliche Beschreibung einzelner Befehle liefert die Befehlsfolge help befehl. Der man-Befehl liefert keine Information zu shell-internen Befehlen. In manchen Fällen gibt er, irreführenderweise, Information aus zu eventuell gleichnamigen Befehlen und Unterkommandos anderer Unix-Befehle.
Es gibt einige Variablen, welche von der Shell selbst mit Werten vorbelegt werden. Dies sind die folgenden Variablen:
PPID, PWD, OLDPWD, REPLY, UID, BASH, BASH_VERSION, SHLVL, RANDOM, SECONDS, LINENO, OPTARG, OPTIND.
Eine ganze Reihe weiterer Variablen werden von der Shell benutzt, wobei ihnen in manchen Fällen auch ein Standardwert zugewiesen wird:
IFS, PATH, HOME, CDPATH, ENV, MAIL, MAILCHECK, MAILPATH, MAIL_EARNING, PS1, PS2, PS4, NO_PROMPT_VARS, HISTSIZE, HISTFILESIZE, OPTERR, PROMPT_COMMAND, IGNOREEOF, IGNORFEOF, HOSTTYPE, TMOUT, FCEDIT, FIGNORE, NOTIFY, NOTIFY, HISTORY_CONTROL, COMMAND_ORIENTED_HISTORY, GLOB_DOT_FILENAMES, ALLOW_NULL_GLOB_EXPANSION, HISTCHARS, NOLINKS, HOSTNAME_COMPLETION_FILE, NOCLOBBER, AUTO_RESUME, NO_EXIT_ON_FAILED_EXEC, CDABLE_VARS, PUSHD_SILENT.
Bei der Wahl der Namen für eigene Variablen ist darauf zu achten, daß diese von den Namen aus den beiden obigen Listen verschieden gewählt werden. Ein einfachsten geht das, wenn man für Namen eigener Variablen nur Kleinbuchstaben verwendet.
Variablen werden nicht explizit deklariert oder vereinbart. Durch Benutzung eines neuen Namens wird automatisch eine entsprechende neue Variable vereinbart. Einen Wert weist man einer Variablen durch folgende Anweisung zu:
variable=wert
wert kann in Hochkomma (Zeichen ' auf der #-Taste, nicht den Akzent) oder Gänsefüßchen eingeschlossen werden, insbesondere falls dort Sonderzeichen enthalten sind, welche andernfalls von der Shell als Metazeichen interpretiert würden. Auch wenn wert nur aus Ziffern besteht, handelt es sich um eine Zeichenkette.
Möchte man sich den Inhalt einer Variablen ausgeben lassen, so kann man dazu den shell-internen Befehl echo benutzen:
echo $variable
Der echo-Befehl gibt einfach den ihm als Parameter übergebenen Text auf dem Bildschirm aus. Das $-Zeichen vor dem Variablennamen bewirkt, daß dieser durch den Inhalt der Variablen ersetzt wird. Insofern wird also hier dem echo-Befehl der Inhalt der angegebenen Variablen als Parameter übergeben. Die Liste aller vereinbarten Variablen einschließlich deren Inhalte kann man sich mit dem Befehl set anzeigen lassen.
Wie auch in vielen höheren Programmiersprachen wird auch bei Shell-Variablen zwischen lokalen und globalen Variablen unterschieden. Ohne weitere explizite Vereinbarung sind Shell-Variablen zunächst lokal. Das bedeutet, sie gelten nur für die aktuelle Shell. Sie werden nicht an eventuell daraus gestartete Prozesse oder Sub-Shells übergeben. Gleichnamige, ebenfalls lokale Variablen in einer Subshell sind nicht mit denen der aktuellen Shell identisch.
Globale Variablen hingegen,welche auch Umgebungsvariablen genannt werden, sind auch allen von der aktuellen Shell aus gestarteten Programmen, also insbesondere auch in einer neuen Shell, bekannt. Werden also Shell-Variablen z.B dazu benutzt, um Informationen an Programme weiterzugeben, sind zu diesem Zweck globale Variablen zu benutzen. Eine lokale Variable kann global gemacht werden mit dem Befehl export:
export variable
Hierbei kann auch gleich ein Wert mit zugewiesen werden:
export variable=wert
Man kann die zugewiesene Zeichenkette wert wie bei der normalen Zuweisung auch wieder in Hochkomma oder Gänsefüßchen eingeschließen. Soll das Attribut "global" wieder aufgehoben werden, so benutzt man die Option -n des export-Befehles:
export -n variable
Die Namen aller globalen Variablen einschließlich der ihnen zugewiesenen Werte bekommt man durch Eingabe des export-Befehls ohne weitere Parameter.
Möchte man als Beispiel beim Aufruf des Editors vi erreichen, daß immer automatisch die Optionen showmode und number gesetzt sind, so kann man diese Informationen über die von vi dafür vorgesehene Shell-Variable EXINIT an den Editor übergeben. Das funktioniert aber nur, wenn diese Variable global ist, da für den Editor ein eigener Prozeß gestartet wird.:
export EXINIT="set showmode number"
In den folgenden Abschnitten werden noch einige besondere Shellvariablen vorgestellt, welche insbesondere Ablauf und Verhalten der aktuellen Shell selbst steuern.
PATH gibt den Kommando-Suchpfad für die Shell an. Diese Variable enthält volle Pfadnamen zu den Dateiverzeichnissen, die durchsucht werden müssen. Ein Doppelpunkt (:) schließt jeweils einen Pfad ab. Die angegebenen Verzeichnisse werden in der Reihenfolge durchsucht, in der sie in PATH angegeben worden sind. HOME enthält den vollen Pfadnamen des Login-Verzeichnisses (home-directory). HOME wird im Kommando cd als Standard-Parameter benutzt, falls kein anderer angegeben wird. MAIL Die Shell durchsucht nach jeder Kommandoausführung die in MAIL angegebene Datei nach einem neuen Eintrag. Wird ein Eintrag gefunden, so erscheint am Bildschirm eine entsprechende Meldung. PS1 enthält das Zeichen, das die Shell bei interaktiver Benutzung ausgibt, sobald eine Eingabe erwartet wird. PS2 Falls im Dialog syntaktische Shell-Strukturen benutzt werden, die über mehrere Zeilen gehen, so gibt die Shell am Beginn einer jeden neuen Zeile den Inhalt von PS2 aus, bis die Struktur abgeschlossen ist. TERM Bezeichnung des angeschlossenen Terminaltyps USER Benutzername SHELL voller Pfadname des Shellinterpreters UMASK Aktuelle Einstellung für umask
Zeichen Bedeutung \d Datum \w Working-Directory \t Uhrzeit \h Rechnername \n neue Zeile \# laufende Nummer
Der Promptext sollte in Hochkomma eingeschlossen werden:
PS1='Prompttext'
Um einen veränderlichen Prompttext zu erhalten, können innerhalb der Prompttextes aber auch Shellvariablen benutzt werden. Sie werden jeweils vor der jeweiligen Ausgabe des Textes durch ihren aktuellen Inhalt ersetzt. Dem Namen der Variablen ist ein $-Zeichen voranzustellen. Analog dazu können auch Befehle mit einbezogen werden. Sie werden jeweils vor Ausgabe des Prompttextes ausgeführt, sofern der Befehl zusammen mit eventuellen Parametern in ` eingeschlossen ist. Anstelle des Befehles selbst wird die Ausgabe des Befehles in den Prompttext übernommen. Folgende Tabelle gibt einige Beispiele:
Inhalt von PS1 Prompttext '\h:$PWD>' aixfile2:/u/urz/x29> '\h:\w>' aixfile2:~> '`fs q` \t\n\h:$PWD>' 27% of quota used. 14:00:09 aixfile2:/u/urz/x29>
Das erste Beispiel ist die Voreinstellung für den Prompttext im Unix-Pool des URZ. Anstelle der Shell-Variablen $PWD hätte auch die Zeichenkombination \w benutzt werden können, jedoch unterscheidet sich die Ausgabe etwas im Format.
Folgende Wildcards können verwendet werden:
* beliebige, 0-14 Zeichen lange Zeichenkette ? genau ein beliebiges Zeichen z.B.: [bdz7] genau eines der Zeichen b, d, z oder 7 Z.B.: [g-r] genau ein Zeichen aus dem Bereich g bis r
Beispiele:
rm * löscht alle Dateien im aktuellen Verzeichnis
rm ? löscht alle Dateien, deren Name aus genau einem Zeichen besteht
chmod 700 * ändert die Zugriffsrechte aller Dateien im aktuellen Verzeichnis
rm dat[1-3]a löscht die Dateien dat1a, dat2a und dat3a
Hinweis:
Die aufgeführten Beispiele zum Löschen ganzer Dateigruppen sind nicht ganz ungefährlich. Vorsichtshalber sollte das rm-Kommando in folgender Form verwendet werden:
rm -i ....... (interaktives Löschen)
- Es liest von der Standardeingabe (stdin).
- Es schreibt auf die Standardausgabe (stdout).
- Fehlermeldungen gelangen auf die Standardfehlerausgabe (stderr).
Viele Kommandos sind Filter. Auch Benutzerprogramme sollten nach Möglichkeit als Filter geschrieben werden. Filter verfolgen ein virtuelles Dateikonzept. Es gibt folgende Voreinstellungen:
stdin Tastatur stdout Bildschirm stderr BildschirmDurch Umlenkung auf der Shellebene können andere Dateien angeschlossen werden. Die Programme bleiben dabei völlig unberührt.
Folgende Umlenkzeichen können verwendet werden:
> Ausgabeumlenkung (alter Dateiinhalt wird, falls vorhanden, überschrieben) >> Ausgabeumlenkung (die Ausgabe wird an alten Dateiinhalt, falls vorhanden, angehängt) 2> Ausgabeumlenkung für stderr, stdout wird auf stderr gelegt 2>> analog zu >> 1>&2 Standardkanal 1 wird auf Kanal 2 gelegt < EingabeumlenkungBeispiel:
Das Kommando
ls -l > datei.liste
speichert die Ausgabe des Kommandos ls -l in der Datei datei.liste.
Dadurch erspart man sich die Angabe von temporären Zwischendateien. Das Pipezeichen ist der senkrechte Strich (|). Mit Hilfe von Pipes lassen sich mächtige und evtl. auch langlaufende Kommandos erzeugen.
Beispiel:
ls -l | more erzeugt eine bildschirmgerechte Ausgabe
Während mit Hilfe der Zeichen > und < die Dateiausgabe bzw. die Dateieingabe umgelenkt werden können, lassen sich mit Hilfe des |-Zeichens verschiedene Programme direkt verbinden, ohne daß Zwischendateien angegeben werden müssen.
In der Shellvariablen PATH steht dazu eine Liste von Verzeichnisnamen. Die einzelnen Einträge sind jeweils durch Doppelpunkt getrennt. Wird nun ein Programmname oder Kommandoname eingegeben, so durchsucht die Shell nacheinander die einzelnen Verzeichnisse, welche in PATH angegeben sind, ob dort das betreffende Kommando zu finden ist.
Um nicht bei jedem Befehlsaufruf den gewünschten Befehl unter Zuhilfenahme des Suchpfades aufs neue suchen zu müssen, legt die Shell eine Tabelle an, in der alle bereits aufgerufenen Befehle zusammen mit der Pfadangabe eingetragen werden. Vor dem Durchsuchen der Verzeichnisse im Suchpfad wird zunächst in dieser Tabelle nachgeschaut. Ist ein Befehl dort bereits vorhanden, so wird die hier vermerkte Pfadangabe benutzt, um Zeit zu sparen. Diese Tabelle kann mit dem Shell-Befehl hash aufgelistet werden.
Für den seltenen, aber denkbaren Fall, daß sich das Verzeichnis, in dem ein Befehl abgelegt ist, ändert (man hat z.B. ein Programm in ein anderes Verzeichnis verschoben), so muß man dafür Sorge tragen, daß ein eventuell bereits vorhandener Eintrag in der oben genannten Tabelle vorher gelöscht wird, da der Befehl sonst nicht gefunden wird, obwohl er in einem im Suchpfad enthaltenen Verzeichnis steht. Hierzu benutzt man den hash-Befehl:
hash kommando
hash -r kommando
Im ersten Fall wird der Tabelleneintrag für das angegebene Kommando aktualisiert, im zweiten Fall gelöscht.
Desweiteren werden alle eingegebenen Befehlszeilen in einem Puffer zwischengespeichert. Die Anzahl der Zeilen, welche in diesem Puffer Platz hat, wird in der Shell-Variablen HISTSIZE festgelegt (URZ-Voreinstellung: 500). Ist der Puffer voll, wird die älteste Zeile entfernt. Mit den Tasten "Cursor rauf" und "Cursor runter" kann in diesem Puffer geblättert werden, wobei dabei die Befehlszeilen nacheinander in der Eingabezeile erscheinen. Eine solche Zeile kann beliebig verändert werden. Erst nach Betätigen der Eingabetaste wird sie ausgeführt. Diese Zeile steht dann als aktuellste Zeile im Puffer, gleichgültig ob sie verändert wurde oder nicht. Dieser Mechanismus ist sehr hilfreich, wenn immer wieder eine bestimmte Befehlsfolge benötigt wird, sich aber die Programmierung eines Skriptes noch nicht lohnt: Beispiel: Quellenprogramm editieren, Compiler aufrufen, Programm aufrufen, wieder das Quellenprogramm editieren usw.
Dieser Puffer wird sogar nach Beendigung der Shell permanent abgespeichert. Hierzu wird normalerweise die Datei .bash_history benutzt. Der Name dieser Datei steht in der Shell-Variablen HISTFILE, die Anzahl der Zeilen, welche in dieser Datei abgelegt werden, ist der Variablen HISTFILESIZE abgelegt (URZ: 500). Beim Starten einer Shell, also insbesondere bei einem neuen Login, wird diese Datei wieder in den temporären Puffer kopiert, sodaß sofort wieder die letzten Befehle aus der letzten Sitzung zur Verfügung stehen.
Achtung:
Der temporäre Puffer wird nur zurückgeschrieben, wenn die Shell beendet wird (etwa durch die Befehle exit oder logout oder auch durch die Tastenkombination <Ctrl>+d). Schließen des Fensters oder gar Benutzung des Logout-Knopfes am X-Terminal "killt" den Prozeß, in welchem die Shell abläuft, ohne die Shell ordnungsgemäß zu beenden.
Normalerweise benutzt man diese Funktion zur Vervollständigung von Dateinamen. Da Unix-Befehle nichts anderes als in Dateien abgelegte Programme sind, gilt das gleiche auch für Namen von Befehlen und Skripten sowie shellinternen Befehlen. Steht vor dem eingetippten Namensanfang ein Leerzeichen (oder wird in der ersten Spalte der EIngabezeile begonnen), so versucht die Shell hier immer, auf einen gültigen Dateinamen zu vervollständigen. Beginnt der Namensanfang hingegen mit einem $-Zeichen, so wird, falls möglich, auf den Namen einer vorhandenen Shellvariablen ergänzt. Bei einer Tilde nimmt die Shell an, es handele sich um einen Benutzernamen, bei einem @-Zeichen wird auf einen gültigen Rechnernamen ergänzt.
Beginn mit ... ergänze auf ... Befehl bzw. Datei $ Variablenname ~ Benutzername @ RechnernameDie Ergänzung auf Rechnernamen funktioniert allerdings nur mit Rechnern, welche in der Datei /etc/hosts eingetragen sind.
Am URZ enthält die Datei /etc/hosts nur die minimal notwendigen Einträge. Ansonsten wird der domain naming service (DNS) verwendet.
alias kürzel=text
Der Text rechts vom Gleichheitszeichen kann in Hochkomma oder Gänsefüßchen eingeschlossen werden. Die Eingabe des Kürzels als Befehl bewirkt dann die Ausführung des ihm zugewiesenen Textes so, als wäre dieser direkt eingegeben worden. Es folgen drei Beispiele:
alias new="ls -lat | head"
alias ll="ls -la"
alias ls="ls -la"
Das erste Kürzel new liefert eine Liste der zehn zuletzt geänderten Dateien, das Kürzel ll eine ausführliche Dateiliste. Im dritten Beispiel erkennt man, daß man auch ein Kürzel definieren kann, dessen Name mit dem eines Befehles identisch ist. Der Befehl wird dadurch überschrieben; bei Eingabe von ls wird das entsprechende Kürzel benutzt. Soll dennoch einmal der Originalbefehl aufgerufen werden, so kann dazu der interne Befehl command benutzt werden:
command ls
bewirkt die direkte Ausführung des Unix-Befehles ls, obwohl ein gleichnamiges Kürzel vereinbart wurde.
Werden bei Aufruf des Kürzels Parameter mit angegeben, so werden diese hinten an des betreffenden Text angehängt. Als Beispiel diene das eben vereinbarte Kürzel ll:
ll otto
führt folgenden Befehl aus.
ls -la otto
Im einfachsten Fall enthält ein solches Shellskript eine Folge von Unix-Befehlen, Programmaufrufen und shellinternen Befehlen, welche nach Aufruf des Skriptes sequentiell abgearbeitet wird. Zur Abarbeitung dieses Skriptes wird ein eigener Prozeß mit einer Subshell gestartet, welche die Befehle dann interpretiert.
Zudem hat man noch die Möglichkeit, durch speziell dafür vorgesehene Sprachelemente von dieser sequentiellen Abarbeitung abzuweichen. Es gibt Anweisungen zur Programmierung von Schleifen und Verzweigungen. Sprünge sind jedoch nicht möglich. Zudem kann der Ablauf eines Shellskriptes auch durch Parameter gesteuert werden, welche beim Aufruf des Sktiptes angegeben werden können. Diese Parameter stehen dann während der Ausführung des Skriptes in speziellen Shell-Variablen zur Verfügung und können beliebig verarbeitet werden.
Ein Shellskript ist aus Sicht des Betriebssystems eine normale Textdatei, welche mit jedem beliebigen Editor erstellt und bearbeitet werden kann. Zur Ausführung der Datei ist Leseberechtigung erforderlich. Der Aufruf geschiegt über den Befehl sh:
sh Shellskript-Datei
Der Befehl sh startet eine Sub-Shell (Bourne-Shell), in welcher dann die Anweisungen der Skriptdatei ablaufen. Steht die Skriptdatei in einem Verzeichnis, welches im Suchpfad enthalten ist, so kann sie direkt durch Eingabe ihres Namens aufgerufen werden. Voraussetzung hierfür ist jedoch, daß für den Aufrufer zusätzlich zur Leseberechtigung auch noch Ausführberechtigung besteht.
Werden mehr als 9 Parameter übergeben, so stehen der zehnte und alle weiteren Parameter nicht direkt zur Verfügung. Eine Möglichkeit ist hier die Benutzung der Variablen $*. Sie enthält die komplette Parameter-Zeichenkette wie beim Aufruf angegeben. Diese kann dann z.B. mit einer for-Schleife (siehe dort) ausgewertet werden. Eine andere Möglichkeit stellt der shellinterne Befehl shift dar: Durch den Aufruf von shift werden alle Parameter in die Variable mit der nächst niedrigeren Nummer verschoben. Der alte Inhalt von $2 steht dann in $1, der von $3 nun in $2 usw. Der Inhalt von $1 steht danach also nicht mehr zur Verfügung und muß daher ggf. vorher ausgewertet werden. Der zehnte, bisher unzugängliche Parameter steht nunmehr in $9 zur Verfügung. Durch Angabe einer positiven, ganze Zahl n kann dieser Vorgang beschleuningt werden: Der Aufruf shift 5 entspricht z.B. dem fünfmaligen Aufruf von shift.
Zu dem gibt es noch die Variable $0, welche den Namen der aufgerufenen Skriptdatei in der Form enthält, wie dieser beim Aufruf angegeben wurde, also z.B. ggf. mit Pfadangabe. $0 wird durch den Befehl shift nicht verändert. Die Variable $$ enthält die PID, d.h. die Prozeßnummer des das Skript ausführenden Prozesses.
Folgende Tabelle stellt die in diesem Abschnitt behandelten Variablen noch einmal zusammen:
Variable Bedeutung $0 Name der Skriptdatei mit Pfadangabe $1, $2, ..., $9 erster bis neunter Parameter $* kompletter Parameterstring $# Anzahl der Parameter $$ PID des Skriptes
Das Ganze soll nun noch durch ein kleines Beispiel verdeutlich werden. Der Aufruf des Shellskriptes skript
/u/urz/x29/skript Montag 17.5.1993
führt zu folgender Variablenbelegung:
Variable Belegung $0 /u/urz/x29/skript $1 Montag $2 17.5.1993 $# 2 $* Montag 17.5.1993
for variable in liste
do
...
done
variable steht für den Namen der zu benutzenden Laufvariablen. Dieser ist ohne $-Zeichen anzugeben. liste ist eine Zeichenkette. Der Schleifenkörper, das sind die Anweisungen zwischen do und done (oben durch ... dargestellt), wird entsprechend der Anzahl der Wörter in liste durchlaufen, wobei der Laufvariablen vor jedem Durchlauf jeweils das nächste Wort aus liste zugewiesen wird. Die Wörter in liste werden durch ein oder mehrere Leerzeichen getrennt. Fehlt das Schlüsselwort in zusammen mit liste, so wird die Zeichenkette $*, also die beim Aufruf der Skriptes als Parameter angegebene Zeichenkette benutzt.
Folgender Ausschnitt aus einem Shell-Skript löscht alle Dateien im aktuellen Verzeichnis, deren Name mit .text endet, und gibt für jede Datei eine entsprechende Meldung aus:
for i in *.text
do
rm -r $i
echo Datei $i geloescht
done
Hierbei wird von der Shell der Text *.text durch eine Liste aller diesen Namensmuster entsprechenden Dateinamen ersetzt.
Eine for-Schleife kann vorzeitig verlassen werden. Die Anweisung break beendet die Schleifenausführung durch einen Sprung hinter das erste Kommando folgend auf done. Die Anweisung continue hingegen bewirkt einen Sprung auf die erste Anweisung innerhalb der Schleife, wobei die Laufvariable mit den nächsten Wert belegt wird. Beiden Anweisungen kann noch eine positive ganze Zahl als Parameter übergeben werden, wobei dann bei geschachtelten Schleifen gleich mehrere innere Schleifen verlassen werden bzw. an den Anfang einer entsprechend weit außen liegenden Schleife gesprungen wird.
Die case-Anweisung arbeitet ähnlich wie gleichnamige Anweisung in Programmiersprachen wie etwa Pascal oder C, wenn auch mit etwas anderer Syntax.:
case wort in
muster1) kdo-folge1;;
muster2) kdo-folge2;;
.....
*) kdo-folgen;;
esac
wort sowie die verschiedenen Vegleichsmuster muster sind Zeichenketten; die rechte Klammer dahinter dient zur Trennung und gehört nicht zur Zeichenkette selbst. wort, normalerweise der Inhalt einer Shellvariablen, wird zuerst mit dem ersten angegebenen Muster verglichen. Bei Übereinstimmung wird die dort angegebene Kommandofolge ausgeführt, danach an die nächste Anweisung hinter esac verzweigt. Andernsfalls wird mit der nächsten Muster verglichen usw. Tritt bei keinem Vergleich Übereinstimmung auf, so wird die Kommandofolge in der mit *) beginnenden Zeile ausgeführt. Diese Zeile kann auch weggelassen werden. Ohne Übereinstimmung mit einem Vergleichsmuster wird dann ebenfalls mit der auf esac folgenden Anweisung fortgefahren.
Enthalten die einzelnen Kommandofolgen mehrere Kommandos, so sind diese durch durch Semikolon (;) zu trennen und können auch auf mehrere Zeilen verteilt werden. Aus diesem Grund muß stets mit einem doppelten Semikolon abgeschlossen werden, auch wenn die Kommandofolge nur aus einem einzelnen Kommando besteht.
Es folgt ein Beispiel zur Verwendung der case-Anweisung. Zur Demonstration diene ein kleines Shellskript names dirprint. Das Skript druckt den Inhalt des aktuellen Verzeichnisses aus. Als Parameter können -kurz, -lang oder -ganzlang angegeben werden, je nach dem, wie ausführlich die Liste sein soll. Bei allen anderen Parameterangaben erfolgt eine (knappe) Fehlermeldung:
case $1 in
-kurz) ls | lpr;;
-lang) ls -lag | lpr;;
-ganzlang) ls -lagR | lpr;;
*) echo "haeh ??";;
esac
Der einzige zu übergebende Parameter steht in der Variablen $1 zur Verfügung. Sollte beim Aufruf gar kein Parameter angegeben worden sein, so ist $1 leer, was ebenfalls zur Ausgabe der Fehlermeldung führt.
Zur Formulierung von Vergleichsoperationen dient die test-Anweisung. Hiermit können, speziell in Zusammenhang mit den Anweisungen if, while und until, Verzweigungen und bedingte Schleifen programmiert werden.
Die einfache Form der if-Anweisung hat folgende Syntax:
if kdo-folge
then kdo-folge
else kdo-folge
fi
Besteht kdo-folge aus mehr als einem Kommando, so sind diese durch Semikolon (;) zu trennen. Es können auch mehrere Zeilen benutzt werden. Ist der Exit-Status der Kommandofolge hinter if gleich 0, so wird die Kommandofolge hinter then abgearbeitet, andernfalls die hinter else. Danach wird mit der auf fi folgenden Anweisung fortgefahren. Die else-Klausel kann auch entfallen.
In der erweiterten Form der if-Aweisung können noch eine oder mehrere elif-Klauseln verwendet werden:
if kdo-folge
then kdo-folge
elif kdo-folge
then kdo-folge
elif kdo-folge
then kdo-folge
...
else kdo-folge
fi
Ist der Exit-Status der Kommandogolge hinter if von 0 verschieden, so kommt die Kommandofolge hinter der ersten elif-Klausel zur Ausführung, wobei dann in Abhängigkeit dessen Exit-Statuses entweder die Kommandofolge hinter der zugehörigen then-Klausel oder aber der nächsten elif-Klausel abgearbeitet wird.
Sicher kommt es häufig vor, daß man mit der if-Anweisung eine Programmverzweigung in Abhängigkeit einer oder mehrerer Bedingungen programmieren kann. Da aber auf if immer eine Kommandofolge, also keine Bedingung folgt, benutzt man hier die test-Aneisung. Ihr wird als Parameter eine Bedingung übergeben. Test liefert dann seinerseits einen Exit-Staus 0, falls die Bedingung erfüllt ist. Andernfalls ist der Exit-Status von 0 verschieden.
Mit test kann entweder das Vorhandensein einer Datei oder das Ergebnis einer Vergleichsoperation abgefragt werden. Im folgenden werden beide Möglichkeiten kurz angerissen. Weitere Informationen erhält man durch "help test", da test ein shellinterner Befehl ist.
Möchte man das Vorhandensein einer bestimmten Datei abfragen, so übergibt man test den entsprechenden Dateinamen und stellt diesem noch ein Attribut voran, welches zusätzlich abgefragt wird. Existiert die Datei und hat zusätzlich das gewünschte Attribut, so gibt test den Exit-Status 0 zurück.
Mögliche Argumente für test sind folgende:
-r datei Datei existiert und es besteht Leseerlaubnis -w datei Schreiberlaubnis -x datei ausführbar -f datei "normale" Datei -d datei Katalog (Directory) -s datei Datei nicht leer
So kann zum Beispiel abgefragt werden, ob die Datei /etc/hosts existiert und eine gewöhnliche Datei, also z.B. kein Verzeichnis o.ä. ist, mit folgender if-Anweisung:
if test -f /etc/hosts
Eine andere, häufig anzutreffende Schreibweise ist die folgende:
if [ -f /etc/hosts ]
Beide Zeilen sind jedoch in der Wirkung identisch. Man beachte die Leerzeichen neben den eckigen Klammern, welche wesentlich sind.
Die andere Möglichkeit ist, als Parameter für test eine Vergleichsbedingung zu formulieren, wobei hier sowohl Zeichenkettenvergleiche als auch arithmetische Vergleiche möglich sind. Arithmetische Vergleiche setzen natürlich voraus, daß die Operanden numerisch interpretiert werden können.
Im einzelnen sind folgende arithmetische Vergleiche möglich:
-lt kleiner -le kleiner gleich -eq gleich -ne ungleich -ge größer gleich -gt größer
Hingegen gibt es nur zwei Zeichenkettenvergleiche:
= gleich != ungleich
Der Unterschied z.B. zwischen = und -eq wird schnell durch folgendes Beispiel deutlich: Es ist gilt zwar 012 -eq 12, aber 012 != 12.
Mehrere Vergleiche bzw. Bedingungen könnenn logisch verknüpft werden, und zwar durch -a (und-Verknüpfung) oder -o (oder-Verknüpfung). Beispiel:
if test $a = Fehler -a -f /etc/error
if [ $a = Fehler -a -f /etc/error ]
Zur Programmierung von Schleifen dienen neben der bereits vorgestellten for-Anweisung insbesondere die Anweisungen while und until. Hier wird eine Gruppe von Anweisungen solange wiederholt abgearbeitet, bis eine bestimmte Kommandofolge einen Exit-Status ungleich 0 (while) oder den Exit-Status 0 (until) liefert. Die Syntax beider Befehle ist recht ähnlich:
while kdo-folge
do
...
done
bzw.
until kdo-folge
do
...
done
Auch bei der until-Schleife wird die Kommandofolge, deren Exit-Status über einen erneuten Schleifendurchlauf entscheidet, immer zu Beginn ausgeführt. Hier unterscheidet sich die until-Anweisung von den zu oft gleichnamigen Anweisungen in C oder Pascal. Analog zur for-Anweisung können auch wieder die Anweisungen break und continue verwendet werden.
ps -aefl
anzeigen lassen.
Neben den angezeigten Prozeßdaten existieren noch weitere Kenndaten, die nicht angezeigt werden, wie z.B. die GID des Prozesses oder das Verzeichnis, von dem aus der Prozeß gestartet wurde.
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD 202803 S root 1 0 0 60 20 1004 160 Mar 10 - 15:31 /etc/init 240801 S root 1977 1 0 60 20 34ad 88 1cd4a1 Mar 10 - 4:25 /etc/syncd 60 8 260801 S root 2259 1 0 60 20 18c6 240 Mar 10 - 0:00 /etc/srcmstr 42801 S root 3259 1 0 60 20 50b4 240 bb18 Mar 10 - 0:00 /usr/lib/errdemo n 240801 S root 3350 2259 0 60 20 314c 144 Mar 10 - 0:00 /etc/qdaemon 240801 S x18 3717 1 0 60 20 11a4 120 11:25:0 hft/ 0:00 ksh 1 1 /usr/bin/X11/xin it 260801 S x18 4490 3717 0 60 20 6539 436 11:25:1 hft/ 0:00 mwm 0 1 200001 R x18 4795 5017 8 64 20 1104 140 12:06:4 pts/ 0:00 ps -aelf 0 1 240801 S x18 5017 7320 1 60 20 7a5e 136 11:55:0 pts/ 0:00 /bin/ksh 2 1 260801 S root 5855 2259 0 60 20 30ec 152 Mar 10 - 0:10 /etc/syslogd 260801 S root 6114 2259 0 60 20 58f6 228 Mar 10 - 0:00 /usr/lib/sendmai l -bd -q30m 60801 S root 6892 1 0 60 20 290a 288 Mar 10 - 0:00 /etc/inetd 260801 S x18 7059 1 0 60 20 4e1 280 11:25:5 - 0:04 aixterm 7 260801 S x18 7320 1 0 60 20 1ca7 280 11:55:0 - 0:02 aixterm 2 250001 Z x18 7565 4490 0 60 20 0:00 <defunct> 260801 S root 8704 2259 0 60 20 7d1f 176 Mar 10 - 0:00 /usr/etc/rpc.mou ntd 260801 S root 8962 2259 0 60 20 922 152 Mar 10 - 0:00 /usr/etc/rpc.sta td 260801 S root 9220 2259 0 60 20 1d27 164 Mar 10 - 0:00 /usr/etc/rpc.loc kd 240801 S root 9478 1 0 26 20 1926 228 1db614 Mar 10 - 5:05 /etc/cron 60801 S root 9752 1 0 60 20 4411 616 Mar 10 - 0:27 /usr/vice/etc/af sd -rmtsys 240801 S x18 10486 1 0 60 20 318c 132 1bce07 Mar 24 hft/ 0:02 -ksh c 0 260801 S x18 10887 1 2 61 20 5d77 224 11:25:0 hft/ 0:30 /usr/lpp/X11/bin 4 2 1 /X c 0 250001 Z x18 11151 4490 0 60 20 0:00 <defunct> 240801 S root 11278 1 0 60 20 5d37 92 1daf4c Mar 10 - 4:48 /usr/lpp/monitor /loadavgd 2112 40001 S root 11792 1 0 60 20 1144 228 Mar 10 - 2:17 /usr/vice/etc/af sd -rmtsys 40001 S root 12049 1 0 23 20 1946 244 1db5d4 Mar 10 - 0:00 /usr/vice/etc/af sd -rmtsys 40001 S root 12306 1 0 23 20 2148 256 1db5d4 Mar 10 - 0:00 /usr/vice/etc/af sd -rmtsys 240801 S root 12567 2259 0 60 20 4551 112 1dae7c Mar 10 - 0:00 /etc/writesrv 240801 S x18 13460 7059 0 60 20 7c5f 124 11:25:5 pts/ 0:00 /bin/ksh 8 0 220801 S x18 13717 13460 0 60 20 2449 248 11:26:0 pts/ 0:05 telnet aix950a 3 0
Die verschiedenen Ausgabefelder bedeuten folgendes:
F systemintern benutzte Flags; z.B. bedeutet 000001, daß dieser Prozeß sich im Arbeitsspeicher befindet.
UID UID-Nummer des Prozeßeigentümers
PID Prozeßnummer des laufenden Prozesses
PPID Prozeßnummer des übergeordneten Prozesses (Parent Process IDentification)
C Scheduling-Parameter
PRI Priorität
NI Nice-Wert für die Prioritätenberechnung
ADDR Hauptspeicher oder Plattenadresse des Prozesses
SZ virtuelle Speichergröße des Prozesses
WCHAN Eventnummer, auf die der Prozeß wartet
S bezeichnet den Zustand des Prozesses
- O Der Prozeß existiert nicht.
- W Der Prozeß wartet auf ein Ereignis.
- I Der Prozeß ist in einem Zwischenzustand.
- T Der Prozeß wurde angehalten.
- S Der Prozeß wurde suspendiert.
- R Der Prozeß ist aktiv.
- Z Der Prozeß ist terminiert (Zombie).
- X Der Prozeß wächst.
TTY gibt das Peripheriegerät an, von dem aus der Prozeß gestartet wurde.
Ist an dieser Stelle ein Fragezeichen, so bedeutet dies, daß dieser Prozeß keinem Terminal zuzuordnen ist.
TIME bisher verbrauchte Rechenzeit
CMD Name des Kommandos, das den Prozeß gestartet hat
Die allgemeine Syntax für UNIX-Kommandos lautet:
kommando -optionen argumente
Jede Kommandoeingabe wird mit <Cr> abgeschlossen.
In einer UNIX-Kommandozeile stehen die Optionen zwischen dem Kommandonamen und den Hauptargumenten.
Wenn die Shell das erste Wort als einen Kommandonamen erkennt, d.h. ein Kommando mit diesem Namen findet, startet sie in der Regel einen Unterprozeß, in dem das Kommando ausgeführt wird. Wenn das Kommando seinerseits weitere Kommandos aufruft, werden weitere Unterprozesse generiert und ausgeführt.
Normalerweise wartet ein Prozeß, bis ein Unterprozeß abgeschlossen ist, bevor er weiterarbeitet. Der Unterprozeß gibt dem aufrufenden Prozeß einen Exit-status zurück. Dieses ist eine Zahl, die gleich 0 ist, falls das Kommando normal ausgeführt worden ist, ansonsten ungleich 0 sein kann. Der Exit-Status ist hauptsächlich für evtl. notwendige Fehlerbehandlung gedacht.
- eingebaute Systemkommandos
- sonstige Systemkommandos (Dienstprogramme)
- vom Anwender erstellte Prozeduren und Programme
Die eingebauten Systemkommandos werden bereits beim Aufruf der Shell in den Hauptspeicher geladen. Sie können daher sehr schnell ablaufen.
Eine vollständige Auflistung und Beschreibung der eingebauten Kommandos der Bourne-Shell findet man in der Dokumentation, die mit
man sh
zu erhalten ist.
Die sonstigen Systemkommandos befinden sich standardmäßig in den Verzeichnissen /bin und /usr/bin. Beim ersten Aufruf eines Kommandos muß die entsprechende Datei von der Platte geladen werden. Dokumentation zu den Systemkommandos erhält man mit
man kommando
Funktion: Liefert das Inhaltsverzeichnis des angegebenen Verzeichnisses (directory) Optionen:
-a alle Einträge, auch Dateien, die mit einem Punkt beginnen, werden angezeigt. -d ist die Datei ein Verzeichnis, so wird dessen Name, jedoch nicht sein Inhaltsverzeichnis ausgegeben. -l long format -s Dateigröße wird in Blöcken ausgegeben
Funktion: Das angegebene Verzeichnis wird zum Arbeitsverzeichnis gemacht. Bemerkung:
Ohne Parameter wird das Home-Verzeichnis zum Arbeitsverzeichnis. Mit cd .. wird in das darüberliegende Verzeichnis geschaltet.
Funktion: Der Name des aktuellen Verzeichnisses wird ausgegeben.
Funktion: Eines oder mehrere neue Verzeichnisse werden angelegt.
Optionen: keine Bemerkung:
Es werden die Standardzugriffsrechte vergeben. Besitzer ist der Anleger.
Funktion: Die angegebenen Kataloge werden gelöscht, falls sie leer sind.
Optionen: -r rekursives Löschen, es wird das Verzeichnis mitsamt seinen Unterverzeichnissen gelöscht. Bemerkung:
Das Löschen von Verzeichnissen ist nur dem Besitzer und dem Superuser erlaubt.
Funktion: Alle angegebenen Dateien werden gelöscht.
Optionen:
-f Dateien werden ohne Nachfrage auch dann gelöscht, wenn Schreibschutz besteht. -i Vor dem Löschen jeder Datei wird zurückgefragt. -r Es können auch Verzeichnisses angegeben werden. Die Verweise in dem Verzeichnis werden rekursiv gelöscht, zum Schluß das Verzeichnis selbst.Bemerkung:
Falls eine Schreibsperre besteht, wird vom System nachgefragt, sofern nicht die Option -f verwendet wurde. Löschen darf jeder Benutzer, der das Schreibrecht auf das Verzeichnis (directory) hat, in dem die Datei, die gelöscht werden soll, eingetragen ist. Die Zugriffsrechte auf die Datei selbst sind für das Löschen unerheblich.
Funktion: Der angegebenen Datei wird ein zusätzlicher Name gegeben, unter dem sie ansprechbar sein soll (Aliasname). Dieser Name kann in einem weiteren Verzeichnis eingetragen sein (Link-Funktion). Bemerkung:
Durch ln wird entweder ein Aliasname im gleichen Verzeichnis angelegt oder das hierarchische System durchbrochen, indem in einem anderen Verzeichnis ein Verweis auf die Datei eingetragen wird. Soll eine solche Datei später gelöscht werden, so muß dies in beiden Verzeichnissen geschehen, wenn die Löschung vollständig sein soll. Anderenfalls können irreführende Verweise zurückbleiben, die den Ablauf weitere Arbeiten behindern können.
Beispiele:
ln lq.script lq - lq.script erhält den Aliasnamen lq.
ln /v1/test /v2/test - Die Datei test ist von den Verzeichnissen v1 und v2 erreichbar.
2. cp [optionen] datei1 [datei2] [...] ... dir
Funktion: Die datei1 wird in datei2 kopiert.
Ist der letzte Name ein Verzeichnis, so werden alle angegebenen Dateien in dieses Verzeichnis kopiert.
Optionen: -r rekursiv
-p Das letzte Änderungsdatum wird beibehalten.
2. mv [optionen] dat1 [dat2] [...] ... dir
Funktion: Die Datei dat1 erhält einen neuen Namen dat2.
Bei der Angaben eines Verzeichnisses als letztes Argument werden die Verweise auf die Dateien gelöscht und im angegebenen Verzeichnis neu eingetragen.
Optionen: -f Das Kommando wird auch bei Schreibschutz von dat1 ohne Rückfrage ausgeführt.
Funktion: Ein Druckauftrag wird in die Warteschlange eingeordnet.
Optione n: -P queue Angabe einer Warteschlange
Für den Parameter queue in der Option -P sind am URZ folgende Angaben möglich:
queue ausgewählter Drucker Formular Charakteristik f3820 Laserdrucker 3820 weißes Papier zeilenorientiert f38um Laserdrucker 3820 Recyclingpapier zeilenorientiert f6890 Laserdrucker 6890 weißes Papier zeilenorientiert f68um Laserdrucker 6890 Recyclingpapier zeilenorientiert fdin4 Stahlbanddrucker 4245 DIN A4 weißes Papier zeilenorientiert fumd4 Stahlbanddrucker 4245 DIN A4 Recyclingpapier zeilenorientiert funli Stahlbanddrucker 4245 Tabellierpapier weiß zeilenorientiert fstd1 Stahlbanddrucker 4245 Tabellierpapier zeilenorientiert ps Laserdrucker QMS-PS1700 DIN A4 weißes Papier seitenorientiert Postscript psdup Laserdrucker QMS-PS1700 DIN A4 weißes Papier, seitenorientiert Postscript beidseitig bedruckt gl Laserdrucker QMS-PS1700 DIN A4 weißes Papier seitenorientiert HPGL-Sprache
Beispiel:
man sh > shell.man &
4711
Es wird die PID des Hintergrundprozesses ausgegeben. Es können jetzt sowohl weitere Hintergrundprozesse gestartet werden als auch mit interaktiven Kommandos, z.B. editieren, gearbeitet werden.
Für einen Hintergrundprozeß ist als Standardeingabe /dev/null voreingestellt. Das bewirkt, daß die Eingabe von der Tastatur zum aktuellen, interaktiven Prozeß und nicht zum Hintergrundprozeß geht. Die Voreinstellungen für die Standardausgabe und die Standardfehlerausgabe bleiben der Bildschirm. Dadurch kann durch Meldungen des Hintergrundprozesses die laufende Arbeit im Vordergrund gestört werden. Zur Vermeidung solcher Beeinträchtigungen lenkt man normalerweise die Standardausgabe um.
Mit dem Kommando ps kann man dann jederzeit erfahren, ob die gestarteten Prozesse noch laufen. Das ps-Kommando liefert vor allem die PID.
Soll ein laufender Hintergrundprozeß abgebrochen werden, so verwendet man das kill-Kommando:
kill -9 PID
Der Schalter -9 bewirkt einen sicheren Abbruch des Programmes. Durch Angabe mehrerer PID können mehrere Prozesse gleichzeitig abgebrochen werden. Jeder Benutzer kann natürlich nur seine eigenen Prozesse abbrechen.
Zum Beenden aller aktiven Prozesse muß Folgendes eingegeben werden:
kill -9 0
ed zeilenorientierter Editor
ex zeilenorientierter Editor (Obermenge von ed)
vi full-screen Editor
Auf den UNIX-Rechnern des Rechenzentrum werden noch einige weitere Editoren angeboten. Vorrangig zu nennen ist hier der Editor
emacs full-screen-Editor
Neben den reinen Editoren bietet UNIX Möglichkeiten zum Textformatieren mit den Programmen troff, roff, nroff, sowie etlichen zusätzlichen Post- und Präprozessoren und zahlreichen weiteren Tools, mit denen sich recht gut Textdateien bearbeiten lassen. Besonders erwähnenswert sind in diesem Zusammenhang die Interpreter sed und awk, die zwei mächtige Instrumente zur Manipulation von Textdateien darstellen.
Der Editor vi ist Bestandteil einer jeden UNIX-Installation. Darum empfiehlt das Rechenzentrum seinen Benutzern, welche in ansehbarer Zeit auch auf anderen Unix-Systemen arbeiten werden, sich zumindest mit den wichtigsten Befehlen dieses Editors vetraut zu machen.
Der Editor emacs kann kostenfrei eingesetzt werden und wird darum von vielen Installationen angeboten. Einige Kurse des Rechenzentrums setzen grundlegende Kenntnisse dieses Editors voraus.
An dieser Stelle sollen die Eigenschaften der hauptsächlich verwendeten Editoren im UNIX kurz diskutiert werden. Eine vollständige Funktionsbeschreibung der Editoren soll hier nicht erfolgen. Stattdessen wird auf separate Skripten bzw. im Buchhandel erhältliche Literatur verwiesen.
Der Editor ex arbeitet ebenso wie vi stets auf einer Kopie der zu bearbeitenden Datei, die im Arbeitsspeicher abgelegt ist. Diese Kopie muß zum Beenden der Editorsitzung explizit auf die Platte zurückgeschrieben werden.
ex [-r] [-R] [-v] datei
Die angegebenen Optionen bedeuten dabei:
-r ist die vorhergehende Sitzung abgebrochen worden, so kann man mit Hilfe dieser Option den größten Teil der durchgeführten Modifikationen wiedergewinnen. -R ex wird im Read-Only-Modus aufgerufen -v ex geht in den vi-modus
Beispiel:
ex daten.test
"daten.test" 71 lines, 4711 characters
:
Nach dem Aufruf zeigt der Editor den Namen der zu editierenden Datei und deren Länge in Zeilen und Zeichen an. Anschließend gibt er den Kommandoprompt, einen Doppelpunkt, aus und erwartet den ersten ex-Befehl. Immer wenn der Doppelpunkt erscheint, ist ex eingabebereit.
[bereich] kommando [ziel oder wiederholungsfaktor] [zusatz]
Erläuterungen zu den einzelnen möglichen Bestandteilen des ex-Kommandos:
Die Angabe bereich:
Jedes Kommando wirkt auf einen gewissen Bereich, der durch die Angabe von bereich festgelegt wird. Fehlt die Angabe von bereich, so bezieht sich das Kommando auf die aktuelle Zeile. Ist als Bereich eine Zahl angegeben, so wird das Kommando in der entsprechenden Zeile ausgeführt. Allgemein hat die Bereichsangabe folgende Form:
bereichsanfang,bereichsende
Die Felder bereichsanfang und bereichsende sind stets durch ein Komma zu trennen. Als bereichsanfang und bereichsende können eingesetzt werden:
n Zeilennummer n
/muster/ die Zeichenkette muster
$ die letzte Zeile der Datei
- die Zeile vor der aktuellen Zeile
. die aktuelle Zeile
% die gesamte Datei (äquivalent zu 1,$)
Beispiele:
6,36 steht für die Zeilen 6 bis 36
7,$ steht für die Zeile 7 bis zum Dateiende
.-3,.+1 steht für drei Zeilen vor bis eine nach der aktuellen Zeile
Die Angabe ziel oder wiederholungsfaktor:
Eine Zahl, die direkt hinter einem ex-Kommando geschrieben wird, gibt entweder die Zeile an, die geschrieben wird (ziel), oder wie oft der Befehl wiederholt ausgeführt werden soll (wiederholungsfaktor). Welche der beiden Möglichkeiten zutrifft, hängt vom ex-Befehl ab. In der Regel werden diese Zahlenangaben von schreibenden Kommandos als ziel interpretiert, von den anderen Befehlen als wiederholungsfaktor.
Die Angabe zusatz:
Diese Angabe ist nur bei manchen ex-Befehlen zulässig. Als zusatz kann angegeben werden:
# den Zeilen wird ihre Zeilennummer vorangestellt
p (print) die aktuellle Zeile wird nach der Ausführung angezeigt
l (list) wie p, allerdings in einem anderen Format
command mode Der "command mode" ist der Modus, in dem man ex-Befehle eingeben kann. Dieser Modus wird durch den Kommandoprompt : angezeigt.
insert mode In diesen Modus gelangt man vom "command mode" aus durch die Eingabe eines insert-, append- oder change-Kommandos. In diesem Modus wird kein Prompt angezeigt, alle Eingaben werden in diesem Modus in den Arbeitsspeicher (Puffer) geschrieben. Durch die Eingabe eines Punktes am Beginn eines neuen Zeile verläßt man den "insert mode", und der Kommandoprompt des "command mode" wird wieder angezeigt.
visual mode Dies ist der Editor vi (siehe nachfolgendes Kapitel).
open mode Dies ist ebenfalls der Editor vi, wobei allerdings nur jeweils eine Zeile angezeigt wird.
insert mode within visual mode or open mode
Innerhalb des vi und des "open mode" kann wiederum in einen "insert mode" geschaltet werden.
Von diesen Modi werden in diesem Kapitel nur die beiden ersten besprochen.
[zeile]a (append) versetzt ex in den Eingabemodus. Der Text wird nach der angegebenen Zeile eingefügt.
[bereich]c[n] (change) ersetzt die Zeilen des angegebenen Bereichs und die nächsten n Zeilen durch den nachfolgend eingegebenen Text. Der Editor ex geht dabei in den Eingabemodus.
[bereich]co zeile (copy) kopiert die Zeilen des angegebenen Bereichs hinter die angegebene Zeile.
[bereich]d[n][puf][zusatz] (delete) löscht die angegebene Zeile aus dem Puffer. Die erste nicht gelöschte Zeile wird die neue Arbeitsposition. Gibt man einen Hilfspuffer puf an, so wird der gelöschte Text dorthin gespeichert. Der Name des Puffers darf nur aus einem Zeichen bestehen.
e datei (edit) die genannte Datei wird editiert.
[zeile]i (insert) versetzt ex in den Eingabemodus. Der Text wird vor der angegebenen Zeile eingefügt.
[zeile]j[n][zusatz] (join) fügt die angegebenen Zeilen zu einer Zeile zusammen.
[bereich]l[n][zusatz] (list) gibt die Zeilen des angegebenen Bereichs aus.
[zeile]ma x (mark) setzt die Marke x auf die angegebene Zeile.
[bereich]m[n] (move) kopiert die Zeilen des angegebenen Bereichs an die Stelle nach der n-ten Zeile. Die alten Zeilen werden gelöscht. Die erste Zeile des neuen Bereichs wird die aktuelle Position.
o (open) ex geht in den open-Modus über.
[bereich]p[n] (print) gibt die Zeichen des angegebenen Bereichs aus. Nichtdruckbare Zeichen werden dabei durch ihre Kontrollzeichensymbole dargestellt.
[zeile]pu[put] (put) fügt die zuletzt gelöschten und im Hilfspuffer gesicherten Zeilen an der angegebenen Position ein.
q (quit) beendet ex, ohne den Text zu sichern. Wurde kein write ausgeführt, so gibt ex eine Warnung aus. In diesem Fall kann man ex mit q! verlassen.
[zeile]r[datei] (read) liest den Inhalt der angegebenen Datei und setzt diesen nach der angegebenen Zeile ein.
[bereich]s/text1/text2/[op][n][zs] (substitute) im angegebenen Bereich wird der jeweils erste Text, auf den das suchmuster text1 paßt, durch text2 ersetzt. Wird für op g angegeben, so werden alle passenden Textstücke der Zeilen ersetzt (sonst nur jeweils das erste in der Zeile vorkommende). Wird als op c gesetzt, so wird jede einzelne Ersetzung abgefragt und muß mit y oder n bestätigt werden.
se [parameter] (set) erlaubt das Setzen und Abfragen von Editoroperationen. Ohne Angabe von parameter werden die Werte aller Optionen ausgegeben.
u (undo) hebt die Änderung des letzten Editorkommandos wieder auf. Eine zweite Eingabe des undo-Kommandos hebt die Wirkung des ersten wieder auf!
[bereich]w[datei] (write) schreibt die Zeilen des angegebenen Bereichs in die angegebene Datei.
[bereich]w>>[datei] wie w, jedoch wird der Text an das Ende der angegebenen Datei angehängt.
[bereich]y[puf][n] (yank) die Zeilen des angegebenen Bereichs werden in den Hilfspuffer puf gesichert.
[bereich]!kommando kommando wird der Shell als Kommando übergeben und dort ausgeführt. Die Ausgabe des Kommandos ersetzt den Text des angegebenen Bereichs.
zeilennr. setzt die aktuelle Zeile auf die angegebene zeilennr.
/muster/ sucht, ausgehend von der aktuellen Zeile, nach einem Text, der auf das Muster paßt. Ist ein solcher Text gefunden, so wird die entsprechende Zeile zur aktuellen Zeile.
?muster? wie /muster/, die Suche erfolgt rückwärts.
Der Editor vi ist ein sogenannter Fullscreen-Editor. Er gibt also den Text seitenweise auf dem Bildschirm aus. Er ist tastaturunabhängig, indem er ausgiebig von der Ctrl-Taste, in der Regel aber nicht von Funktions- und Sondertasten Gebrauch macht.
Fullscreen-Editoren müssen den Typ des verwendeten Bildschirms bzw. der verwendeten Bildschirmemulation kennen, um arbeiten zu können. Darum muß darauf geachtet werden, daß die Umgebungsvariable TERM entsprechend eingestellt und exportiert worden ist. Über diese Variable TERM kann ein Fullscreen-Editor, also auch vi, erkennen, welche Eigenschaften das Terminal hat.
Der Editor arbeitet nicht direkt mit der Datei, sondern benutzt immer eine Kopie, um eventuelle Fehler oder Fehlbedienungen rückgängig machen zu können.
vi old.file
vi new.file
vi new.file old.file
vi
In der Kommandozeile kann bereits die zu editierende Datei angegeben werden.
a (append) - Text anhängen
i (insert) - Text einfügen
o (open) - neue Zeile einfügen
Diese Kommandos werden ohne <Cr> eingegeben.
Nach der Eingabe eines dieser Kommandos wird der einzufügende Text fortlaufend eingegeben.
Um den Einfügemodus zu verlassen, muß die <ESC>-Taste gedrückt werden. Der Cursor wird dann eine Spalte zurücklaufen und den vi in den Kommandomodus zurückschalten. Alle Kommandos werden durch die Eingabetaste (<Cr>) abgeschlossen.
:write oder :w
Der vi kopiert nach diesem Kommando seinen internen Puffer auf die von ihm angegebene Datei. Falls diese Datei noch nicht existieren sollte, zeigt dies der vi an mit dem Dateinamen, gefolgt von "NEW FILE" und der Anzahl der geschriebenen Zeichen. Der Puffer steht zur weiteren Arbeit unverändert zur Verfügung.
Falls der vi ohne Angabe eines Dateinamens aufgerufen worden ist, so kann er keine neue Datei anlegen. In diesem Falle muß das write-Kommando mit der Angabe eines Dateinamens aufgerufen werden:
:w dateiname
Dann wird der Puffer in eine Datei namens "dateiname" geschrieben.
Zum Verlassen des Editors gibt es mehrere Methoden. Falls der Text bereits zurückgeschrieben worden ist, genügt das Kommando
:q (quit)
Wenn der Text zurückgeschrieben werden und gleichzeitig vi verlassen werden soll, erfolgt dies durch eine der folgenden Eingaben:
:wx
oder :x
Eine dritte Möglichkeit zum Beenden mit Abspeichern besteht in der Betätigung der Tastenkombination <Shift-ZZ>.
Wenn der Editor verlassen werden soll, ohne die veränderten Daten zurückzuschrieben, so muß das Kommando
:q!
benutzt werden.
So kann mit folgendem Kommando direkt auf die 47. Zeile der Datei positioniert werden:
:47
Mit den Scroll-Befehlen kann man am Bildschirm durch die Datei blättern, ohne den Bildschirm neu aufbauen zu müssen:
<Ctrl-D> - Abwärts blättern (Down)
<Ctrl-U> - Aufwärts blättern (Up)
Wenn man nur einige Zeilen oberhalb oder unterhalb des Bildschirmfensters sehen möchte, so können Scroll-Befehle für zeilenweises Rollen eingegeben werden:
<Ctrl-E> - Eine Zeile abwärts
<Ctrl-Y> - Eine Zeile aufwärts
Durch seitenweises Blättern wird der Bildschirm gelöscht, und dann der Inhalt der nächsten bzw. zurückliegenden Seite angezeigt:
<Ctrl-F> - Seitenweise vorwärts (Forward)
<Ctrl-B> - Seitenweise rückwärts (Backward)
Auch innerhalb einer Zeile kann der Cursor zeichenweise oder wortweise bewegt werden. Wenn dem jeweiligen Befehl eine Zahl vorangestellt wird, so wird der angegebene Befehl entsprechend oft ausgeführt.
Folgende Kommandos können ausgeführt werden:
b Zum Beginn des vorherigen Wortes
e Zum Ende des nächsten Wortes
w Zum Beginn des nächsten Wortes
<BS> Cursor eine Position nach links (Backspace)
<LEER> Cursor eine Position nach rechts
Bei einigen Terminals können auch die Pfeiltasten zur Cursorbewegung verwendet werden. Dies ist aber nicht der Standard, sondern eine Funktionserweiterung.
Auch zum Wechsel der Zeile gibt es viele Kommandos:
j Cursor eine Zeile nach unten
k Cursor eine Zeile nach oben
<RETURN> Cursor auf die erste Position der nächsten Zeile
+ Cursor auf das erste Wort der nächsten Zeile
- Cursor auf das erste Wort der vorherigen Zeile
H Cursor auf die erste Zeile des Bildschirmes
M Cursor auf die Mitte des Bildschirmes
L Cursor auf die letzte Zeile des Bildschirmes
Eine andere Art der Textpositionierung ergibt sich, wenn der Editor nach einem bestimmten Suchmuster suchen muß. Um einen Text zu suchen, muß im Kommandomodus folgendes eingegeben werden:
/suchmuster/
Da es sich hierbei um ein Kommando handelt, wird dieses wieder mit der Eingabetaste (<Cr>) abgeschlossen.
Durch dieses Kommando wird ab der aktuellen Cursorposition das Suchmuster gesucht und der Cursor auf die gefundene Stelle positioniert. Wird das Suchmuster nicht gefunden, so erscheint der Text
pattern not found
auf der letzten Zeile des Bildschirmes.
Soll in der Datei rückwärts gesucht werden, so ist das Kommando folgendermaßen einzugeben:
?suchmuster\
Die Textmustersuche wird normalerweise, falls das Textmuster bis Dateiende nicht gefunden wurde, am Anfang der Datei fortgesetzt. Wenn nur bis zum Dateiende gesucht werden soll, kann dafür ein interner Schalter im vi gesetzt werden:
:set nowrapscan oder :set nows
Bei der Textsuche kann verhindert werden, daß der Editor zwischen Klein- und Großschreibung unterscheidet:
:set ignorecase oder :set ic
Das Kommando
:set noic
schaltet den vi wieder in den normalen Modus zurück.
Wenn die Textstelle, die der vi gefunden hat, noch nicht die gewünschte ist, so kann die Suche mit dem Kommando
n
wiederholt werden. Das n-Kommando funktioniert sowohl für das Rückwärts- als auch für das Vorwärtssuchen.
Der vi-Editor kennt einige Zeichen, die eine besondere Bedeutung innerhalb von Suchmustern besitzen. Mit ihnen kann man sich helfen, wenn man das gesuchte Wort nicht genau kennt. Diese Sonderzeichen stellen einen Platzhalter dar für nicht genau bekannte Zeichen.
Der Punkt "." steht dabei für ein beliebiges einzelnes Zeichen an der Stelle, an der es sich im Suchmuster befindet.
Für eine beliebige Anzahl sich wiederholender Zeichen wird der Stern "*" im Suchmuster verwendet. Das Zeichen, das wiederholt wird, steht vor dem Stern.
Emacs ist, wie auch vi, ein Editor, welcher mit den Buchstaben- und Zifferntasten sowie als Sondertasten mit den Tasten Ctrl und Esc auskommt. So ist Emacs unabhängig vom sonst herstelleranhängigen Tastaturlayout, andererseits ist so eine Vielzahl von verschiedenen Tastankombinationen definiert, welche nur schwer einprägbar sind. Im URZ ist eine Emacs-Version installiert, welche unter X-Window-Umgebung ablaufend den Vorteil der Menüsteuerung bietet. Alle wichtigen Grundfunktionen lassen sich mit der Maus über Menüs anklicken, so daß eigentlich kaum noch Tastenkombinationen benötigt werden, was besonders bei nur gelegentlicher Nutzung von großem Vorteil ist. Deshalb hat sich das URZ auch entschieden, Emacs in Einführungs- und Programmierkursen als Standardeditor einzusetzten.
Der Editor Emacs wird mit dem folgenden Kommando aufgerufen:
emacs [old.file] [argument]
In der Kommandozeile kann bereits die zu editierende Datei angegeben werden; es ist nur ein einziger Dateiname zulässig. Ist die Datei bereits vorhanden, so wird sie in den Hauptpuffer von emacs eingelesen. Außer einem Dateinamen kann in der Kommandozeile das Argument +n enthalten sein, wobei mit der Zahl n angegeben wird, in welcher Zeile emacs den Cursor unmittelbar nach dem Aufruf positionieren soll. Während einer emacs Sitzung können in weitere (maximal 12) emacs-Puffer zusätzliche Dateien eingelesen werden.
An einem X-Window-Terminal wird für Emacs ein neues Fenster eröffnet. Die Größe dieses Fensters kann auch während des Editierens verändert werden.
Am einfachsten verläßt man Emacs durch Anklicken des Menüpunktes "Exit Emacs" im Menü "Buffers". Es gibt aber auch zwei Kommandos, um emacs zu verlassen. Mit dem einen Kommando wird die Arbeit mit emacs temporär unterbrochen, mit dem anderen wird die Arbeit beendet.
<Ctrl-Z> die Arbeit wird unterbrochen
<Ctrl-X><Ctrl-C> die Puffer werden abgespeichert und der emacs- Prozeß wird beendet.
Emacs verfügt über eine eingebaute Dokumentation. Über das Menü "Help" oder die Tastenkombination <Ctrl-h> können Informationen über die Benutzung des Editors abgerufen werden.
In der ersten Zeile steht das Emacs-Hauptmenü. Es hat die vier Menüpunkte "Buffers", "File", "Edit" und "Help". Über den Menüpunkt "Buffers" kann zwischen mehreren Puffern hin-und hergeschaltet werden. So können mehrere Dateien gleichzeitig editiert werden, jede Datei belegt einen separaten Puffer. Immer angeboten wird ein Puffer namens "*scratch*". In diesem zunächst leeren Puffer können neue Daten einegeben werden. Das Arbeiten mit mehreren Puffer innerhalb einer einzigen emacs-Sitzung ist auch auf einem X-Window-Terminal dem statt dessen möglichen mehrmaligen mehrmaligen Aufruf von Emacs vorzuziehen, da das Kopieren und Verschieben von Daten zwischen den verschiedenen zu editierenden Dateien dann komfortabler ist.
Der zweite Menüpunkt "File" enthält alle Befehle zum Laden und Abspeichern von Dateien. Außerdem gibt es hierunter Befehle zum Verlassen von Emacs. Der Befehl "New Frame" eröffnet ein neues X-Window-Fenster mit einer zweiter Emacs-Siztung, was einem zweiten Emacs-Aufruf von der Shells aus gleichkommt.
Im dritten Menü sind alle Befehle zum Ausschneiden, Kopieren und Einfügen von Textblöcken zu finden. Diese Funktionen sind nicht zu verwechseln mit den Funktionen "Cut" und "Paste" der X11-Oberfläche. Hier werden vielmehr alle Ausgeschnittenen oder kopierten Textbereiche in einem Stapelpuffer abgelegt, aus dem dann vor Benutzung der Funkion "Paste" der gewünschte Textblock ausgewählt werden kann ("Choose Next Paste").
Der letzte, vierte Menüpunkt "Help" wurde oben bereits erwähnt.
Unter der Menüleiste gibt es ein Textfenster, das in der letzten Zeile eine Modusanzeige enthält und einen zusätzlichen sogenannten Echobereich. Das Textfenster kann sowohl horizontal als auch vertikal in mehrere Textfenster unterteilt werden. Das Fenster, in dem sich der Cursor befindet, ist das ausgewählte Fenster, in dem gearbeitet wird.
Jedes Textfenster hat als letzte Zeile seine eigene Modusanzeige, die beschreibt, was in diesem Fenster abläuft. Diese Zeile wird standardmäßig invers angezeigt.
Wenn mehrere Dateien gleichzeitig bearbeitet werden, so hat jede Datei ihre eigene aktuelle Position.
Wenn mehrere Textfenster geöffnet sind, so hat jedes Fenster seine eigene aktuelle Position.
Falls ein Kommando nicht ausgeführt werden kann, wird in diesem Bereich eine kurze Fehlermeldung angezeigt. Eine Fehlermeldung wird von einem akustischen Signal begleitet.
Einige Kommandos geben in dem Echobereich Informationsmeldungen aus. Diese Meldungen sehen Fehlermeldungen sehr ähnlich, werden aber nicht akustisch angemeldet.
Normalerweise hat die Moduszeile folgendes Aussehen:
--ch-Emacs: buf
(major minor)----pos------------------------------
Bedeutung der einzelnen Felder:
Das Feld ch beinhaltet zwei Sterne "**" wenn der Text modifiziert worden ist, "--" zeigen an, daß der Text unverändert ist und durch "%%" wird angezeigt, daß dieser Puffer nur gelesen werden kann.
Der Puffername des Textfensters wird für buf eingesetzt.
Durch pos wird angezeigt, ob weiterer Text oberhalb oder unterhalb der Begrenzungen des Bildschirmfensters vorhanden ist. Wenn die Datei klein ist und vollständig auf den Bildschirm paßt, so ist der Inhalt von pos "All". Anderenfalls wird "Top" eingesetzt, falls der Anfang der Datei angezeigt wird, oder "Bot", falls das Ende der Datei zu sehen ist. Bei einer Position in der Mitte einer Datei wird der Prozentanteil von der Datei angezeigt, der sich oberhalb der oberen Bildschirmbegrenzung befindet.
Das Feld major mode zeigt einen der sogenannten major modes an. Die verfügbaren Modi sind: Fundamental mode, Text mode, Lisp mode und C mode.
Das Feld minor mode zeigt eine Liste sog. minor modes an, die augenblicklich für dieses Textfenster eingeschaltet worden sind, so zeigt z.B. "Ovwrt" den eingeschalteten Überschreibmodus an.
Zu empfehlen ist neben einem deutschsprachigen Kurzskript des URZ (erhältlich im URZ in Zimmer 001) das Buch von D. Cameron und B. Rosenblatt mit dem Titel "Learning GNU emacs", welches auch in der Bibliothek des URZ unter der Signatur GH9101 zu finden ist.