\documentclass[10pt,austrian]{article}
\usepackage[latin1]{inputenc}
\usepackage{a4}
\pagestyle{plain}

\textwidth16cm
\parindent0em
\parskip1.5ex plus 0.5ex minus 0.5ex
\renewcommand{\baselinestretch}{1.2}

\newcommand{\3}{\ss}

\begin{document}
\section{Herkunft und Eigenschaften von Linux}
\subsection{Einleitung}
Eigenschaften:
\begin{itemize}
\item echtes 32-bit Betriebssystem
\item UNIX-ähnlich
\item POSIX-konform
\item enthält keinen Original-UNIX-Code
\end{itemize}
Anfangs der $70^{er}$ entstand das 1. UNIX in den AT\&T Bell-Laboratories;
Ziel war relativ kleine Maschinen effektiv zu nützen; multi-user-Betrieb;
Ende der $70^{er}$ gab es 3 UNIX-Hauptlinien:
\begin{itemize}
\item AT\&T-UNIX
\item PC-UNIX (Microsoft-Lizenz)
\item BSD-UNIX (University of Berkeley)
\end{itemize}
Nachdem die UNIX-Lizenzen drastisch verteuert wurden entstanden UNIX-look-alike
Systeme z.B.: Coherent, MINIX von J.~Tanenbaum (microkernel-System).
Krieg der verschiedenen UNIX-Systeme; Standardisierungsversuche;
POSIX-Standard (Portable Operating System for Computer Environments) von IEEE;
Benutzerschnittstelle: X-Windows ist das kostenlose Kernsystem worauf
unterschiedliche Oberflächen aufbauen;

\subsection{Aufgaben eines Betriebssystems}
Shells wandeln die Benutzerbefehle in die entsprechenden Aufrufe von
Systemdiensten um.

\subsubsection*{Technische Voraussetzungen}
\begin{description}
\item[Interruptsystem]
\item[Timer Interrupt] Vermeidung, daß 1 Anwendungsprogramm alle anderen
Anwendungsprogramme und das Betriebssystem blockiert;
\item[Privilegienstufen] ab Intel 386 gibt es 4 Privilegienstufen ``Ringe''
wobei die höchste Prioritätsstufe Nr.~0, der Kernel-Modus ist (z.B.:
Speicheroperationen, Gerätezugriff);
\item[Virtuelle Speicherverwaltung] der von einem Anwendungsprogramm benötigte
Speicherplatz muß im Hauptspeicher nicht zusammenhängend sein;\\
Speicherauslagerungen:
\begin{description}
\item[Swapping] ganze Programme werden auf die HD ausgelagert;
\item[Paging] Teile eines Programms werden auf die HD ausgelagert;
\end{description}
\end{description}

\subsubsection*{Die LINUX-Lösung}
\paragraph{Resource Rechenzeit: }
Jedes aktive Programm wird in einem Prozeß ausgeführt, der relativ zu den
anderen Prozessen eine gewisse Priorität hat $\Rightarrow$ Warteschlange.
Ein {\em Alterungszähler} erhöht im Laufe der Zeit die Priorität eines
wartenden Prozesses, sodaß er nicht ewig von höherprioren  überholt wird.
Mittels der {\em Zeitscheibe} wird überwacht, daß jeder Anwendungs- oder
Betriebssystem-Prozeß nur eine maximal zulässige Zeit ungestört die CPU in
Beschlag nimmt, nach Ablauf dieser Zeitscheibe wird überprüft welcher Prozeß
als nächster dran kommt. Läuft ein Prozeß gerade auf der CPU so ist sein
Status: Running, ist er in der Warteschlange, so ist sein Status: Active.
\paragraph{Speicherverwaltung: }
Jede Operation, die in die Hauptspeicherverwaltung eingreift (z.B.: in einen
Speicherbereich adressieren) ist ein privilegierter Befehl $\Rightarrow$
Aktivierung des Betriebssystems. Bei einem illegalen Zugriff wird der
schuldige Prozeß abgebrochen, eine Fehlermeldung ``bus error'' oder ``memory
fault'' abgesetzt und der Hauptspeicherausdruck in eine Datei namens core
geschrieben.

\subsection{Prozesse}
Vereinfacht besteht ein Prozeß aus:
\begin{itemize}
\item Verwaltungsdaten
\item dynamischer Bereich: Speicherbereich für Laufzeitstack;\\
dynamische Speicherverwaltung des Programms auf heap;
\item Programm-code und -Daten (statischer Teil eines Prozesses)
\end{itemize}

\subsubsection*{Prozeßbaum}
Prozeß Nr.~0 hat als einziger keinen Vorgängerprozeß; er entsteht beim booten;\\
Prozeß Nr.~1 -- Init-Prozeß:
\begin{itemize}
\item Start gewisser Systemdienste gemäß /etc/inittab und der rc-Dateien im
Verzeichnis /etc;
\item Systemanmeldung (über Konsole oder serielle Leitung) mit dem
Getty-Prozeß;
\item Anmeldeshell;
\end{itemize}
Bei Beenden des Anmeldeprozesses werden, falls man dagegen keine Vorkehrungen
getroffen hat, alle Kind- und Enkelprozesse mit-beendet. Danach startet init
einen neuen Getty-Prozeß. Die Prozeßhierarchie wird unter dem Verzeichnis
/proc verwaltet.
\begin{description}
\item[Waisen] Wird ein (Eltern-) Prozeß, der noch von ihm abstammende(Kind-)
Prozesse laufen hat, beendet, so werden diese Kindprozesse $\Rightarrow$
Waisen vom Prozeß~Nr.~1 adoptiert.
\item[Zombies] Jeder Prozeß liefert bei seiner Beendigung noch einige Daten
an seinen Elternprozeß. Es werden zwar der Hauptspeicher und ein Großteil
der Verwaltungstabellen freigegeben, aber nicht alle, bis das der Eltern- oder
Adoptivprozeß erledigt. In der Zwischenzeit existiert der Prozeß als Zombie
(Prozeßstatus Z nach Aufruf der Prozeßtabelle mit ps).
\item[Dämonen] Systemprozesse, die im Hintergrund laufen, d.h. sie haben
keinen Ausgabeterminal (z.B.: Init-, Drucker-, Netzwerkprozesse)
(Terminalangabe ? bei Aufruf der Prozeßtabelle mit ps).
\end{description}

\subsection{Dateisystem}
Festplatte vor der Installation von Linux in virtuelle Laufwerke und die
swap-partition von Linux (eigenes Format) partitionieren.

Linux unterstützt viele verschiedene Dateiformate (z.B.: ext2, MSDOS,
ISO~9660 (CD-Roms)).

Das jeweilige Dateisystem mit mkfs auf die jeweilige Partition bringen.

\subsubsection*{Aufbau eines UNIX-/Linux-Dateisystems}
\begin{description}
\item[bootblock] enthält den boot-loader zumindest wenn es die Wurzelpartition
ist;
\item[superblock] enthält Infos über Partition und Dateisystem; beim mounten
liest Linux den superblock; Änderungen werden bis zum unmounten (umount),
sync oder Herunterfahren des Betriebssystems nur in der Kopie im Hauptspeicher
gemacht;
\item[Inode-Liste] enthält Infos über Dateien;
\item[Datenblöcke] enthalten die Daten selber und die Verweise von den Inodes
zu ihnen;
\end{description}

\subsubsection*{Dateihierarchie}
Die Dateihierarchie ist baumförmig abgesehen von den Links (Sprünge quer durch
den Baum);
\begin{description}
\item[Verzeichnis /proc:] Prozeßverwaltung: Die Inodes in diesem Dateibaum werden
zur Verwaltung der Prozeßhierarchie und der zu den Prozessen gehörenden
Speicherbereiche und Verwaltungsinformationen genutzt.
\item[Verzeichnis /dev:] Einträge der Geräte und Resourcen;\\
ls -l gibt bei der
\begin{itemize}
\item Typangabe an:
\begin{description}
\item[b] blockorientiertes Gerät
\item[c] zeichenorientiertes Gerät
\end{description}
\item statt der Dateigröße die device number (major-device-nr.,
minor-device-nr.) an:
\begin{description}
\item[major-device-nr.] Gerätetreiber
\item[minor-device-nr.] I/O-port, spezielle Funktionalität, ...
\end{description}
\end{itemize}
\end{description}

\subsubsection*{Inode}
wichtigste Verwaltungsstruktur für Dateien; 64 Bytes groß;\\
2 Teile:\\
\begin{description}
\item[Informationsteil] Inhalt: Kennung des users, der group, Rechtemaske,
Dateigröße, Dateityp, verschiedene Zeitmarken, Link-count;
\item[Verweisteil]
\begin{itemize}
\item Adressen der zur Datei gehörenden Datenblocks (indirekt adressiert);
\item bei Geräteknoten: major-device-nr., minor-device-nr.;
\end{itemize}
\end{description}

Das Programm fsck versucht beim Wiederhochfahren nach einem Stromausfall bzw.
Systemabsturz die Inode-Einträge und Superblöcke wiederherzustellen
(Datenverlust möglich);

