Aufgabenblatt 2

Shell

Abgabe: 16.11.2006

Aufgabe 1

Entwickelt einen neuen Kommandointerpretierer, die My-Shell (msh).
My-Shell soll, wie gewohnt, das Laden und Ausführen von Programmen ermöglichen, z.B.

$ ls -l dir
Ferner soll My-Shell Elemente für Eingabeumlenkung (<), Ausgabeumlenkung (>) und maximal eine Pipe (|) bereitstellen:
$ cat file1 > file2
$ sort -u < file1
$ uniq file1 | more
Außerdem sollen Kommandos auch asynchron (&) gestartet werden können:
$ cat < longfile | sort > sortedfile &
Unterstützt alle möglichen Kombinationen von Umlenkung, Pipe und asynchroner Bearbeitung. Behandelt "unmögliche" Kombinationen als Fehler, z.B. die Ausgabeumlenkung am Anfang der Pipeline. Verwendet für die Implementierung soweit wie möglich dup2(2).

Aufgabe 2

Erweitert My-Shell um einen History-Mechanismus.
Dabei soll sich der Kommandointerpretierer die letzten 10 Kommandos merken. Durch die Eingabe des Kommandos history wird diese Liste von Kommandos, jeweils mit einer laufenden Nummer versehen, am Bildschirm angezeigt. Gibt man

$ !5
ein, so wird das Kommando mit der Nummer 5, sofern vorhanden, wiederholt. Die Eingabe von !! bewirkt die wiederholte Ausführung des letzten Kommandos, ohne Änderung der Kommando-Liste.

Aufgabe 3

Erweitert My-Shell um eine Unterstützung des aktuellen Arbeitsverzeichnisses.
Dabei soll sich das Arbeitsverzeichnis mit dem Kommando cd wechseln und mit pwd anzeigen lassen:

$ cd /home/bude/mustermann
$ pwd
/home/bude/mustermann
$ cd ../..
$ pwd
/home
Verwendet dazu chdir(2) und getcwd(3).

Aufgabe 4

Erweitert die Ausgabeumlenkung von My-Shell.
Dabei sollen nun beliebig viele Pipes unterstützt werden:

$ cat file | sort -r | uniq -c
Ferner sollen auch Fehlerausgaben eines Kommandos in eine Datei (>&) umgelenkt werden können:
$ cat file >& errorfile
Dies soll unabhängig von der normalen Ausgabeumlenkung geschehen und sinnvoll mit den Elementen aus Aufgabe 1 kombinierbar sein.

Hinweise

Ein- und Ausgabeumlenkungen in Dateien bzw. Pipes werden vom Kommandointerpretierer vorgenommen, nachdem ein fork-Systemaufruf abgesetzt wurde und bevor der Kindprozeß mittels exec ein neues Programm lädt.

Bei asynchron gestarteten Prozessen muß der Elternprozeß auf deren Terminieren reagieren, um ggf. bestimmte Aufräumarbeiten zu veranlassen. Um auf die Beendigung von Kindprozessen zu warten, verwendet man den Systemaufruf wait(2) bzw. waitpid(2). Durch den Systemaufruf signal(3) kann man sich benachrichtigen lassen, wenn bestimmte Ereignisse auftreten, und eine entsprechende Unterbrechungsbehandlung anstoßen. In unserem Fall ist das Signal SIGCHLD interessant, siehe signal(7). Sicherheitshalber empfiehlt es sich, vor Verwendung von signal zuerst das gewünschte Verhalten mittels siginterrupt(3) einzustellen.