Zurück zum Anfang
Die Shell ist die Benutzeroberfläche mitunter für Leute, die auf
Dauer an Reizüberflutung leiden und lieber Befehle eintippen, als
ständig mit der Maus auf dem Bildschirm herumzufahren. Außerdem
können durch Shell-Skripte (Also Befehlsdateien, die wie Programme
abgearbeitet werden) viele Vorgänge leicht automatisiert werden.
Aber auch bei Benutzung der p.OS-Shell müssen wir nicht auf
Drag&Drop und intuitive Bedienung verzichten. Befehle und
Dateinamen können durch Drag&Drop ins Shell-Fenster gezogen
werden, die Shell erlaubt es auch, abgekürzte Befehle und
Dateinamen einzutippen und erweitert diese automatisch.
Eine History-Funktion erlaubt das Blättern rückwärts durch die
vorher eingegebenen Befehle, die dann auch editiert werden können.
Außerdem steht noch eine Reihe von Tastaturabkürzungen zur
Verfügung.
Die Shell wird in einem sogenannten Console-Window geöffnet
(CON:), das die Ein- Ausgabeumgebung für die von der Shell
gestarteten Programme und die Shell selbst darstellt. Auch andere
Programme können das Gerät CON: für eigene Tastaturein- und
Ausgaben verwenden und profitieren damit genauso von den
erweiterten Funktionen wie Tastaturabkürzungen, Dateinamens- und
Befehlserweiterungen und der History-Funktion
Zunächst wieder eine kleine Kurzübersicht:
1.
Dateinamen- und Befehlserweiterung,
History
2.
Spezielle Eigenschaften des
Console-Fensters
3.
Umleitung der Standardein- und
-ausgabe
4.
Argumentschablonen
5.
Umgebungsvariablen
6.
Dateisystem
7.
Namensmuster
8.
Fehlerbehandlung
9.
Befehlsreferenz (alphabetisch)
Also, Öffnen wir einmal ein Shell-Fenster.
Dann geben wir einen Unvollständigen Befehlsnamen ein und drücken
die [TAB]-Taste. Falls der Teil des Befehls, den wir eingegeben
haben eindeutig ist, d.h. im Befehlspfad der Shell wird nur ein
Befehl gefunden, der mit den von uns eingegebenen Zeichen beginnt,
so wird ohne weiteres Zutun der Befehl vervollständigt.
Falls es jedoch mehrere Befehle gibt, die mit den von uns
angegebenen Buchstaben beginnen, öffnet sich ein kleines Fenster
mit einer Liste der passenden Befehle, aus der wir mit der Maus
den entsprechenden aussuchen können.
Für Dateinamen gilt das Ganze genauso.
Zurücknehmen läßt sich dies mit [Shift+TAB].
Mit der Tastenkombination [CTRL+C] kann die ausdrückliche
Erweiterung eines Befehls verlangt werden, [CTRL+D] erweitert nur
Verzeichnisnamen und [CTRL+F] nur Dateinamen.
Die History-Funktion ermöglicht es darüberhinaus, mit der Taste
[Cursor hoch] den zuletzt eingegebenen Befehl zu wiederholen und
zu editieren.
Siehe auch den Abschnitt "Spezielle Eigenschaften des Console-Fensters" für weitere Informationen
über diese Themen
Meist geben Shell-Befehle ihre Daten über die Standardausgabe aus
und erwarten Eingaben von der Standardeingabe.
Diese beiden Ströme kann man mit den Zeichen ">", "<", ">>" und
"<>" in Dateien oder andere Devices, wie zum Beispiel ein anderes
Ausgabefenster umleiten.
">" leitet die Ausgabe in die angegebene Datei um, die, falls sie
schon existiert, überschrieben wird.
">>" leitet auch in die angegebene Datei um, allerdings wird,
falls die Datei schon existiert, die Ausgabe des Befehls an die
schon existierende Datei angehängt. Falls sie noch nicht existiert
wird sie neu erzeugt.
"<" leitet die Eingabe "aus einer" Datei um, d.h. Wenn das
Programm eine Eingabe fordert, wird sie aus der angegebenen Datei
gelesen.
"<>" schließlich leitet sowoh Ein- als auch Ausgabe in die gleiche
Datei um
Besondere Dateien sind z.B. "CON:", damit wird die Ein/Ausgabe in
ein neues Fenster umgeleitet, oder "NIL:", das Nirwana der Daten:
Was nach NIL: umgeleitet wird, verschwindet einfach
Aufnimmerwiedersehen. Dies ist z.B. in Befehlsdateien wichtig,
oder auch, wenn man ein Programm in den Hintergrund starten möchte
und danach das Shell-Fenster schließen. Siehe hierzu auch den Run Befehl.
CON: bietet hier noch eine Reihe weiterer Möglichkeiten.
CON: kann nämlich noch Argumente Verarbeiten, die wie ein Pfadname
bei Laufwerken hinter den Gerätenamen gehängt werden können:
"CON:[LeftEdge]/[TopEdge]/[Width]/[Height]/[Title]/[Erw.]"
Optionale Erweiterungen (nach "Title"):
/CLOSE
Close-Gadget erzeugen, Kick auf CloseGadget
entspricht Ctrl-\
/AUTO
Window wird erst bei der ersten Ausgabe geöffnet
/WAIT
Window erhält ein Close-Gadget und muß manuell
geschlossen werden
/INACTIVE
Window wird beim Öffnet nicht aktiviert
/NOSIZE
Window erhält kein Size-Gadget
/NODRAG
Window kann mit der Maus nicht verschoben werden
/NODEPTH
Window erhält kein Tiefen-Gadget
/NOBORDER
Window ohne Border öffnen (und ohne System-Gadgets)
/NOSLIDER
Window erhält keinen Slider (Schieber)
/LINES
Anzahl der zu puffernden Zeilen definieren, z.B.
/LINES 800 => 800-Zeilen werden gepuffert
/FONT
Legt den Window-Font fest, z.B. /FONT topaz,11:
als Font wird der 'topaz.font' mit einer Höhe von
'11' verwendet, konnte der Font nicht geöffnet
werden, wird der Screen-Font verwendet. Der Font
darf kein Proportional-Font sein.
/SCREEN
Public-Screen, auf dem das Window geöffnet werden
soll.
/TAB
Schaltet die spezielle CON-Erweiterung ein.
/READONLY
Die Console erlaubt nur Ausgabe aber keine Eingabe.
Dann gibt es noch einige Tastaturabkürzungen:
Während der Ausführung von Kommandos dienen die Kombinationen
[Ctrl+C],[Ctrl+D], [Ctrl+E] und [Ctrl+F] als Prozess-Signale, d.h.
Dem laufenden Programm wird ein Signal mit einer bestimmten
Bedeutung geschickt, und zwar bedeuten die einzelnen Signale
folgendes:
C - bricht den aktuell laufenden Befehl ab
D - bricht das aktuelle Skript ab
E/F - kann vom Kommando frei interpretiert werden
Während der Eingabe über die Kommandozeile sind folgende
Tastenkombinationen verfügbar:
Ctrl-X
Zeile löschen
Ctrl-S
Anzeige stoppen/schrittweise weiterschalten
Ctrl-Q
gestoppte Anzeige wieder freigeben
Ctrl-\
EOF bzw. ^C + ^D erzeugen
Ctrl-Z
Zip Window, Fenstergröße minimal/maximal umschalten
Backspace
Zeichen links vom Cursor löschen
DEL
Zeichen unterm Cursor löschen
Cursor-Left
Cursor nach links bewegen
Cursor-Right
Cursor nach rechts bewegen
Cursor-Up
History-Puffer zurückfahren
Cursor-Down
History-Puffer vorfahren
Shift-Cur-Left
Cursor an den Zeilenanfang
Shift-Cur-Right
Cursor an das Zeilenende
Shift-Cur-Up
History-Puffer nach Muster durchsuchen
Tab
Pfad aufbauen (erweitern)
Shift-Tab
Pfad zurücknehmen
Ctrl-C
Befehlsnamen erweitern
Ctrl-F
Dateinamen erweitern
Ctrl-D
Verzeichnisnamen erweitern
An eine Befehl werden normalerweise auch Argumente übergeben. Um
eindeutig klarzumachen, welche und auf welche Art und Weise ein
Befehl Argumente aktzeptiert, gibt es die Argumentschablonen, die
im folgenden auch bei der Beschreibung der einzelnen Befehle
verwendet werden.
Unter p.OS können die Argumente nicht nur von der Kommandozeile
gelesen werden, sondern auch aus externen Konfigurationsdateien
oder Shell-Variablen, ja auch aus den
Programmen (Befehlen) selbst werden Start-Argumente gelesen. Zur
Speicherung von Default-Argumenten in Shell-Variablen siehe
Abschnitt Umgebungsvariablen.
Abgesehen von den eigentlichen Argumenten gibt es noch
Shell-Optionen, die zusätzlich zu den Argumenten angegeben werden
können. Eine Kommandozeile sieht demnach in der p.OS-Shell so aus:
Die Shell-Optionen müssen immer in "{}" eingeschlossen werden. Es
können mehrere angegeben werden, die dann durch Komma getrennt
oder direkt nebeneinander übergeben werden müssen. Folgende
Optionen stehen zur Verfügung:
{^}
Listet die Argumentzuweisung auf
{%}
Liest die Argumente von Standard-IN, z.B. dir {%}
{!}
Default-Argumente werden nicht berücksichtigt
{?}
Liste der Optionen ausgeben
{*}
Zeigt nur die Argumentschablone an, ohne daß nach
dem Anzeigen zur Eingabe aufgefordert wird.
Beispiel: dir {^%} wartet, bis ein Argument
eingegeben wurde, gibt dies nochmals aus und zeigt dann erst das
eingegebene Verzeichnis an.
Ja, schön, aber was um alles in der Welt soll das nun wieder
nützen?
Dies ist vor allem in Skripts nützlich. Z.B. kann so der Benutzer
Argumente für einen im Skript vorhandenen Befehl selbst eingeben,
ohne daß irgendeine Eingabefunktion o.ä. benötigt wird (mit "%").
Außerdem kann dann (mit der "^"-Option) gleich kontrolliert
werden, ob auch alle Argumente richtig eingegeben wurden.
Beispiel:
; Das interaktive Verzeichnislister-Skript
echo "Welches Verzeichnis wollen Sie angezeigt haben?"
dir {%}
; Hier ist das Skript aus
Kommen wir aber jetzt zu den Argumenten selbst.
Jedes Argument hat ein Schlüsselwort, das von einem optionalen,
durch einen Slash("/") vom Schlüsselwort getrennten Bezeichner
gefolgt werden kann.
Wenn in der Schablone ein Gleichheitszeichen vorkommt, dann kann
sowohl das Schlüsselwort vor- als auch das nach dem
Gleicheitszeichen synonym verwendet werden. Diese Möglichkeit wird
oft bei Befehlen verwendet, die die Angabe von Argumenten mit dem
dazugehörigen Schlüsselwort erwarten. Weil diese normalerweise
sehr lang sind, damit man auch weiß, was gemeint ist, können so
auch Abkürzungen verwendet werden.
Durch Eintippen eines Befehls mit einem "?" als Argument wird die
Argumentschablone dieses Befehls ausgegeben und die Argumente
können interaktiv eingegeben werden (im Gegensatz zur
"*"-Shell-Option, siehe oben). Die Angabe von "??" gibt einen
kurzen Hilfetext zum Programmaus, sofern einer definiert ist.
Leider haben im Moment viele Shell-Programme noch keinen
Hilfetext.
Um Argumente an ein Programm zu übergeben gibt es dann
verschiedene Möglichkeiten:
Die Schlüsselwörter aus der Argumentschablone können mit angegeben
werden, um zu verdeutlichen, welches Argument gemeint ist, etwa
so:
3.pOS:pOS.0[0]> dir DIR MeinDir
Oder auch so:
3.pOS:pOS.0[0]> dir DIR=MeinDir
Wo dies nicht ausdrücklich gefordert ist, kann man auch die
Schlüsselworte weglassen. Allerdings muß dann auf die Reihenfolge
der Argumente geachtet werden. Also so:
3.pOS:pOS.0[0]> dir MeinDir
Falls ein Argument Leerzeichen enthält, muß es in
Anführungszeichen gesetzt werden, damit es als ein Argument
erkannt wird. So:
3.pOS:pOS.0[0]> dir "Mein Dir"
Die geschwätzigste Methode wäre demnach:
3.pOS:pOS.0[0]> dir DIR="Mein Dir"
Die Bezeichner in der Schablone haben dabei die folgenden
Bedeutungen:
/S
Das Schlüsselwort bezeichnet eine Schalter-Option.
Wenn das Argument, das in diesem Fall dem
Schlüsselwort entspricht, angegeben wird, wird eine
Option des Befehls aktiviert. Unter p.OS kann auch
ganz explizit so ein Schalter ein- bzw.
ausgeschaltet werden.
Etwa so: dir all=on oder auch
dir all=1, das Gegenteil davon wäre dann:
dir all=off oder dir
all=0.
Außer zur besseren Lesbarkeit in
Konfigurationsdateien hat das ganze noch einen
anderen Sinn, der im Abschnitt Shell-Variablen erklärt wird.
/K
Das Schlüsselwort muß mit angegeben werden, wenn das
Argument verwendet wird
/N
Das Argument muß einen numerischen Wert haben.
/A
Das Argument muß immer angegeben werden.
/M
Das Argument kann auch mehrmals angegeben werden.
/K
Das Schlüsselwort muß mit dem Wert des Arguments
angegeben werden.
/F
Das Argument muß als letztes angegeben werden. Alles
was ab hier in der Befehlszeile steht, wird als ein
einziges Argument betrachtet. Dies ermöglicht z.B.
Strings als Argument zu übergeben, die Leerzeichen
und andere Sonderzeichen enthalten.
Die p.OS-Shell kennt zwei Arten von Variablen: lokale und globale.
Lokale Variablen sind nur innerhalb des Shell-Prozesses gültig, in
dem sie definiert wurden, globale dagegen gelten in allen
Ausführungsumgebungen von p.OS. Variablen werden durch den
Shell-Befehl Set Werte zugewiesen und durch Get
können die Werte ausgegeben werden.
Die Variablen werden als Dateien in den Verzeichnissen ENV: und
ENVARC: gespeichert. Siehe auch: Set-Kommando.
Eine Shell-Variable wird durch voranstellen eines Dollarzeichens
($) dereferenziert, das heißt, dort wo ein Dollarzeichen gefolgt
von einem Variablennamen steht wird der Wert der Variablen
eingesetzt. Im Grunde ließen sich so auch Befehlsmakros
definieren, dies sollte aber besser mit dem Befehl Alias geschehen.
Die Werte von Variablen sind immer Zeichenketten.
Shell-Variablen für Default-Argumente von Befehlen
Unter p.OS können die Befehle auch Standard-Argumente aus
Variablen einlesen. Diese Variablen sind im Verzeichnis ENV:shell
(bzw. EnvArc:shell) gespeichert. Wir möchten jetzt zum Beispiel,
daß beim Aufruf des DIR-Befehls automatisch alle
Unterverzeichnisse mitangezeigt werden, ohne daß wir jedesmal
"ALL" angeben müssen:
SET shell/DIR ALL
Wenn wir danach ein Verzeichnis ohne seine Unterverzeichnisse
anzeigen lassen wollen, müssen wir folgendermaßen vorgehen:
dir ALL=OFF
Jetzt wird auch der Sinn des expliziten Aus- und Einschaltens von
Schalterargumenten klar. Darüberhinaus könnten wir auch die
Shell-Option "{!}" verwenden, die die Verwendung von
Default-Argumenten unterdrückt.
Das momentane Dateisystem von p.OS ist weitgehend mit dem AmigaOS
FastFileSystem kompatibel - wobei bisher Hardlinks nur gelesen
werden können und Softlinks gar nicht unterstützt werden. Auch auf
die Multiuser-Fähigkeit müssen wir noch etwas warten.
Ein Dateiname kann also bis zu 34 Zeichen enthalten, wobei
eigentlich jedes Zeichen darin vorkommen darf.
Nicht zu empfehlen ist es allerdings, Sonderzeichen zu verwenden,
die als Namensmuster schon eine spezielle
Bedeutung haben. Wenn ein Dateiname Lerrzeichen enthält, muß er an
einen Befehl als in Anführungszeichen eingeschlossenes Argument
übergeben werden.
Namen von Geräten und Datenträgern werden unterschieden: Zum einen
gibt es den DOS-Device-Namen, der z.B. beim Mount-Befehl
angegeben werden muß. Dieser bezieht sich auf das Gerät an sich und dient dem
Betriebssystem zur Unterscheidung der verfügbaren Geräte. Er kann vom Benutzer
nicht ohne weiteres geändert werden. Im Gegensatz dazu gibt es
noch den Datenträgernamen (Volume Label). Er kann vom Benutzer
frei gewählt werden und ermöglicht es, aussagekräftige Namen für
Datenträger zu vergeben. Bei Diskettenlaufwerken wird der
Unterschied ziemlich deutlich: Eine ins Laufwerk "df0:" eingelegte
Diskette wird immer unter dem Gerätenamen "df0:" angesprochen. Der
Datenträgername kann jedoch bei jeder Diskette verschieden sein.
Zu jeder Datei wird das Erstellungsdatum, die Uhrzeit, 8
Schutzbits und wahlweise ein Kommentar gespeichert.
Die Schutzbits haben folgende Bedeutung (siehe auch Befehle List und Protect):
s
Die Datei ist ein Skript und kann ohne den Befehl Execute ausgeführt werden
p
Diese Datei ist ein "pures" ausführbares Programm,
d.h. es ist Multitasking-reentrant und reexecutable
und kann daher mit dem Befehl Resident speicherresident
gemacht werden
a
Die Datei wurde archiviert. Viele Backup- und
Archivierungsprogramme benutzen dieses Bit, um zu
bestimmen, welche Dateien bereits archiviert wurden,
so daß bei einem späteren Archivierungsvorgang diese
Dateien nicht mehr gelesen werden müssen
r
Die Datei kann gelesen werden
w
In die Datei kann geschrieben werden
e
Die Datei kann ausgeführt werden (Nur bei Programmen
sinnvoll)
d
Die Datei kann gelöscht werden
Die meisten Befehle aktzeptieren als Argument, in dem ein
Dateiname oder ein Pfadname angegeben werden muß auch ein
Namensmuster, das aus sog. Wildcards besteht, also Zeichen, die
für mehrere Zeichenfolge stehen, besteht. Folgende Wildcards ("w"
ist ein belibiges Wildcard-Zeichen) stehen zur Verfügung:
?
Steht für ein beliebiges einzelnes Zeichen
#w
Wiederholt die danach stehende Wildcard, d.h. #?
bedeutet z.B.: "0 bis n beliebige einzelne Zeichen",
was bei Dateinamen auch dem Begriff "alle"
entspricht.
w1|w2
Steht für alle Zeichenketten, die entweder durch w1
oder durch w2 definiert sind
~w
steht für alles, was nicht durch w defininiert ist
(w1 w2 ...)
steht für alles, was durch w1 und w2 und ...
definiert ist
%
steht für eine leere Zeichenfolge
[-]
Steht für alle Zeichen, die im Bereich zwischen
und stehen (alphabetisch bzw.
im ASCII-Code)
Es kommt natürlich ziemlich oft vor, daß ein Programm nicht so
ausgeführt werden kann, wie es ursprünglich vorgesehen war. Sei
es, daß falsche Argumente übergeben wurden, eine angegebene Datei
nicht gefunden wurde oder was auch immer. Der Benutzer bekommt in
so einem Fall eine Fehlermeldung über die Standard-Fehlerausgabe.
Was aber tun, wenn ein Programm einen Fehler verursacht, das nicht
interaktiv über die Shell gestartet wurde, sondern beispielsweise
aus einem Skript heraus? Soll das Skript dann einfach abgebrochen
werden? Soll es mit evtl. Fehlerhaften Daten weiterarbeiten? Soll
eine Fehlermeldung ausgegeben werden oder nicht?
Die Antwort auf all diese Fragen ist die Fehlercodierung der
Shell.
Nach der Ausführung eines Programms gibt das Programm einen
bestimmten Zahlenwert, den Fehlercode, an die Shell zurück. Tritt
überhaupt kein Fehler auf, liegt dieser Wert zwischen 0 und 4 (NO
ERROR).
Manche Fehler bedingen nicht notwendigerweise, daß das Programm
abgebrochen wird. In so einem Fall gibt das Programm einen Wert
zwischen 4 und 7 Zurück (WARN) um die Umgebung (das Skript) darauf
hinzuweisen, daß das Programm möglicherweise nicht vollständig
korrekt ausgeführt wurde, aber dennoch nicht abgebrochen werden
mußte.
Bei anderen Fehlern muß das Programm abgebrochen werden und die
ausführende Umgebung (das Skript) muß dies erfahren, was aber
nicht unbedingt heißt, daß unser Skript deshalb auch abgebrochen
werden muß. Einerseits wäre da der Spezialfall, daß das Programm
durch den Benutzer unterbrochen wurde, was einen Fehlercode von 8
(ABORT) zur folge hat. Falls das Programm intern einen
"nicht-fatalen" Fehler erkennt, wird dieser Zustand durch einen
Wert zwischen 9 und 19 (ERROR) gekennzeichnet.
Falls ein Fehler aufgetreten ist, der die weitere Ausführung des
aufrufenden Skripts (oder was auch immer das Programm aufgerufen
hat) unmöglich macht ("fataler" Fehler), wird ein Wert ab 20 und
höher (FAIL) zurückgegeben.
Bei der Ausführung eines Skripts prüft die p.OS-Shell nach jedem
Befehl, der ausgeführt wurde, seinen Rückgabewert und bricht das
Skript ab, falls der Wert größer als ERROR (10) ist.
Mit dem Befehl FailAt kann dieses Verhalten
beeinflußt werden. Der Grenzwert für den Abbruch eines Skripts
kann beispielsweise hochgeschraubt werden, um danach mit
IF WARN, IF ERROR oder IF FAIL den Fehler quasi von
Hand abzufangen.
Befehlsreferenz