\section{Installation von Linux}
\begin{description}
\item[fdisk] Platte partitionieren;
\item[mkfs] als Linux-Partition formatieren;
\item[zusätzliche Festplatten] partitionieren, formatieren und Einträge in die
Datei /etc/fstab (Gerätenamen, Anbindungspunkt im Verzeichnissystem, Art der
Einbindung);
\item[df --hT] (diplay filesystem); Anzeige der Art des filesystems der Größe,
der Größe des noch freien Platzes und des mount points.
\item[du] (disk usage); Zeigt die Größe des Arguments und seiner
subdirektories in kB an.
\item[fsck] (filesystem check) Es können entweder die device names oder die
mount points angegeben werden.
\item[Erstellen einer Bootdiskette] cat $\backslash$vmlinuz $>$
$\backslash$dev$\backslash$fd0 
\end{description}

\section{Tour durch Linux}
\begin{description}
\item[Virtuelle Konsolen:] hin- und herschalten zwischen ihnen mit Alt--Fx
oder Strg--Alt--Fx, Fx $\in$ [F1, {\ldots}, F12];
\item[.bash\_profile:] Diese Datei enthält die Anweisungen zur Konfiguration
(Voreinstellung) der Shell;
\end{description}

\subsubsection*{Shell}
In die Shell eingebaute Kommandos werden direkt augeführt, sonst wird in
einer Variable PATH, nach den möglichen Pfaden der externen Kommandos
nachgesehen; externe Kommandos laufen jeweils in einem eigenen von der Shell
gestarteten Prozeß;

\subsubsection*{/etc/passwd -- Benutzerdatenbank}
Diese Datei stellt die Benutzerdatenbank dar;
Aufbau einer Zeile dieser Datei: username: verschlüsseltes password: UID: GID:
Kommentar: home\_dir: login\_program\\
\begin{description}
\item[UID] user identification number; UID~0 ist dem superuser vorbehalten;
\item[GID] group-ID; Zugehörigkeit zu einer in der Gruppendatei definierten
Gruppe;\\
Aufbau einer Zeile der Gruppendatei /etc/group:\\
groupname: leere Spalte; ursprünglich für Gruppenkennwort vorgesehen:
Mitgliedsliste (Mitglieder durch Kommas getrennt)\\
\begin{description}
\item[newgroup] Befehl zum Ändern der Gruppenzugehörigkeit;
\item[passwd] Befehl zum Ändern des eigenen Passworts; wärend dieses Programmlaufes
wird dem Benutzer mithilfe des Set-UID-Bits für die Dauer des Programmlaufes
praktisch das superuser-Recht zugeteilt $\Rightarrow$ er kann sein eigenes
Passwort ändern;
\end{description}
\item[Kommentar] enthält meist Raumnummer, Tel.Nr. bzw. Klappe;
\item[home\_dir] Verzeichnis in dem sich der user nach dem login automatisch
befindet; dieser Eintrag ist unbedingt erforderlich;
\end{description}

\subsubsection*{Identitätswechsel mit su}
remote als superuser einloggen ist nicht erlaubt;\\
\begin{description}
\item[su {\it new\_username}] (substitute user): Befehl um die eigene
Identität zu wechseln;
\item[exit] Befehl um wieder zur ursprünglichen Identität zurückzuwechseln;
\end{description}

Für schizofrene:
\begin{description}
\item[id] gibt eigene UID, GID und mögliche Gruppenzugehörigkeiten aus;
\item[who am i] Ausgabe: hostname! username terminal login\_date login\_time;
\end{description}

\subsubsection*{Abmelden}
\begin{description}
\item[exit] wartet bis zuerst die Kindprozesse beendet sind;
\item[logout] beendet automatisch die Kindprozesse;
\item[Strg--D] beendet automatisch die Kindprozesse;
\end{description}

\subsection{Wandern im Dateibaum}
\begin{description}
\item[cd {\it Pfad}] wechseln in das durch den Pfad bezeichnete Verzeichnis;
\item[cd] wechseln in das durch die Variable HOME bezeichnete Verzeichnis;
\end{description}

\subsubsection*{Zugriff auf externe Datenträger}
\begin{description}
\item[mount] ohne Argument $\Rightarrow$ Liste der aktuell angehängten Geräte;
der Befehl mount ist oft nur dem superuser erlaubt;
\item[mount --t{\it Typangabe Geräteknoten Verzeichnis (in das eingehängt wird)}]
z.B.: mount --tiso 9660 /dev/mcd /cdrom
\begin{description}
\item[Typangabe:] ISO~9660~Dateisystem (CDRom-Norm);
\item[Geräteknoten des CD-Rom-Laufwerkes:] /dev/mcd;
\item[Verzeichnis in das der Dateibaum der CD-Rom-Daten eingehängt wird:]
/cdrom;
\end{description}
\item[umount] Befehl zum Abhängen eines Laufwerkes;

Die Datei /etc/fstab enthält die eingehängten Geräte und ihre Dateibäume;

\item[Wichtig bei Verwendung von Disketten:] Reihenfolge: Diskette einlegen
-- mounten -- bearbeiten -- unmounten -- Diskette entfernen einhalten; erst
beim unmounten werden die Daten auf die Diskette geschrieben!
\end{description}

\subsection{Dateien und Verzeichnisse bearbeiten}
\subsubsection*{Verzeichniskommandos}
\begin{description}
\item[rm] (remove - entfernen) Löschen von Dateien, Verzeichnissen und Links;
\item[rm --r] rekursives Löschen des Verzeichnisses mit allen
Unterverzeichnissen und den enthaltenen Dateien;
\item[rm --ri] löschen des Verzeichnisse mit allen Unterverzeichnissen und
enthaltenen Dateien, mit Rückfrage;
\item[rm --rf] löschen des Verzeichnisse mit allen Unterverzeichnissen und
enthaltenen Dateien, ohne Rückfrage;
\item[rm --f] löschen ohnen Rückfrage;
\end{description}

\subsubsection*{Links}
\begin{description}
\item[ln --s {\em Verzeichnis linkname}] einen symbolischen Link anlegen; 
mehrere  Namen für ein Verzeichnis; wird das Verzeichnis
gelöscht, so hängt der Link in der Luft;
\item[ln] (hard link) mehrere Namen für eine Datei; dies ist nur innerhalb eines
Dateisystems möglich; die Datei kann erst gelöscht werden, wenn alle auf sie
weisenden Links gelöscht wurden;

\item[rm] einen symbolischen Link entfernen;
\end{description}

\subsubsection*{Drucken}
{\bf cat {\em Datei}$>$/dev/lp0} schickt die angegebene Datei direkt unter
Umgehung des Druckauftragssteuerungssystems an den Drucker $\Rightarrow$
brutal;

\subsubsection*{Dateieigentümer und Dateiattribute}
\begin{description}
\item[chown {\it neuer\_Eigner Datei(en)}] change ownership
\item[chgrp {\it neue\_Gruppe Datei(en)}] change group
\item[umask {\it xyz}] ändern der Zugriffsrechte dadurch, daß man von der
Standardrechtemaske Rechte abzieht; x,y,z $\in$ [0,...7]; 0 entzieht keine
Rechte, 7 entzieht alle;\\
Schema:\\
\begin{description}
\item[x Eigentümerrechte] z.B.: x=0 $\Rightarrow$ user hat alle Rechte
\item[y Gruppenrechte] z.B.: x=2 $\Rightarrow$ group hat keine Schreibrechte
\item[z public-Rechte] z.B.: x=7 $\Rightarrow$ public hat keine Rechte
\end{description}
\item[chmod {\it xyz datei}] nachträgliches Ändern der Zugriffsrechte für eine
Datei oder ein Verzeichnis;
\begin{itemize}
\item numerische Schreibweise:
Die Zahl x steht für die user-Rechte, y für die group-Rechte und z für die
public-Rechte. Die 3 Zahlen können, wenn man sie im binär-code anschreibt als
1-aus-n-code-Darstellung der Rechte derjeweiligen Entität betrachtet werden.
Die Folge der Rechte ist jeweils read, write und execute. Das execute-Recht
bedeutet für Verzeichnisse, daß es betreten werden darf
x,y,z $\in$ [0,...7]; x=7 $\Rightarrow$ user hat alle Rechte ;
\item symbolische Schreibweise:
\begin{description}
\item[u] user
\item[g] group
\item[o] oder {\bf a} public
\item[+] ein Recht gewären
\item[--] ein Recht entziehen
\item[=] Gleichsetzen der Rechte verschiedener Entitäten
\item[r] read Leserecht
\item[w] write Schreibrecht
\item[x] execute Ausführungsrecht bzw. Verzeichniszutritt
\end{description}
\end{itemize}
\item[Set UserID-Bit] kurz SUID-Bit: Für den Lauf des Programmes, das das
UID-Bit setzt wird der user zum superuser. Nach dem Programmlauf stirbt der
Prozeß und alle Rechte sind wieder so wie vorher (z.B.: passwd-Programm).
\end{description}

\subsection{Kommunikation}
\begin{description}
\item[mesg] Abfrage ob messages empfangen werden;
\item[mesg yes] message-Empfang einschalten;
\item[mesg no] message-Empfang ausschalten;
\item[write \it{Empfänger}] dem Empfänger eine Nachricht schreiben;
\item[write \it{Empfänger Terminal}] ist ein user auf mehreren Terminals
eingelogged, so muß noch das Terminal angegeben werden;
\item[wall] allen eingeloggeden usern als root eine Nachricht senden;
\item[Strg--D] Abschließen des Nachrichtentextes;
\item[mail] ohne Argument; nachsehen ob mails eingelangt sind;
\item[mail {\it Empfänger}] eine mail schreiben;
\item[`.'] mail-Text mit dem Punkt abschließen;
\end{description}

\subsection{Zeit und Kalender}
\begin{description}
\item[date] Datum und Uhrzeit ausgeben;
\item[date --s {\it hh:mm:ss}] Zeit einstellen;
\item[cal] Ausgabe des Kalenders des aktuellen Monats; mit Jahreszahl als
Argument des entsprechenden Jahres;
\item[hwclock] Setzen, Anzeiten oder Synchronisieren (mit der Systemzeit)
der hardwareclock; nur als root möglich; 
\item[at {\it Uhrzeit} $\hookleftarrow$] die hierauf eingegebenen Befehle werden zu der
angegebenen Uhrzeit ausgeführt; Abschluß der Befehlssequenz mit {\em Strg--D};
\item[atq] Anzeige der Abarbeitungsschlange;
\item[atrm {\it Jobnummer}] entfernen dieses Jobs aus der Abarbeitungsschlange;
\item[batch] Die hierauf angegebenen Befehle werden ausgeführt, sobald die
Systemauslastung unter einen bestimmten Level fällt;
\end{description}

\subsubsection*{crontab}
Der Dämon crond ist für die Abwicklung der Zeitdienste zuständig; er wird
automatisch beim Hochfahren gestartet; die Einstellungen stehen in der Datei
crontab, die vom Programm crontab bearbeitet wird; nur für superuser; in den
Dateien allow und deny steht wer crontab benutzen darf und wer nicht;
\begin{description}
\item[crontab --l] crontab-Datei betrachten;
\end{description}

\subsection{Prozeßmanagement}
\begin{description}
\item[ps] Prozeßliste ausgeben: PID TTY STAT TIME COMMAND
\begin{description}
\item[PID] Prozeß-ID;
\item[TTY] Terminal von dem aus der Prozeß gestartet wurde;
\item[STAT] Aktivitätsstatus:
\begin{description}
\item[R] run
\item[S] sleep
\end{description}
\item[TIME] Rechenzeit;
\item[COMMAND] Aufrufender Befehl;
\end{description}
\item[ps --l] Ausgabe in Langform;
\item[ps --ax] alle Prozesse, auch die fremden anzeigen;
\item[top] ständig aktualisierte Liste der am System laufenden Prozesse;
\end{description}

\subsubsection*{Prozesse beenden}
Programm das im Vordergrund läuft mit eingebauten Kommandos beenden, sonst:
\begin{description}
\item[Strg --D] bedeutet Dateiende für die Standardeingabe;
\item[Strg --C] Kill-Character, Zeichen für Programmbeendigung;
\item[kill {\it PID}] Befehl an den Prozeß in dem das Programm läuft dieses zu
beenden, manche Programme ignorieren das aber;
\item[kill --9 {\it PID}] Beendet auch Prozesse die sich wehren;
\end{description}

\section{Die Shell}
\subsection{Dateien die mit der Shell in Zusammenhang stehen}
Dateien die Voreinstellungen der shell enthalten:
\begin{description}
\item[/etc/profile] enthält: Voreinstellungen die für alle Benutzer
systemweit gelten, z.B.: Systemzeit, Basissuchpfad in Variable PATH;
\item[.profile] benutzerspezifische shell-Einstellungen; liegt im
home-Verzeichnis des users;
\end{description}
Bei Verwendung der bash-shell gibt es noch zusätzlich:
\begin{description}
\item[bash\_profile]
\item[bash\_login]
\item[bash\_logout] diese Befehle werden beim Beenden der Sitzung ausgeführt;
\item[.bash\_history] enthält die letzten gemachten Kommandoeingaben;
\item[.inputrc] enthält die Tastaturdefinition für den Kommandozeileneditor;
\end{description}

Nochmaliges Ausführen einer versteckten Datei: z.B.: von .profile mit:
{\bf. .profile}; .profile ist ein Shellskript das durch Eingabe seines Namens
mit vorangestelltem Punkt in der aktiven Shell abgearbeitet wird;

\subsubsection*{Shellprompt}
\begin{description}
\item[PS1] Variable des Shellprompts;
\item[echo \$PS1] Befehl zur Ausgabe des Shellprompts;
\item[PS2] Variable des Fortsetzungsprompts; erscheint, wenn man z.B. das
$\backslash$-, $>>$ - oder das '(quote)-Zeichen eingibt und Enter drückt, oder
wenn eine unvollständige Kontrollstruktur der Shellprobrammierung direkt von
der Kommandozeile aus eingegeben wird; zurück zum normalen Prompt mit Strg--C;
\item[IFS] Variable die die Trennzeichen der Shell enthält (Leerzeichen, Tab,
Zeilenumbruch)
\end{description}

\subsubsection*{Vordergrund- und Hintergrundausführung}
\begin{description}
\item[{\it command\_1}; {\it command\_2}; ...] (mehrere) Kommando(s) im
Vordergrund abarbeiten lassen;
\item[{\it command\_1} \& {\it command\_2} \& ...] (mehrere) Kommando(s) im
Hintergrund abarbeiten lassen; Shell ist sofort wieder für eine neue
Benutzereingabe bereit;
\end{description}

\subsubsection*{Klammern in der Shell bei Pipes}
Befehle {\it a, b, c};\\
\begin{description}
\item[{\it a}$\mid\mid${\it b}$\mid${\it c}] zuerst wird Befehl {\it a} gestartet,
tritt dabei ein Fehler auf wird die Pipe {\it b}$\mid${\it c} gestartet;
\item[\{{\it a}$\mid\mid${\it b}\}$\mid${\it c}] zuerst wird Befehl {\it a}
gestartet, tritt ein Fehler auf wird Befehl {\it b} gestartet, die Pipe mit
{\it c} findet in jedem Fall statt;
\end{description}

\subsubsection*{Exit-Status und die bedingte Kommandoausführung}
\begin{description}
\item[Exit-Status] jedes C- oder Shell-Programm liefert bei fehlerfreier
Ausführung den Exit-Status~0 zurück, sonst einen anderen Wert;
\item[\$] Exit-Status-Variable;
\item[echo \$?] Abfrage des Exit-Status;
\item[{\it command\_1} \&\&\ {\it command\_2}] läuft {\it command\_1}
fehlerfrei, so wird {\it command\_2} gestartet;
\item[{\it command\_1} $\mid\mid$ {\it command\_2}] nur wenn bei
{\it command\_1} ein Fehler auftritt, wird {\it command\_2} gestartet;
\end{description}

\subsubsection*{Dateinamen}
In der Verzeichnisdatei stehen die Dateinamen mit den dazugehörenden Inodes;
\begin{description}
\item[hard link] in der gleichen oder in einer anderen Verzeichnisdatei steht
ein weiterer Name mit der gleichen Inode;
\item[symbolic link] eigener Eintrag mit eigener Inode;
\item[maximale Dateinamenlänge] 255 Zeichen;
\item[ls --b] nicht darstellbare Dateinamenbestandteile werden durch
Ersatzdarstellungen angezeigt;
\end{description}

\subsubsection*{Wildcards}
\begin{description}
\item[*] für dieses Zeichen kann jedes beliebige Zeichen beliebig oft, auch
nullmal, stehen;
\item[?] ein beliebiges Zeichen exakt einmal an dieser Position;
\item[{[...]}] ein beliebiges Zeichen, welches in der Klammer angegeben ist,
exakt einmal an dieser Position;
\item[{[!...]}] ein beliebiges Zeichen, welches {\bf nicht} in der Klammer
angegeben ist, exakt einmal an dieser Position;
\end{description}

\subsubsection*{Aufhebung der Bedeutung von Shell-Sonderzeichen}
\begin{description}
\item[$\backslash$] die Bedeutung des nachfolgenden Zeichens wird aufgehoben;
\item[`...`] (Shift--\#) Text innerhalb der einfachen quotes wird nicht von
der Shell interpretiert;
\item[`...`] (Akzent) Text innerhalb der einfachen quotes wird nicht von
der Shell interpretiert;
\end{description}

\subsubsection*{Synonyme für Befehle}
\begin{description}
\item[alias \it{neuer\_befehlsname}=\it{befehl}] Zuweisung des neuen
Befehlsnamens an den Befehl; ist der Befehl mehr als ein Wort (Befehl mit
Optionen), so muß man diese Worte unter Anführungsstriche setzen;
\item[unalias \it{neuer\_befehlsaname}] Aufhebung der Zuweisung;
\item[alias] (ohne Argument) Ausgabe der aktuellen alias-Liste;
\end{description}
Mit den alias' können keine Parameter übergeben werden; ist das letzte Zeichen
eines Ersetzungstextes eines alias das Leerzeichen, so wird ein nachfolgendes
alias ebenfalls umgewandelt; z.B.:\\
alias f="echo "; alias g="HALLO"; alias h="echo";\\
f g $\Rightarrow$ HALLO wird ausgegeben;
h g $\Rightarrow$ g wird ausgegeben;

\subsubsection*{Komandozeilenpuffer}
\begin{description}
\item[!!] Äquivalent zur $\uparrow$--Cursortaste gefolgt von Return;
\item[!--{\it n}] der {\it n}-Zeilen zurückliegende Befehl wird ausgeführt;
\item[history] Ausgabe desKommandopufferfiles;
\item[history {\it n}] Ausgabe der letzten {\it n}-Kommandozeilen;
\item[HISTFILE] Variable die den Namen des history-files angiebt;
\item[!{\it Zeichenkette}] sucht das letzte Kommando das mit der
{\it Zeichenkette} anfing, und führt es aus;
\item[!?{\it Zeichenkette}] sucht das Kommando in dem die {\it Zeichenkette}
enthalten ist und führt es aus;
\item[\^{\it alt}\^{\it neu}] ersetzt in der letzten Kommandozeile den
{\it alt}-Text durch den {\it neu}-Text und führt diesen Befehl aus;
\end{description}

\subsubsection*{Kommandozeileneditor}
\begin{description}
\item[Strg--A] Cursor springt an den Anfang der aktuellen Kommandozeile;
\item[Strg--E] Cursor springt an das Ende der aktuellen Kommandozeile;
\item[Strg--F] Cursor springt ein Zeichen nach rechts;
\item[Strg--B] Cursor springt ein Zeichen zurück;
\item[Alt--F] Cursor springt ein Wort nach rechts;
\item[Alt--B] Cursor springt ein Wort zurück;
\item[Strg--L] clear screen;
\item[Tab] word-completion; Versuch das Kommandowort (Befehl, Datei, user, ...)
zu verfollständigen;
\item[Alt--?] Ausgabe der Liste der Möglichkeiten für word-completion;
\item[Alt--/] filename-completion;
\item[Alt--\~] username-completion;
\item[Alt--\$] complete variable;
\item[Alt--@] complete hostname;
\item[Strg--T] transpose characters; Vertauschen des Zeichens an der
Cursorstelle mit dem Zeichen davor;
\item[Alt--U] upcase word; von der Cursorposition bis zum Ende des Wortes
Klein- in Großbuchstaben umwandeln;
\item[Alt--L] downcase word; von der Cursorposition bis zum Ende des Wortes
Groß- in Kleinbuchstaben umwandeln;
\end{description}

\subsubsection*{Anpassung des Kommandozeileneditors}
\begin{description}
\item[bind --v] Ausgabe der Liste der aktuellen Editorfunktionen mit den
Tastaturbelegungen;
\item[bind --l] Ausgabe der möglichen Kommandos;
\item[bind --d] Ausgabe der aktuellen Editorfunktionen in der Art, daß diese
Ausgabe durch Umleitung in eine Datei und Nachbearbeitung zur Neubelegung
verwendet werden kann.
\item[bind --f {\it Dateiname}] Neubelegung der Editorfunktionen gemäß dieser
Datei; nichtanzeigbare Zeichen werden folgendermaßen dargestellt:
\begin{description}
\item[Strg--Taste] $\backslash$C
\item[Alt--Taste] $\backslash$e
\item[Entfernen--Taste] DEL
\item[Leertaste] SPACE oder SPC
\item[Enter--Taste] RETURN, RET, LFD oder NEWLINE
\item[Tabulator--Taste] TAB
\end{description}
\item[bind --q {\it Kommandoname}] Ausgabe der entsprechenden
Tastenkombination;
\item[.inputrc] Datei die die selbstgewählte Tastaturbelegung enthält (falls
nicht die Standardbelegung verwendet werden soll); Kommentare stehen hinter \#;
\end{description}

\subsection{Umlenkung von Datenströmen}
Linux betrachtet Dateien als lange zusammenhängende Folgen von Bytes. Der
Inhalt ist nicht von Bedeutung $\Rightarrow$ einheitliche Sicht von Linux auf
die Daten.\\
$\Rightarrow$ Erweiterung des Dateikonzeptes auf Geräte, Resourcen und FIFOs
ist dadurch möglich;\\
$\Rightarrow$ einfache Umleitung der Datenströme;

\subsubsection*{Prozeß und Terminal}
Der Init-Prozeß ist der erste Prozeß der zum Terminal drei
Kommunikationslinien-Standardkanäle anlegt. Jeder Unterprozeß und jede
Subshell von ihm erbt diese Verbindungen an seinem Anfang.
\paragraph{Standardkanäle:}
\begin{description}
\item[Standardeingabe] (stdin) Kanalnummer~0 Tastatur - Prozeß Verbindung;
\item[Standardausgabe] (stdout) Kanalnummer~1 Prozeß - Bildschirm Verbindung;
\item[Standardfehlerkanal] (stderr) Kanalnummer~2 Prozeß - Bildschirm Verbindung;
\end{description}

\subsubsection*{Eingabe- /Ausgabe-Umlenkung}
Programm das alle seine Eingaben von der Standardeingabe liest bis das EOF-
(End of File-) Zeichen auftritt, und seine Ausgaben auf die Standardausgabe
leitet. Filterprogramme sind einfache Spezialisten für einfache Aufgaben,
komplexere Aufgaben können durch Datei- oder Kommandoumlenkungen oder Pipes
gelöst werden ($\Rightarrow$ Shellprogrammierung, C, awk, ...).
\begin{description}
\item[{\it befehl} $>$ {\it datei}] Ausgabe statt am Bildschirm in die Datei
umgeleitet; existiert diese Datei schon, so wird sie überschrieben, außer die
Shellvariable {\bf noclobber} ist gesetzt;
\item[{\it befehl} $>>$ {\it datei}] Ausgabe statt am Bildschirm an die
existierende Datei angehängt;
\item[{\it befehl} 2$>$ {\it datei}] Ausgabe des Fehlerkanals (Kanalnummer~2)
in die Datei umgelenkt
\item[{\it befehl} 2$>>$ {\it datei}] Ausgabe des Fehlerkanals
(Kanalnummer~2) an die Datei angehängt;
\item[{\it befehl} $>$ {\it datei} 2$>$\&1] Umleitung der Standardausgabe und des
Fehlerkanals;
\item[{\it befehl} $>$ {\it datei} 2\&$>$1] alternative Schreibweise;
\item[{\it befehl} $>$ {\it datei} 2$>$\&1 $\mid$ mail {\it mail\_adr}] Umlenkung
der Standardausgabe und des Fehlerkanals in ein mail;
\item[{\it befehl} 2$>$ {\it fehlerdatei} $>$ {\it ergebnisdatei}] Umlenkung
des Fehlerkanals und der Standardausgabe in eine jeweils eigene Datei;
\item[{\it befehl} $<$ {\it datei}] Eingabe von der Datei anstatt von der
Tastatur;
\item[{\it befehl} $<<$ {\it Zeichen}] Here-Dokument; alle nachfolgenden
Eingabezeilen oder Zeilen des Shellskripts bis zum Aufhebungszeichen
{\it "Zeichen"} sind Eingabe; damit kann ein interaktives Programm mit seinen
sonst zwischendurch erforderlichen Eingaben gestartet werden;
\item[{\it befehl n}$<$ {\it datei}] Kanal Nr. {\it n} zum Einlesen öffnen;
{\it n} $\in$ [1,2, ...];
\item[{\it befehl n}$>$ {\it datei}] Kanal Nr. {\it n} zum Auslesen öffnen;
\item[{\it befehl n}$<$$>$ {\it datei}] Kanal Nr. {\it n} zum Lesen und
Schreiben öffnen;
\item[{\it befehl n}$<$\& --] Kanal Nr. {\it n} schließen;
\item[{\it befehl n}$>$\& --] Kanal Nr. {\it n} schließen;
\end{description}


\subsubsection*{Piping}
Es gibt 2 Formen des Pipings:
\begin{description}
\item[{\it command\_1}$\mid${\it command\_2}$\mid$ ...] einfache Pipe; die
Kommandos werden von der gleichen Kommandozeile losgeschickt;
\item[{\it command\_3} $<$({\it command\_1}) $<$({\it command\_2})] das
{\it command\_3} bekommt die Ausgaben der Kommandos 1 und 2 nicht über eine
Datei sondern ein Verzeichnis; die sendenden Kommandos machen einen FIFO-Eintrag
ins Verzeichnis /tmp und dieser Verzeichniseintrag wird quasi wie ein
Dateiname an das {\it command\_3} geliefert;
z.B.: wc $<$(cat {\it datei\_1}) $<$(cat {\it datei\_2})
\end{description}

\subsubsection*{Kommandoumlenkung}
\begin{description}
\item[{\it command\_1}`{\it command\_2}`] (grave-Akzent) oder:
\item[{\it command\_1}\$({\it command\_2})] die Ausgabe des zweiten
Kommandos wird zur Eingabe des ersten; z.B.:\\
aktpfad=\$(pwd)\\
PS1="$\backslash$u@$\backslash$h: `pwd` $>$ "\\
mail `who$\mid$cut --d" " --f1`$<$ {\it mailtext} damit wird den usern die
eingelogged sind ein mail gesendet;
\end{description}

\subsection{Prozeßsteuerung}
Schickt man ein normalerweise von der Standardeingabe lesendes Programm in den
Hintergrund (und macht keine Eingabeumleitung), so gibt die Shell /dev/null
als Datenquelle an.\\
$\Rightarrow$ Das Programm bekommt ein EOF als Eingabe.\\
$\Rightarrow$ Das Programm beendet sich normalerweise.

Die Ausgabe eines im Hintergrund laufenden Programmes läuft auch (so man sie
nicht umleitet) auf das Terminal.
\begin{description}
\item[nice --{\it wert command}] Änderung der Priorität des Kommandos; nur der
superuser kann die Priorität erhöhen;
\item[nohup {\it command} \$] verhindert, daß ein lange andauernder Prozeß,
der ja von der Kommandoshell, von der er gestartet wurde, abstammt, beim
Ausloggen automatisch beendet wird. Der Prozeß wird vom Init-Prozeß adoptiert.
\item[nohup.out] diese Datei sammelt alle zwischenzeitlichen Ausgaben der im
Hintergrund laufenden Prozesse.
\item[jobs] gibt die aktuell laufenden Jobs aus;\\
{[Job\_Nr]} Symbol Status Befehl\\
\begin{description}
\item[Symbol] + oder -- für den aktuellen bzw. den Vorgängerjob;
\item[Status] Running, Stopped oder Done;
\end{description}
\item[jobs --l] {[Job\_Nr]} Symbol PID Status Befehl
\item[Strg--Z] Anhalten eines im Vordergrund laufenden Jobs;
\item[bg {\it Job\_Nr}] Job in den Hintergrund schicken;
\item[fg {\it Job\_Nr}] Job in den Vordergrund schicken;
\end{description}

\subsection{Shellvariablen}
Shellvariablen werden durch ihre Benutzung ins Leben gerufen; sie müssen nicht
vorher deklariert werden wie z.B.: Variablen in C-Programmen;
\begin{description}
\item[set --u] verhindert, daß auf eine noch nicht definierte Variable
zugegriffen wird; z.B.: es ist noch keine Variable {\it a} definiert;\\
echo \$a $\Rightarrow$ Ausgabe: leere Zeile\\
set --u\\
echo \$a $\Rightarrow$ Ausgabe: a: unbound variable\\
\item[declare --i {\it variable}] Deklaration der Variable als integer; da die
Variable in 32 Bit mit einem Vorzeichenbit dargestellt wird ist der
Zahlenbereich [$-2^{31} ...2^{31}$] ca. $2*10^9$;
\item[Variablennamen] müssen mit einem Buchstaben oder underline beginnen;
\item[declare --r {\it variable}] read only;
\item[declare --x {\it variable}] export; Variable wird auch an subshells
weitergegeben;
\item[declare] (ohne Argument) Ausgabe der aktuellen Einstellungen der
Variablen;
\end{description}

\subsubsection*{Zuweisungen}
\begin{description}
\item[{\it variable}={\it wert}] Achtung: keine Leerzeichen einfügen!
\item[{\it variable}=\${\it variable\_2}] Zuweisung des Wertes der Variable~2
an die Variable~1;
\item[{\it variable}=`{\it command}`] Variable erhält die Ausgabe des
Kommandos;
\item[{\it variable}=\$({\it command})] Variable erhält die Ausgabe des
Kommandos;
\item[read {\it variable}] interaktive Wertzuweisung in Shellskripts;
\end{description}

\subsubsection*{Ausgabe mit echo}
\begin{description}
\item[echo {\it z.B.: Dateinamenmuster}] Ausgabe der Dateien die diesem Muster
entsprechen; praktisch zur Kontrolle, damit man nicht gleich Befehle auf
Dateien anwendet, die man garnicht beglücken will;
\item[echo {\it text}] der Text wird von der Shell analysiert und dann dem
Befehl echo als Argument zur Verfügung gestellt;
\item[echo "{\it text}"] nur noch Kommandoumlenkung und Variablenzugriff möglich;
\item[echo \'{ }{\it text}\'{ }] Shell analysiert nichts mehr;
\end{description}
z.B.: a=5; echo \$a "\$a" $\backslash$\$a '\$a'\\
Ausgabe: 5 5 \$a \$a

Steuerzeichen für Ausgabe mit {\bf echo--e}:\\
(zur Vermeidung von Problemen unter einfache oder doppelte Anführungszeichen 
setzen)
\begin{description}
\item[$\backslash$b] backspace
\item[$\backslash$c] Zeilenvorschubunterdrückung
\item[$\backslash$f] Seitenvorschub
\item[$\backslash$n] Zeilenvorschub
\item[$\backslash$r] carriage return
\item[$\backslash$t] Tabulator
\item[$\backslash$$\backslash$] Das Zeichen "$\backslash$"
\item[$\backslash${\it nnn}] das ASCII-Zeichen, dessen Oktalnummer {\it nnn}
ist
\item[$\backslash$a] Alarm
\end{description}

Verkettung:\\
\$a=5;\\
echo \$a,Leute $\Rightarrow$ 5,Leute\\
echo \$a Leute $\Rightarrow$ 5 Leute\\
echo \$\{a\}Leute $\Rightarrow$ 5Leute\\

\subsubsection*{Shellvariablen und Kommandoaufrufe}
Shellvariablen können in Kommandozeilen verwendet werden, da ihre Inhalte
interpretiert werden. Von Bedeutung nur in Shellskripts, da bei interaktiver
Kommandoeingabe Kommandosynonyme zur Verfügung stehen.

Da die Shell nur 1~Analyse der Kommmandozeile durchführt werden Kommandozeilen,
deren Shellvariablen selbst Shellsonderzeichen und Variablenzugriffe enthalten,
meist fehlerhaft verarbeitet.\\
Z.B.: pipe="$\mid$ wc"\\
ls \$pipe $\Rightarrow$ Ausgabe: no such file or directory (und nicht die
Anzahl der Wörter und Buchstaben des ls-Kommandos.
\begin{description}
\item[eval {\it ausdruck}] der Ausdruck wird von eval genau so analysiert wie
es die Shell macht; eval kann auch geschachtelt werden; die Shell analysiert
dann das Ergebnis noch einmal;\\
eval ls \$pipe $\Rightarrow$ Ausgabe der Anzahl der Wörter und Buchstaben;
\end{description}

\subsubsection*{Gültigkeitsbereich von Variablen}
Jeder Prozeß trägt einige Daten mit sich herum, die als seine Umgebung
(environment) bezeichnet werden. Z.B.: enthält die Umgebung der Shell die
geöffneten Standardkanäle, Datenzugriffe und das aktuelle Arbeitsverzeichnis.

\paragraph{lokale und globale Variablen}
\begin{description}
\item[declare --x {\it variable}] (x...export), oder:
\item[export {\it variable}] die so deklarierten Variablen werden an eine
Subshell weitergegeben;
\item[declare --f {\it shell\_fkt.}] oder:
\item[export --f {\it shell\_fkt.}] die so deklarierten Shellfunktionen werden
an eine Subshell weitergegeben;
\end{description}
Veränderungen einer Variablen in der Subshell werden nicht an die aufrufende
Shell weitergegeben.

\paragraph{Löschen von Variablen}
\begin{description}
\item[{\it variable}=$\hookleftarrow$] Gleichsetzen der Variable mit der leeren
Zeichenkette;
\item[unset {\it variable}] die Variable als ganzes löschen; dies funktioniert
nicht, wenn die Variable noch den Read-Only-Status hat (vorher den Read-Only-Status
beenden mit: readonly --n);
\end{description}

\subsection{Berechnungen mit der Shell}
Zahlenbereich [$-2^{31} ...2^{31}$] ca.$2*10^9$; 32 Bit, 1 Vorzeichenbit;
keine Warnung bei Zahlenbereichsüberschreitung;
\begin{description}
\item[echo \${[{\it Ausdruck}]}] $\Rightarrow$ Ausgabe des Rechenergebnisses;\\
z.B.: a=5; b=2\\
c=\$[\$a+\$b]; echo c $\Rightarrow$ Ausgabe: 7;
\end{description}

\subsubsection*{Operatoren}
\begin{description}
\item[!, \~] logische, bzw. bitweise Negation;
\item[*, /, \%] Multiplikation, Division, Modulo (Rest der ganzzaligen Division);
\item[+, -] Addition, Subtraktion;
\item[$<<$, $>>$] Verschieben des Bitmusters nach links bzw. rechts; $a>>b$
schiebt das Bitmuster von {\it a} um {\it b}-Stellen nach rechts;
\item[$<=$,$>=$] kleiner gleich, größer gleich; das Ergebnis liefert 1 für
TRUE oder 0 für FALSE;
\item[==, !=] Gleichheit bzw. Ungleichheit;
\item[\&, $\mid$] bitweises UND bzw. ODER;
\item[\$\$, $\mid\mid$] logisches UND bzw. ODER;
\item[={\it operator}=] Zuweisung und kombinierte Zuweisung; als Operator sind
alle obigen 2-Operanden-Operationen erlaubt;
\end{description}

\subsection{Das Kommando set}
Mit {\bf set} kann das Verhalten der Shell verändert werden im Gegensatz zu
{\bf stty}, das das Verhalten des Terminals verändert. Da man mit der Shell
nur mittels des Terminals kommuniziert sind komplizierte Verwicklungen
möglich.

\section{Linux-Werkzeuge}
\subsection{Reguläre Ausdrücke}
Metazeichen die von vielen Programmen interpretiert werden:
\begin{description}
\item[{[\^{}...]}] Verneinung der Zeichenklasse, wie [! ...];
\item[\^] Zeilenanfang;
\item[\$] Zeilenende;
\item[$<$] Wortbeginn;
\item[$>$] Wortende;
\item[(...)] Gruppen von Ausdrücken;
\item[$\backslash$] Ausblendung der Sonderbedeutung des folgenden Zeichens;
\end{description}
Von manchen Programmen interpretierte Metazeichen:
\begin{description}
\item[+] das vorangehende Zeichen 1-mal oder öfter;
\item[\{{\it n,m}\}] ein Wiederholungsintervall;
\item[\{{\it n}\}] ein genauer Wiederholungswert;
\item[{\it a}$\mid${\it b}] alternative Ausdrücke;
\end{description}

\subsection*{find}
find {[Verzeichnis][--Optionen][--Test][--Aktionen]}

\subsubsection*{Verzeichnis}
{\bf find} sucht in dem angegebenen Verzeichnis und seinen
Unterverzeichnissen; dieser Eintrag darf nicht ausgelassen werden,
mindestens: /

\subsubsection*{Optionen}
\begin{description}
\item[--daystart] mißt die Zeitmarken der Dateien vom Beginn des heutigen
Tages;
\item[--depth] zuerst dieVerzeichnisinhalte, dann die Verzeichnisse selbst
bearbeiten;
\item[--maxdepth {\it N}] höchstens {\it N}-Stufen im Verzeichnisbaum nach
unten gehen;
\item[--mindepth {\it N}] mindestens {\it N}-Stufen im Verzeichnisbaum nach
unten gehen;
\item[--xdev] Verzeichnisse in anderen Dateisystemen als dem aktuellen werden
nicht durchsucht;
\item[--follow] folgt symbolic links;
\item[--help]
\end{description}

\subsubsection*{Test}
\begin{description}
\item["{\it suchtext}"] Suche nach Namen (des users, der group, Dateinamen, ...);
\item[{\it zahlenwert}] Suche nach dem exakten Zahlenwert;
\item[{\it +zahlenwert}] Suche nach größerer als der angegebenen Zahl;
\item[{\it --zahlenwert}] Suche nach kleinerer als der angegebenen Zahl;
\item[--amin {\it N}] Zugriff vor {\it N}-Minuten;
\item[--anewer {\it file}] auf diese Datei(en) wurde nach dem Zugriff auf
{\it file} zugegriffen;
\item[--cmin {\it N}] Statusänderung der Datei vor {\it N}-Minuten;
\item[--cnewer {\it file}] die Statusänderung wurde nach der Statusänderung
von {\it file} durchgeführt;
\item[--ctime {\it N}] die Statusänderung wurde vor {\it N}-Tagen vorgenommen;
\item[--mmin {\it N}] der Dateiinhalt wurde vor {\it N}-Minuten geändert;
\item[--mtime {\it N}] der Dateiinhalt wurde vor {\it N}-Tagen geändert;
\item[--newer {\it file}] Veränderung erfolgte nach der letzten von {\it file};
\item[--used {\it N}] Zugriff inerhalb von {\it N}-Tagen nach der letzten
Änderung;
\end{description}

\subsubsection*{Aktionen}
\begin{description}
\item[--exec {\it command}] nachdem eine Datei gefunden wurde wird mit ihr
automatisch das Kommando durchgeführt;
\item[--ok {\it command}] nachdem eine Datei gefunden wurde wird mit ihr nach
Rückfrage das Kommando ausgeführt;
\end{description}

\subsection*{grep}
\begin{description}
\item[fgrep] (fast grep) ist schneller als {\bf grep}, kann aber weniger;
\item[egrep] (extended grep) ist langsamer als {\bf grep}, kann aber mehr;
\end{description}
grep [--[[A B]]$<num>$][--[CEFGVchilnqsvwx]][--[ef]]$<expr>$[$<files>$]

\begin{description}
\item[A {\it n}]  gibt {\it n} Zeilen nach der Fundstelle aus;
\item[B {\it n}] gibt {\it n} Zeilen vor der Fundstelle aus;\\
z.B.: grep --A2 --B5 '{\it suchtext}' {\it datei}\\
gibt gibt die gefundenen Zeilen mit den jeweils 2 vorhergehenden und jeweils
5 nachfolgenden Zeilen aus; die einzelnen Fünde werden durch '-- --' getrennt;
\item[--{\it n}] gibt {\it n} Zeilen vor und nach dem Fund aus;
\item[--b] Ausgabe mit der Positionsangabe;
\item[--i] Groß-/Kleinschreibung ignorieren;
\item[--l] Nur die Namen der Dateien mit Fünden ausgeben;
\item[--n] Ausgabe mit Zeilennummern;
\item[--s] nur die Fehlermeldungen ausgeben;
\item[--v] nur die Zeilen ohne den Suchtext ausgeben;
\item[--w] nur die Zeilen ausgeben, in denen der Suchtext als ganzes Wort
vorkommt;
\item[--x] nur die Zeilen ausgeben, in denen der Suchtext als ganze Zeile
vorkommt;
\end{description}

\subsection{file}
{\bf file} {\it datei} gibt an welchen Typs die Datei ist; mögliche Ausgaben:
ascii text, shell script, Linux/i386, symbolic link, block special; ...

\subsection*{cat}
cat (concatenate) hängt die angegebenen Dateien zusammen; für kurze Dateien
ist es als schneller viewer geeignet;
\begin{description}
\item[--b] alle nicht leeren Zeilen nummerieren;
\item[--n] alle Zeilen nummerieren;
\item[--s] mehrere aufeinanderfolgende Leerzeilen werden zu 1~Leerzeile
umgewandelt;
\item[--E] Anzeige von "\$" an jedem Zeilenende;
\item[--T] Tabs als "\^{}I" darstellen;
\end{description}

\subsection*{tac}
Wie cat nur die Zeilenreihenfolge ist umgekehrt;

\subsection*{more und less}
less ist umfangreicher und muß nicht erst die ganze Datei einlesen bevor die
Ausgabe beginnt $\Rightarrow$ schneller;
\begin{description}
\item[less --?] Anzeige der Flags d.h. der internen Kommandos;
\end{description}

\subsection*{tail}
gibt die letzten Zeilen (standardmäßig 10) einer oder mehrerer Datei(en) aus;

\subsection*{head}
gibt die ersten Zeilen (standardmäßig 10) einer oder mehrerer Datei(en) aus;

\subsection*{sort}
{\bf sort} +POS1 --POS2 sortiert gemäß der Zeichen von POS1 bis POS2; POS{\it x}
kann in Tabellen als {\it feld}{\bf .}{\it zeichen} festgelegt werden;
\begin{description}
\item[--b] führende Leerzeichenunbeachtet lassen;
\item[--d] nur Zeichen a--z, A--Z und 0--9 berücksichtigen;
\item[--f] Groß- und Kleinschreibung nicht getrennt behandeln;
\item[--r] (reverse) umgekehrte Sortiereihenfolge;
\end{description}

\subsection*{uniq}
Auswahl der Zeilen einer Datei jenachdem ob sie einmal oder öfter enthalten
sind;
\begin{description}
\item[--u] unterdrückt mehrfache Zeilen;
\item[--d] gibt nur die mehrfach enthaltenen Zeilen aus;
\item[--c] (count) Ausgabe der Zeilen mit ihrer Anzahl des Auftretens
vorangestellt;
\end{description}

\subsection*{tee}
T-Stück in einer Pipe; Abzweigung eines Zwischenergebnisses in eine Datei;\\
...$\mid$ {\bf tee} {\it datei} $\mid$ ...

\subsection*{od}
(octal dump) Betrachten von binären Dateien;
\begin{description}
\item[--Ad] mit dezimaler Byteposition;
\item[--Ao] mit oktaler Byteposition;
\item[--Ax] mit hexadezimaler Byteposition;
\item[--An] ohne Byteposition;
\item[--a] Datenausgabe als ASCII-Zeichen;
\item[--x] Datenausgabe als ASCII-Zeichen;
\item[--f] Datenausgabe als Fließkommazahl;
\end{description}

\subsection*{cut}
Ausschneiden von Spalten aus einer Textdatei;
\begin{description}
\item[--c {\it a}--{\it b}] schneidet die Bites {\it a} bis {\it b} aus der
Datei aus;
\item[--f {\it n}] schneidet die {\it n}-te Spalte aus; Spaltendelimitor
(-Trennzeichen) ist der Tab;
\item[--d"{\it x}"] Zeichen {\it x} als Spaltendelimitor definieren; tritt das
gewählte Zeichen mehrfach hintereinander auf so sieht cut leere Felder
$\Rightarrow$ Abhilfe mit {\bf tr};
\end{description}

\subsection*{fold}
Begrenzung der Zeilenlänge durch Umbruch;

\subsection*{split und csplit}
Zerlegen von Dateien; bei csplit kann man ein Suchmuster angeben, wobei die
Zerlegung so erfolgt, daß die Zeile die das Suchmuster enthält zur 1.~Zeile
der nächsten Splitterdatei wird. Das Suchmuster wird nach dem Dateinamen
angegeben. In geschweiften Klammern kann angegeben
werden, wie oft das Suchmuster angewendet werden soll, keine Angabe
$\Rightarrow$ nur 1~mal; \{*\} $\Rightarrow$ sooft wie möglich;

\subsection*{join}
Zusammenfügen mehrerer sortierter Dateien in Abhängigkeit von einer jeweils
anzugebenden Schlüsselspalte;

\subsection*{paste}
Zeilenweises Zusammenfügen von Dateien; alle jeweils 1.~Zeilen werden zu einer
neuen Gesamt-1.-Zeile (die Bruchstücke sind durch Tabs getrennt);

\subsection*{Vergleiche}
\subsubsection*{cmp}
Byteweiser Vergleich zweier Dateien; bei Ungleichheit wird abgebrochen und der
Exit-Status ist 1;
\begin{description}
\item[--verbose] es wird eine Liste der Unterschiede ausgegeben;
\end{description}

\subsubsection*{comm}
Vergleich von zwei sortierten Dateien;\\
Ausgabe ist 3-spaltig:
\begin{description}
\item[1.~Spalte:] Einträge die nur in der 1.~Datei stehen;
\item[2.~Spalte:] Einträge die nur in der 2.~Datei stehen;
\item[3.~Spalte:] Einträge die in beiden Dateien enthalten sind;
\end{description}

\subsection{Umwandlungen}
\subsubsection*{expand}
Alle Tabs in eine gewünschte Anzahl von Leerzeichen umwandeln;

\subsubsection*{tr}
Zeichen ersetzen oder beseitigen; funktioniert nur innerhalb einer pipe und
jeweils nur eine Ersetzung; z.B.:\\
cat {\it datei} $\mid$ tr "[:punct:]" " " $\mid$ tr --s " " $\mid$ less\\
in der angegebenen Datei werden alle Punktationszeichen durch blanks ersetzt,
und anschließend blank-Ketten durch einzelne blanks ersetzt;\\
tr {[OPTIONS]} SET1 {[SET2]}
\begin{description}
\item[SET1] Liste der zu ersetzenden Zeichen;
\item[SET2] Liste der Ersetzungszeichen; {\it n}-tes~Element ersetzt das
{\it n}-te~Element von SET1;\\
OPTIONS:
\begin{description}
\item[--c] (complement) Ersetzung des Gegenteils der in SET1 angegebenen
Zeichen durch Zeichen von SET2;
\item[--s] (squeeze) mehrfach vorkommende Zeichen werden durch ein einzelnes
Zeichen ersetzt;
\end{description}
\item[trs] Filterprogramm zum Ersetzen von strings
\end{description}

\subsection{Formatierungen}
\subsubsection*{nl}
nl {[OPTION]} ... {[FILE]}\\
Textdateien (oder wenn keine Datei angegeben wird die Standardeingabe) für
einfachen Ausdruck formatieren; Ausdruck mit Kopfzeile, Fußzeile,
Seitennummer, Zeilennummerierung, ...
\begin{description}
\item[Kopfteil] wird mit "$\backslash:\backslash:\backslash:$" eingeleitet;
\item[Körper] wird mit "$\backslash:\backslash:$" eingeleitet;
\item[Fußteil] wird mit "$\backslash:$" eingeleitet;
\end{description}

\subsubsection*{pr}
pr [OPTION] ... [FILE] ...\\
Ausdruck eines Textfiles (oder wenn keine Datei angegeben wird der
Standardeingabe); in der Kopfzeile stehen standardmäßig: Dateiname,
Seitennummer und aktuelles Datum;

\section{Editoren des Linux-Systems}
\subsection{ed}
Zeilenorientierter Editor, d.h. man kann nur ganze Zeilen löschen, ersetzen 
{\ldots};
\begin{description}
\item[ed {\it datei}] wird kein Dateiname oder ein neuer angegeben, so
generiert man eine neue Datei;
\item[Ausgabe:] Anzahl der gelesenen Bytes; ed ist ursprünglich im 
command-modus;
\item[Command-Modus-Befehle:]\\
\begin{description}
\item[q] (quit) Beenden von ed;
\item[w] (write) Speichern der Datei;
\item[l] (last) Anzeigen der letzten Zeile; nichtdruckbare Zeichen werden
durch Ersatzdarstellungen angezeigt;
\item[p] (print) Anzeige der letzten Zeile so wie sie im Druck erscheint;
\item[n] Zeile mit vorangestellter Zeilennummer;
\end{description}
l-, p- oder n-Befehl mit vorangestellter Zeilennummer zeigt die angegebene
Zeile an;\\
Anzeige eines Zeilenbereiches: {\it a, b X}
\begin{description}
\item[{\it a}] Anfangszeilennummer;
\item[{\it b}] Endzeilennummer; für die letzte Zeile der Datei steht: \$;
\item[{\it X}] Befehl l, p oder n;
\end{description}
\end{description}

\subsubsection*{Texteinfügen}
\begin{description}
\item[a return] (append) Text hinter der aktuellen Zeile einfügen;
\item[i return] (insert) Text vor der aktuellen Zeile einfügen;
\end{description}
dann die neue Zeile eingeben und die Eingabe mit return abschließen; mit Punkt
gefolgt von return springt ed wieder in den command-modus;

\subsubsection*{Text löschen}
\begin{description}
\item[d return] (delete) Aktuelle Zeile löschen;
\item[{\it n}d return] (delete) Zeile mit Nummer {\it n} löschen;
\end{description}

\subsubsection*{Kopieren}
\begin{description}
\item[{\it a} t {\it b}] Zeile {\it a} wird hinter Zeile {\it b} kopiert;
für die letzte Zeile der Datei steht: \$;
\end{description}

\subsubsection*{Relative Zeilenadresse}
\begin{description}
\item[+{\it n}] {\it n}-Zeilen nach oben;
\item[-{\it n}] {\it n}-Zeilen nach unten;
\end{description}

\section{Shellprogrammierung}
\subsection{Allgemeines}
Die folgenden Erläuterungen beziehen sich auf die bash-Shell; in der
Korn-Shell gelten sie größtenteils auch; die Shellprogrammierung in der
C-Shell ist aber völlig inkompatibel dazu;

Elemente der Shellprogrammierung:
\begin{description}
\item[Shellbestandteile]\\
\begin{itemize}
\item interne Kommandos der Shell
\item Kontrollstrukturen der Shellsprache
\item Shellvariablen
\end{itemize}
\item[Programme und Shellskripts] mitgeliefert, selbstentwickelt, ...
\end{description}

\subsubsection*{Kommentar}
{\bf \#} alles in einer Zeile hinter der Raute stehende gilt als Kommentar;

\subsubsection*{Wohin mit den selbstgeschriebenen Shellskripts?}
Nich in $\backslash$bin oder $\backslash$usr$\backslash$bin wegen
organisatorischer Probleme bei updates, sondern:\\
eigene in ein $\backslash$bin
subdirectory unter dem eigenen home-Verzeichnis und systemweite (öffentliche)
unter $\backslash$usr$\backslash$local$\backslash$bin\\
PATH-Varaiable entsprechend setzen!

\subsection{Ausführungsformen}
\subsubsection*{expliziter Aufruf einer Subshell}
{\bf bash {\it skript}} Ausführung in einer explizit aufgerufenen Subshell,
die nur für die Laufzeit der Shell existiert; Vorteile des expliziten
Aufrufes:
\begin{itemize}
\item Sicherheit;
\item auch möglich, wenn das Skript für eine andere als die aufrufende Shell
geschrieben wurde;
\item nur das Leserecht muß gesetzt sein;
\end{itemize}

\subsubsection*{Impliziter Aufruf einer Subshell}
{\bf \it skript} Das Shellskript läuft in einer eigenen implizit
aufgerufenen Subshell;\\
Vorteile:
\begin{itemize}
\item Sicherheit;
\item Lese- und Ausführungsrechte müssen gesetzt sein;
\item Aufruf wie der von Linux-Befehlen oder anderer externer Programme;
\end{itemize}

\subsubsection*{Ausführung in der aktiven Shell}
{\bf . {\it skript}} Das Shellskript wird in der aktiven, d.h. in der
aufrufenden Shell ausgeführt;
\begin{description}
\item[Befehl exit] gute Shellskripts enthalten diesen Befehl meistens; so
kann nach dem Ablauf des Shellskripts kontrolliert werden ob der Ablauf ohne
Probleme verlief; der Befehl exit beendet aber auch die Shell in der das
Shellskript läuft! - bei Ausführung in der aktiven Shell meldet man sich
somit ab.
\end{description}

\subsubsection*{Probleme}
Beginnt ein Shellskript mit:
\begin{description}
\item[\#!$\backslash$bin$\backslash$bash] so läuft das Shellskript automatisch
in der bash-Shell ab;
\item[\#!$\backslash$bin$\backslash$csh] so läuft das Shellskript automatisch
in der C-Shell ab;
\item[Befehl exec] exec ruft ein echtes Binärprogramm ohne eigener Subshell
auf (Vorteil: schnell und geringe Systembelastung); alle weiteren Befehle im
Shellskript werden ignoriert!
\end{description}

\subsection{Daten-Ein- und Ausgabe}
\subsubsection*{Argumentevariablen}
Sie werden Beim Aufruf des Shellskripts als Argumente bzw. Parameter übergeben.
\begin{description}
\item[\$\{{\it n}\}] Variable die das {\it n}-te Argument enthält;
{\it n} $\in$ [1...9] bei der Bourne-Shell\\
mit dem Befehl {\bf shift} lassen sich die dahinterliegenden Variablen holen\\
{\it n} $\in$ [1...$\infty$] bei der Bourne-Shell\\
\item[\$0] enthält den Namen des Shellskripts
\item[\$\#] enthält die Anzahl der übergebenen Argumente
\item[\$@ {\rm oder} \$*] enthalten jeweils die ganze Argumenteliste
\end{description}

\subsubsection*{Interaktive Shellskripts}
\begin{description}
\item[read {\it a}] die Variable {\it a} wird interaktiv eingelesen; es wird
alles bis zum abschließenden return eingelesen;
\item[read {\it a b c}] die 3 Variablen {\it a, b} und {\it c} werden
eingelesen; jede Variable erhält ein Wort, falls Worte überzählig sind werden
sie auch der letzten Variable zugewiesen; die möglichen Trennzeichen zwischen
den Variablen stehen in der Shellvariablen IFS;
\end{description}

\subsubsection*{Ausgabe}
\begin{description}
\item[echo "{\it Ausgabetext}"] der Ausgabekanal kann festgelegt werden,
ansonsten Standardausgabe;
\end{description}

\subsubsection*{Andere Verfahren der Dateneingabe}
Sie sind anzuwenden wenn die Daten immer die gleichen sind, oder nicht vom
Benutzer des Skripts bereitgestellt werden.
\begin{description}
\item[Variablenbelegung vor dem Skriptaufruf] Läuft das Skript in einer
eigenen subshell so müssen die Variablen in der aufrufenden shell mit 
{\bf export} vererbbar gemacht worden sein. Durch Argumenteerweiterungen
könne Probleme die dur Nichtbelegung der erforderlichen Variablen entstehen
können vermieden werden.
\item[Dateiumleitung und Piping in Shellskripts] Umleitungen in oder aus
anderen Dateien oder Programmen sind möglich. Z.B.: Ausgabe in den
Fehlerkanal:\\
echo ``{\it text}'' $>$\&2\\
exit 1\\
Zeilenweise Ausgabe mit Zeilennumerierung der im Aufruf spezifizeirten
Datei:\\
cat \$1 $\mid$ while read zeile\\
do\\
echo -e ``\$zno $\backslash$t: \$zeile''\\
let zno+=1\\
done $>$ \$2\\
exit 0\\
\item[Kommandoumlenkung]
\end{description}
%
%
%	Da fehlt noch was!
\newpage
%
%

\section{gawk}
\subsection{Allgemeines}
awk ist ein von Aho, Weinberger und Kernighan entwickelter Reportgenerator.
Ein Reportgenerator ist dazu da Dateien zeilenweise zu lesen, die Zeilen in
Felder zu zerlegen und je nach Aufgabe daraus die entsprechenden Antworten
zu erzeugen (Bericht aus einer Datenbank). gawk ist die Gnu-Version.

\subsection{Aufruf des gawk}
Wird beim Start von awk oder gawk keine Datei angegeben, so wird die
Standardeingabe bis zum Abschluß mit Strg--D bearbeitet.
\begin{description}
\item[gawk {\it 'program' datei}] oder
\item[gawk --f {\it programmdatei datei}] Das Programm kann in der
Kommandozeile direkt angegeben werden oder in der Programmdatei stehen;
Programm in einfache Anführungsstriche setzen!; die Datei enthält die
Datensätze;
\end{description}

\subsubsection*{Optionen}
\begin{description}
\item[--F {\it fs}] Angabe eines fieldseperators {\it fs}; damit wird die
Variable {\it FS} neu belegt;
\item[--v {\it var}] Belegung der Variablen {\it var} mit einem Wert;
\item[--f {\it datei}] Angabe des Programms in der Programmdatei;
\item[--W] Gnu-awk spezifische Optionen;
\item[--W compat] Gnu-awk läuft kompatibel zum original UNIX-awk;
\item[--W lint] Test auf semantisch zweifelhafte oder schlecht portable
Konstrukte;
\item[--W posix] POSIX-kompatibler Modus;
\begin{description}
\item[$\backslash$x] Escape-Sequenzen werden nicht erkannt; 
\item[func] als Synonym für {\bf function} wird nicht erkannt;
\item[** {\rm und } **=] können nicht anstelle der {\bf \^{}and} und 
{\bf \^{}=} Operatoren verwendet werden;
\end{description}
\end{description}

\subsection{Aufruf in Shellskripten}
\subsubsection*{mit interaktivem Dateinamen}
\#!/bin/bash\\
echo --e ``Dateiname: $\backslash$c''\\
read dateiname\\
gawk `\{print \}' \$dateiname\\

\subsubsection*{todschicke Variante}
\#!/usr/bin/gawk --f\\
alle nachfolgenden Zeilen des Shellskripts werden als gawk-Programm
abgearbeitet;

\subsection{Aufbau von gawk-Programmen}
Ein gawk-Programm besteht aus mindestens einer Zeile die enthält:\\
{\it Muster} \{ {\it Aktion(en)} \}\\
das / die Muster werden in jeder Eingabe- /Dateizeile einmal gesucht und falls
vorhanden wird / werden die Aktion(en) ausgeführt; wird kein Muster
angegeben werden die Aktionen auf jeden Fall ausgeführt;

\subsubsection*{Einfaches gawk-Programm}
gawk `\{print ``Hello, world''\}'\\
nach jeder beliebigen weiteren Eingabe wird ``Hello, world'' geantwortet,
bis man die Eingabe von der Standardeingabe mit Strg--D abschließt;

\subsubsection*{Papagei-Programm}
gawk `\{print\}'\\
die Eingabe wird auf jeden Fall zeilenweise ``nachgeplappert'';\\
gawk `\{print \$0\}'\\
liefert das gleiche Resultat;

\subsubsection*{Variablen}
\begin{description}
\item[\$0] diese Variable enthält die ganze Eingabezeilevon der
Standardeingabe, oder die aktuelle Zeile der Datei; daher haben obige zwei
Beispiele dieselbe Wirkung;
\item[\${\it n}] enthält das {\it n}-te Feld (Wort) der aktuellen Zeile; 
{\it n} $\in$ [1{\ldots} 255];
\item[\$NF] enthält das letzte Wort der Zeile;
\item[NF] (number of fields) Anzahl der Worte der aktuellen Zeile;
\item[NR] (line number) Zeilennummer;
\item[OFS] (output field seperator) enthält das Feldtrennzeichen für die
Ausgabe;
\end{description}

gawk `\{print ``Insgesamt'', NF, ``Worte, das letzte ist: ``,\$NF\}'\\
gibt die Anzahl der Wörter in der Zeile und das letzte Wort aus;

\subsubsection*{Formatierte Ausgabe}
{\bf printf} (print formatted) gibt die Variablen in der gemäß der
Formatanweisung entsprechenden Weise aus; jede Formatanweisung beginnt mit
einem \%\\
{\bf printf ({\it formatanweisung, Variable(n)}}\\
z.B.:\\
gawk `\{printf(``\%d$\backslash$t\%d$\backslash$n'', \$1,\$2)\}'\\
gibt die Variablen \$1 und \$2 getrennt durch einen Tab aus und macht einen
Zeilenvorschub;
%
\paragraph{Typzeichen:}
\begin{description}
\item[d] die Variable wird als dezimale Ganzzahl dargestellt;
\item[i] dezimale Ganzzahl;
\item[u] (unsigned) Ganzzahl ohne Vorzeichen;
\item[o] (otale) Ganzzahl;
\item[x] hexadezimale Ganzzahl, 10 bis 15 werden durch a bis f dargestellt;
\item[X] hexadezimale Ganzzahl, 10 bis 15 werden durch A bis F dargestellt;
\item[f] Vorzeichenbehaftete Darstellung der Form [-]dddd.dddd
\item[c] einzelnes Zeichen;
\item[s] Zeichenkette;
\end{description}
%
\paragraph{Ersatzdarstellungen für nicht druckbare Zeichen:}
\begin{description}
\item[$\backslash\backslash$] der backslash;
\item[$\backslash$a] das Alarmsignal (beep);
\item[$\backslash$b] backspace;
\item[$\backslash$r] Wagenvorlauf;
\item[$\backslash$f] (formfeed) Seitenvorschub;
\item[$\backslash$t] Tabulatorschritt;
\item[$\backslash$v] vertikaler  Vorschub;
\item[$\backslash$n] Zeilenvorschub;
\item[$\backslash$c] Unterdrücken des Zeilenvorschubes;
\end{description}

\subsection{Muster von gawk-Programmen}
\subsubsection*{Vergleichsausdrücke}
erfolgt der Vergleich nur zwischen Zahlen, so wird er numerisch
durchgeführt, ansonsten werden Zeichenketten verglichen; z.B.: {\it
``Hamburg''} $<$ {\it``München''} stimmt, da der ASCII-Code von H kleiner ist als
der von M;
\begin{description}
\item[$<$] kleiner als;
\item[$<=$] größer gleich als;
\item[==] Gleichheit;
\item[!=] Ungleichheit;
\item[$>=$] größer gleich;
\item[$>$] größer;
\item[\~] Mustervergleich;
\item[!\~] verneinter Mustervergleich;
\end{description}
z.B.:\\
gawk `\$0 $>=$ 22'\\
plappert jede Zeichenkette, deren Zahlenwert größer als 22 ist nach;\\
gawk `\$0 $>=$ 22 \{print\}'\\
macht genau das gleiche;\\
gawk `/Anne Hektor/'\\
plappert alle Zeilen in denen der Name steht nach;\\
gawk `\$0 ~ ``Anne Hektor''\{print\}'\\
macht genau das gleiche;\\


\begin{description}
\item[/{\it zeichenkettenmuster}/] das zwischen den slashes stehende Muster;
z.B.: /Aaanne Hektor/
\end{description}


\begin{description}
\item[]
\end{description}

\begin{description}
\item[]
\end{description}

\typeout{}
\typeout{copyright by Thomas Poetsch, 9.; Marktg. 8-10/22}
\typeout{}


\end{document}
