Grundlegende Ueberarbeitung
This commit is contained in:
		| @@ -63,7 +63,8 @@ done | ||||
| echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen | ||||
| \end{listing} | ||||
| \normalsize | ||||
| TODO!!! | ||||
|  | ||||
| TODO!!! Daten aus Subshell hochreichen | ||||
|  | ||||
| Achtung! while ist eine Subshell - Daten m<>ssen hochgereicht werden. | ||||
|  | ||||
| @@ -339,8 +340,7 @@ Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit d | ||||
| \index{trap=\texttt{trap}|)}\index{Signal|)} | ||||
|  | ||||
|  | ||||
| \section{Chaoten: Dateien in zuf<75>llige Reihenfolge | ||||
| bringen}\label{chaoten}\index{Zufallszahlen|(} | ||||
| \section{Chaoten: Dateien in zuf<75>llige Reihenfolge bringen}\label{chaoten}\index{Zufallszahlen|(} | ||||
|  | ||||
| Wir wollen uns einen MP3-Player programmieren, der Alle MP3-Dateien aus einem | ||||
| bestimmten Verzeichnisbaum in zuf<75>lliger Reihenfolge abspielt. Damit dieses | ||||
| @@ -354,7 +354,7 @@ Das Problem ist, da | ||||
| k<EFBFBD>nnen. Auf Systemen, in denen die Datei \texttt{/dev/urandom} existiert, | ||||
| liefert uns der Kernel aber schon sehr zuf<75>llige Zeichenfolgen. Diese Folgen | ||||
| k<EFBFBD>nnen alle Zeichen enthalten, daher m<>ssen sie vor der Benutzung f<>r unsere | ||||
| Zwecke noch etwas 'bereinigt' werden. | ||||
| Zwecke noch etwas `bereinigt' werden. | ||||
|  | ||||
| Wie das aussieht, wenn es fertig ist, sieht man im folgenden Skript: | ||||
|  | ||||
| @@ -379,13 +379,13 @@ ignorieren Gro | ||||
| \end{listingcont} | ||||
| \normalsize | ||||
| \begin{flushright} | ||||
| Hier ist der 'magische Teil'. Mit dem \texttt{echo} wird die Ausgabe einer Pipe | ||||
| Hier ist der `magische Teil'. Mit dem \texttt{echo} wird die Ausgabe einer Pipe | ||||
| ausgegeben, gefolgt von dem aktuellen Dateinamen. Diese Pipe enth<74>lt ein | ||||
| \texttt{tr}, der alle ungewollten Zeichen (alles, was kein Textzeichen ist) aus | ||||
| einem Datenstrom entfernt. Die Daten erh<72>lt \texttt{tr} durch die | ||||
| \texttt{<}-Umleitung aus oben genannter Datei. | ||||
|  | ||||
| Diese Datei liefert 'ohne Ende' Zeichen. Wir wollen aber nur acht Zeichen | ||||
| Diese Datei liefert `ohne Ende' Zeichen. Wir wollen aber nur acht Zeichen | ||||
| haben, die wir unserem Dateinamen voranstellen k<>nnen. Dazu benutzen wir das | ||||
| Kommando \texttt{dd} mit den angegebenen Parametern. Damit die Erfolgsmeldung | ||||
| von \texttt{dd} nicht die Ausgabe verunstaltet, lenken wir sie nach | ||||
| @@ -424,3 +424,79 @@ done | ||||
| \end{listingcont} | ||||
| \normalsize | ||||
| \index{Zufallszahlen|)} | ||||
|  | ||||
|  | ||||
|  | ||||
| \section{Wer suchet, der findet}\label{beispiele_suchen}\index{grep=\texttt{grep}|(textbf} | ||||
|  | ||||
|  | ||||
| \subsection{Prozesse suchen}\label{beispiele_suchen_prozesse}\index{ps=\texttt{ps}|(textbf}\index{pgrep=\texttt{pgrep}|(textbf} | ||||
|  | ||||
| Im Zusammenhang mit grep st<73><74>t fast jeder Shell-Skripter fr<66>her oder sp<73>ter auf | ||||
| das Problem, da<64> er irgendwas davon abh<62>ngig machen will, ob ein bestimmter | ||||
| Proze<EFBFBD> l<>uft oder nicht. Im Normalfall wird er zuerst folgendes ausprobieren, | ||||
| was aber oft (nicht immer) in die Hose gehen wird: | ||||
|  | ||||
| \texttt{ps aux | grep }\textit{prozessname}\texttt{ \&\& echo \dq}\textit{l<EFBFBD>uft | ||||
| schon}\texttt{\dq} | ||||
|  | ||||
| Der Grund daf<61>r ist, da<64> unter Umst<73>nden in der Ausgabe von \texttt{ps} auch | ||||
| das \texttt{grep}-Kommando samt Parameter (\textit{prozessname}) aufgelistet | ||||
| wird. So findet das \texttt{grep}-Kommando sich quasi selbst. | ||||
|  | ||||
| Abhilfe schafft entweder \texttt{pgrep} (\ref{pgrep}) oder das folgende | ||||
| Konstrukt: | ||||
|  | ||||
| \texttt{ps aux | grep \dq}\textit{[p]rozessname}\texttt{\dq~\&\& echo | ||||
| \dq}\textit{l<EFBFBD>uft schon}\texttt{\dq} | ||||
|  | ||||
| Das p ist jetzt als eine Zeichenmenge (regul<EFBFBD>rer Ausdruck) angegeben worden. | ||||
| Jetzt sucht \texttt{grep} also nach dem String \textit{prozessname}, in der | ||||
| Ausgabe von \texttt{ps} erscheint das \texttt{grep}-Kommando allerdings mit | ||||
| \textit{[p]rozessname} und wird somit ignoriert. | ||||
|  | ||||
| \index{ps=\texttt{ps}|)textbf}\index{pgrep=\texttt{pgrep}|)textbf} | ||||
|  | ||||
|  | ||||
| \subsection{Dateiinhalte suchen}\label{beispiele_suchen_dateien}\index{find=\texttt{find}|(textbf} | ||||
|  | ||||
| Ein weiterer wertvoller Trick, diesmal im Zusammenhang mit \texttt{find} ist | ||||
| folgendes Szenario: Es gibt ein Verzeichnis mit vielen Unterverzeichnissen, | ||||
| <EFBFBD>berall liegen Perl-Skripte und andere Dateien. Gesucht sind alle Dateien, in | ||||
| denen eine Zeile mit dem Inhalt `strict' vorkommt. Man k<>nnte jetzt | ||||
| folgendes versuchen: | ||||
|  | ||||
| \texttt{grep -r strict *} | ||||
|  | ||||
| Das f<>hrt allerdings dazu, da<64> alle Dateien durchsucht werden, nicht nur die | ||||
| Perl-Skripte. Diese tragen nach unserer Konvention\footnote{Perl-Skripte m<>ssen | ||||
| keine spezielle Extension haben, es sei aber um des Beispiels Willen mal | ||||
| angenommen.} die Extension `.pl'. Wir starten also eine rekursive Suche <20>ber | ||||
| alle Dateien, die dem Muster entsprechen: | ||||
|  | ||||
| \texttt{grep -r strict *.pl} | ||||
|  | ||||
| Das f<>hrt wieder nicht zu dem gew<65>nschten Ergebnis. Da die Unterverzeichnisse | ||||
| nicht die Extension `*.pl' tragen, werden sie nicht ber<65>cksichtigt. F<>r die | ||||
| Suche in Unterverzeichnissen ziehen wir \texttt{find} (Siehe Abschnitt | ||||
| \ref{find}) heran: | ||||
|  | ||||
| \texttt{find . -name \textbackslash*.pl -exec grep \{\} \textbackslash;} | ||||
|  | ||||
| Dieser Befehl gibt uns zwar die gefundenen Zeilen aus, nicht aber die Namen der | ||||
| Dateien. Es sieht f<>r \texttt{grep} so aus als ob nur eine Datei durchsucht | ||||
| w<EFBFBD>rde, da besteht keine Notwendigkeit den Namen anzugeben. Das ginge mit dem | ||||
| Parameter \texttt{-l}, allerdings w<>rden uns dann nur noch die Dateinamen | ||||
| angezeigt. Eine Ausgabe mit beiden Informationen erhalten wir mit dem folgenden | ||||
| Konstrukt: | ||||
|  | ||||
| \texttt{find . -name \textbackslash*.pl -exec grep strict /dev/null \{\} \textbackslash;} | ||||
|  | ||||
| Hier durchsucht \texttt{grep} nicht nur die gefundenen Dateien, sondern bei | ||||
| jedem Aufruf auch \texttt{/dev/null}, also den digitalen M<>lleimer der per | ||||
| Definition leer ist. Da es f<>r \texttt{grep} so aussieht als ob mehr als eine | ||||
| Datei durchsucht w<>rden, wird bei jeder Fundstelle sowohl der Dateiname als | ||||
| auch die gefundene Zeile ausgegeben. | ||||
|  | ||||
| \index{find=\texttt{find}|)textbf} | ||||
| \index{grep=\texttt{grep}|)textbf} | ||||
|   | ||||
| @@ -8,6 +8,9 @@ | ||||
| \item Unix In A Nutshell (\texttt{http://www.oreilly.com/catalog/unixnut3/}) | ||||
| \item Unix Power Tools (\texttt{http://www.oreilly.com/catalog/upt2/}) | ||||
| \item Von DOS nach Linux HOWTO (\texttt{http://www.linuxhaven.de/dlhp/HOWTO/DE-DOS-nach-Linux-HOWTO.html}) | ||||
|  | ||||
| TODO!!! Andere URL angeben (http://www.tldp.org...) | ||||
|  | ||||
| \item ... und eine Menge Skripte, die ich im Laufe der Zeit gelesen habe (das | ||||
| kann ich nur jedem empfehlen - es ist spannender als es sich anh<6E>rt...). | ||||
| \end{itemize} | ||||
|   | ||||
| @@ -24,28 +24,28 @@ haben. | ||||
|  | ||||
| \section{Die Tar-Br<42>cke} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! tar-Br<42>cke | ||||
|  | ||||
|  | ||||
| \section{Binaries inside} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! binaries inside | ||||
|  | ||||
| \subsection{Bin<EFBFBD>re Here-Dokumente} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! bin<69>re Here-Dokumente | ||||
|  | ||||
| \subsection{Schwanz ab!} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! Schwanz ab | ||||
|  | ||||
| \section{Dateien, die es nicht gibt} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! Dateien, die es nicht gibt | ||||
|  | ||||
| \subsection{Speichern in nicht existente Dateien} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! Speichern in nicht existente Dateien | ||||
|  | ||||
| \subsection{Subshell-Schleifen vermeiden} | ||||
|  | ||||
| @@ -83,7 +83,7 @@ nach der Vollendung der Schleife wieder den Wert 0 enth | ||||
| Das liegt daran, da<64> diese Schleife als Teil einer Pipe in einer Subshell | ||||
| ausgef<EFBFBD>hrt wird. Die Variable \texttt{\$count} steht damit in der Schleife | ||||
| praktisch nur lokal zur Verf<72>gung, sie wird nicht an das umgebende Skript | ||||
| 'hochgereicht'. | ||||
| `hochgereicht'. | ||||
|  | ||||
| Neben der Methode in \ref{daten_hochreichen} bietet sich hier eine viel | ||||
| einfachere L<>sung an: | ||||
| @@ -110,7 +110,7 @@ Standardeingabe der Schleife (und somit auf das \texttt{read}-Kommando) legen. | ||||
|  | ||||
| \subsection{Daten aus einer Subshell hochreichen}\label{daten_hochreichen} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! Daten aus einer Subshell hochreichen | ||||
|  | ||||
| \subsection{Dateien gleichzeitig lesen und schreiben} | ||||
|  | ||||
| @@ -145,3 +145,8 @@ grep "wichtig" <&3 > "$FILE" | ||||
|  | ||||
| Allerdings sollte man bei dieser Methode beachten, da<64> man im Falle eines | ||||
| Fehlers die Quelldaten verliert, da die Datei ja bereits gel<65>scht wurde. | ||||
|  | ||||
| \section{Auf der Lauer: Wachhunde} | ||||
|  | ||||
| TODO!!! Auf der Lauer: Wachhunde | ||||
|  | ||||
|   | ||||
							
								
								
									
										27
									
								
								shell.tex
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								shell.tex
									
									
									
									
									
								
							| @@ -104,15 +104,28 @@ | ||||
| \thispagestyle{empty}                  % eine Leerseite | ||||
| ~\vfill | ||||
| \footnotesize | ||||
| Copyright \copyright{} 2000-2003 Ronald Schaten (\texttt{ronald@schatenseite.de})\bigskip | ||||
| Copyright \copyright{} 2000-2004 Ronald Schaten (\texttt{ronald@schatenseite.de})\bigskip | ||||
|  | ||||
| \texttt{${}$Id${}$}\bigskip | ||||
| TODO: Vern<72>nftige Lizenz einsetzen!\bigskip | ||||
|  | ||||
| Die aktuellste Version dieses Dokumentes befindet sich im World Wide Web auf meiner Homepage (\texttt{http://www.schatenseite.de/}).\bigskip | ||||
| %\texttt{${}$Id${}$}\bigskip | ||||
|  | ||||
| Dieses Dokument ist entstanden, weil ich f<>r mich selbst eine kompakte <20>bersicht zu diesem Thema haben wollte. Ich beabsichtige nicht, damit in irgendeiner Form Kommerz zu machen. Ich stelle es frei zur Verf<72>gung, in der Hoffnung, da<64> andere Leute daraus vielleicht einen Nutzen ziehen k<>nnen. \textbf{Aber ich <20>bernehme keine Garantie f<>r die Korrektheit der hier dargestellten Dinge.} Mit der Formulierung \textsl{'daraus vielleicht einen Nutzen ziehen k<>nnen'} meine ich nicht, da<64> dieses Dokument~---~oder Teile daraus~---~verkauft werden darf. \textbf{Dieses Dokument darf nur kostenlos weitergegeben werden.}\bigskip | ||||
| Die aktuellste Version dieses Dokumentes befindet sich im World Wide Web auf | ||||
| meiner Homepage (\texttt{http://www.schatenseite.de/}).\bigskip | ||||
|  | ||||
| Ich danke folgenden Personen, die mir bei der Durchsicht behilflich waren und durch ihre konstruktive Kritik zu Verbesserungen beigetragen haben (in chronologischer Reihenfolge ihres Eingreifens): | ||||
| Dieses Dokument ist entstanden, weil ich f<>r mich selbst eine kompakte | ||||
| <EFBFBD>bersicht zu diesem Thema haben wollte. Ich beabsichtige nicht, damit in | ||||
| irgendeiner Form Kommerz zu machen. Ich stelle es frei zur Verf<72>gung, in der | ||||
| Hoffnung, da<64> andere Leute daraus vielleicht einen Nutzen ziehen k<>nnen. | ||||
| \textbf{Aber ich <20>bernehme keine Garantie f<>r die Korrektheit der hier | ||||
| dargestellten Dinge.} Mit der Formulierung \textsl{`daraus vielleicht einen | ||||
| Nutzen ziehen k<>nnen'} meine ich nicht, da<64> dieses Dokument~---~oder Teile | ||||
| daraus~---~verkauft werden darf. \textbf{Dieses Dokument darf nur kostenlos | ||||
| weitergegeben werden.}\bigskip | ||||
|  | ||||
| Ich danke folgenden Personen, die mir bei der Durchsicht behilflich waren und | ||||
| durch ihre konstruktive Kritik zu Verbesserungen beigetragen haben (in | ||||
| chronologischer Reihenfolge ihres Eingreifens): | ||||
|  | ||||
| \begin{list}{$\bullet$}{\itemsep=-0.5cm} | ||||
| \item J<>rgen Ilse (\texttt{ilse@asys-h.de})\\ | ||||
| @@ -123,7 +136,9 @@ Ich danke folgenden Personen, die mir bei der Durchsicht behilflich waren und du | ||||
| \item Kai Th<54>ne (\texttt{kai.thoene@gmx.de})\\ | ||||
| \end{list} | ||||
|  | ||||
| Und ich bitte alle Leser, auf eventuelle Fehler zu achten und mich darauf aufmerksam zu machen. Auch abgesehen davon freue ich mich <20>ber jede R<>ckmeldung. | ||||
| Und ich bitte alle Leser, auf eventuelle Fehler zu achten und mich darauf | ||||
| aufmerksam zu machen. Auch abgesehen davon freue ich mich <20>ber jede | ||||
| R<EFBFBD>ckmeldung. | ||||
| \normalsize | ||||
| \newpage | ||||
| \pagenumbering{roman} | ||||
|   | ||||
| @@ -14,6 +14,7 @@ | ||||
| \texttt{\{ }\textsl{Befehl1}\texttt{ ; }\textsl{Befehl2}\texttt{; \}} & Befehlsblock; alle Befehle werden in der momentanen Shell ausgef<65>hrt, aber die Ausgaben werden behandelt, als ob nur ein Befehl ausgef<65>hrt w<>rde \tabularnewline\STRUT | ||||
| \textsl{Befehl1}\texttt{ | }\textsl{Befehl2} & Pipe\index{Pipe}, verwendet die Ausgabe von \textsl{Befehl1} als Eingabe f<>r \textsl{Befehl2} \tabularnewline\STRUT | ||||
| \textsl{Befehl1}\texttt{ `}\textsl{Befehl2}\texttt{`} & Befehls-Substitution, verwendet die Ausgabe von \textsl{Befehl2} als Argumente\index{Parameter}\index{Argument|see{Parameter}} f<>r \textsl{Befehl1} \tabularnewline\STRUT | ||||
| \textsl{Befehl1}\texttt{ \$(}\textsl{Befehl2}\texttt{)} & Befehls-Substitution, andere Schreibweise\tabularnewline\STRUT | ||||
| \textsl{Befehl1}\texttt{ \&\& }\textsl{Befehl2} & AND\index{AND}, f<>hrt zuerst \textsl{Befehl1} und dann (wenn \textsl{Befehl1} erfolgreich war) \textsl{Befehl2} aus\footnote{Einen <20>hnlichen Mechanismus kennt man aus verschiedenen Programmiersprachen unter dem Begriff \textsl{Kurzschlu<EFBFBD>auswertung}\index{Kurzschlu<EFBFBD>auswertung} bzw. \textsl{lazy evaluation}\index{Lazy Evaluation|see{Kurzschlu<EFBFBD>auswertung}}.} \tabularnewline\STRUT | ||||
| \textsl{Befehl1}\texttt{ || }\textsl{Befehl2} & OR\index{OR}, entweder \textsl{Befehl1} ausf<73>hren oder \textsl{Befehl2} (Wenn \textsl{Befehl1} nicht erfolgreich war) | ||||
| \end{longtable} | ||||
|   | ||||
| @@ -8,14 +8,13 @@ | ||||
|  \hline | ||||
|  \endlastfoot | ||||
|  | ||||
| \texttt{-A} \textit{n} & Gibt \textit{n} Zeilen nach einer Fundstelle aus \tabularnewline\STRUT | ||||
| \texttt{-B} \textit{n} & Gibt \textit{n} Zeilen vor einer Fundstelle aus \tabularnewline\STRUT | ||||
| \texttt{-C} & Gibt einen Kontext von zwei Zeilen vor und nach einer Fundstelle aus \tabularnewline\STRUT | ||||
| \texttt{-}\textit{n} & Gibt einen Kontext von \textit{n} Zeilen vor und nach einer Fundstelle aus \tabularnewline\STRUT | ||||
| \texttt{-E} & Benutzt erweiterte regul<75>re Ausdr<EFBFBD>cke \tabularnewline\STRUT | ||||
| \texttt{-F} & Der Suchbegriff wird nicht als regul<75>rer Ausdruck, sondern als `fixed String' benutzt \tabularnewline\STRUT | ||||
| \texttt{-c} & Gibt f<>r jede durchsuchte Datei die Anzahl der Fundstellen aus \tabularnewline\STRUT | ||||
| \texttt{-h} & Unterdr<EFBFBD>ckt die Angabe der Dateinamen \tabularnewline\STRUT | ||||
| \texttt{-f} & Liest die Suchbegriffe Zeile f<>r Zeile aus einer Textdatei \tabularnewline\STRUT | ||||
| \texttt{-i} & Ignoriert die Unterscheidung zwischen Gro<72>- und Kleinschreibung \tabularnewline\STRUT | ||||
| \texttt{-l} & Gibt nur die Dateinamen aus \tabularnewline\STRUT | ||||
| \texttt{-n} & Gibt zus<75>tzlich die Zeilennummern der Fundstellen aus \tabularnewline\STRUT | ||||
| \texttt{-e} & PLATZHALTER - TODO!!! | ||||
| \texttt{-q} & Gibt die Fundstellen nicht aus, am Exitcode ist zu erkennen ob etwas gefunden wurde \tabularnewline\STRUT | ||||
| \texttt{-v} & Findet alle Zeilen, in denen das Suchmuster \emph{nicht} vorkommt | ||||
| \end{longtable} | ||||
|   | ||||
| @@ -38,7 +38,7 @@ Problem und L | ||||
| Um sowohl das Finden eines Werkzeugs zu einem gegebenen Problem als auch das | ||||
| Finden einer Beschreibung zu einem gegebenen Werkzeug zu vereinfachen, und um | ||||
| die oben beschriebene n:m-Beziehung abzubilden, werden hier also zun<75>chst | ||||
| typische Aufgaben beschrieben. Diese enthalten 'Links' zu den in Frage | ||||
| typische Aufgaben beschrieben. Diese enthalten `Links' zu den in Frage | ||||
| kommenden Werkzeugen. Danach gibt es eine alphabetische Aufz<66>hlung der | ||||
| wichtigsten Kommandos. | ||||
|  | ||||
| @@ -46,28 +46,52 @@ wichtigsten Kommandos. | ||||
|  | ||||
| \subsection{Ein- und Ausgabe}\label{ein_und_ausgabe} | ||||
|  | ||||
| Beinahe jedes Skript verwendet in irgendeiner Form die Ein- oder Ausgabe. Sei | ||||
| Praktisch jedes Skript verwendet in irgendeiner Form die Ein- oder Ausgabe. Sei | ||||
| es in interaktiver Art auf dem Terminal, oder im Hintergrund auf Dateien. | ||||
| Einige grundlegende Kommandos in diesem Zusammenhang werden hier vorgestellt. | ||||
|  | ||||
| cat | ||||
| echo | ||||
| head | ||||
| printf | ||||
| read | ||||
| tail | ||||
| An dieser Stelle sei darauf hingewiesen, da<64> es auf unixoiden Systemen nicht | ||||
| nur Dateien im Sinne von `ein paar Kilobytes Daten, die irgendwo auf der | ||||
| Festplatte rumliegen' gibt. Vielmehr findet man hier die Ger<65>te des Rechners | ||||
| als Dateien unter /dev. Der Kernel selbst stellt Schnittstellen in Form von | ||||
| virtuellen Dateien unter /proc (ab Kernel 2.6 auch unter /sys) zur Verf<72>gung. | ||||
| Und Schlu<6C>endlich k<>nnen Prozesse sich sogenannte Named Pipes\index{Named Pipe} | ||||
| anlegen, in die sie schreiben oder aus denen sie lesen. | ||||
|  | ||||
| Diese Kommandos sind also universell n<>tzlich, nicht nur im Zusammenhang mit | ||||
| Dateien auf der Festplatte. | ||||
|  | ||||
| \begin{itemize} | ||||
| \item \texttt{cat} (\ref{cat}): Dateien einlesen und ausgeben | ||||
| \item \texttt{echo} (\ref{echo}): Daten ausgeben | ||||
| \item \texttt{grep} (\ref{grep}): In Dateien suchen | ||||
| \item \texttt{head} (\ref{head}): Dateianfang ausgeben | ||||
| \item \texttt{printf} (\ref{printf}): formatierte Datenausgabe | ||||
| \item \texttt{read} (\ref{read}): Zeilen einlesen | ||||
| \item \texttt{sort} (\ref{sort}): Zeilenweises Sortieren | ||||
| \item \texttt{tail} (\ref{tail}): Dateiende ausgeben | ||||
| \end{itemize} | ||||
|  | ||||
|  | ||||
| \subsection{Pfade und Dateien}\label{pfade_und_dateien} | ||||
|  | ||||
| Eine der Hautaufgaben von Shell-Skripten ist nat<61>rlich das Hantieren mit | ||||
| Eine der Hauptaufgaben von Shell-Skripten ist nat<61>rlich das Hantieren mit | ||||
| Dateien. In diesem Abschnitt geht es allerdings nicht um den Umgang mit | ||||
| Dateiinhalten, sondern vielmehr werden einige n<>tzliche Tools im Umgang mit | ||||
| Dateien an sich vorgestellt. | ||||
|  | ||||
| basename | ||||
| dirname | ||||
| touch | ||||
| Auch hier gilt nat<61>rlich der Hinweis aus Abschnitt \ref{ein_und_ausgabe}: Eine | ||||
| Datei kann viel mehr sein als nur ein paar Daten im Filesystem. | ||||
|  | ||||
| \begin{itemize} | ||||
| \item \texttt{basename} (\ref{basename}): Den Namen einer Datei (ohne Pfad) ausgeben | ||||
| \item \texttt{cp} (\ref{cp}): Dateien kopieren | ||||
| \item \texttt{dirname} (\ref{dirname}): Den Pfad zu einer Datei (ohne den Namen) ausgeben | ||||
| \item \texttt{find} (\ref{find}): Dateien suchen | ||||
| \item \texttt{mv} (\ref{mv}): Dateien verschieben | ||||
| \item \texttt{rm} (\ref{rm}): Dateien l<>schen | ||||
| \item \texttt{touch} (\ref{touch}): Eine leere Datei anlegen, bzw. das Zugriffsdatum einer Datei <20>ndern | ||||
| \item \texttt{xargs} (\ref{xargs}): Ausgaben eines Kommandos als Parameter eines anderen Kommandos benutzen | ||||
| \end{itemize} | ||||
|  | ||||
|  | ||||
| \subsection{Pipes manipulieren}\label{pipes_manipulieren}\index{Pipe|(textbf} | ||||
| @@ -76,53 +100,93 @@ Das Konzept der Pipes (R | ||||
| (\ref{befehlsformen}) vorgestellt. Im wesentlichen besteht es darin, da<64> Daten | ||||
| von einem Programm an ein anderes weitergeleitet werden. Auf diese Weise | ||||
| entsteht eine sogenannte \textit{Pipeline}\index{Pipeline} aus mehreren | ||||
| Kommandos. | ||||
| Kommandos. Einige Kommandos sind f<>r den Einsatz in einem solchen Konstrukt | ||||
| pr<EFBFBD>destiniert, obwohl die meisten auch alleine eingesetzt werden k<>nnen. | ||||
|  | ||||
| Einige Kommandos sind f<>r den Einsatz in einem solchen Konstrukt pr<70>destiniert, | ||||
| obwohl die meisten auch alleine eingesetzt werden k<>nnen. Einige dieser | ||||
| Tools sollen im Folgenden vorgestellt werden. | ||||
| <EFBFBD>brigens gibt es einen goldenen Merksatz f<>r die Auswahl einiger dieser Tools: | ||||
|  | ||||
| Benutze nicht \texttt{awk}, wenn Du \texttt{sed} benutzen kannst. Benutze | ||||
| nicht \texttt{sed}, wenn Du \texttt{grep} benutzen kannst. Benutze nicht | ||||
| \texttt{grep}, wenn Du \texttt{cut} benutzen kannst. | ||||
|  | ||||
| Der Grund daf<61>r liegt darin, da<64> diese Programme bei jedem Einsatz gestartet | ||||
| und ausgef<65>hrt werden m<>ssen. Und man sollte sich um der Performance willen den | ||||
| kleinsten geeigneten Hammer nehmen. | ||||
|  | ||||
| \begin{itemize} | ||||
| \item \texttt{cut} (\ref{cut}): Teile einer Zeile ausschneiden | ||||
| \item \texttt{grep} (\ref{grep}): In einer Pipe suchen | ||||
| \item \texttt{sed} (\ref{sed}): In einer Pipe editieren | ||||
| \item \texttt{awk} (\ref{awk}): In einer Pipe editieren | ||||
| \item \texttt{sort} (\ref{sort}): Zeilenweises Sortieren | ||||
| \item \texttt{tee} (\ref{tee}): Datenstrom in einer Datei protokollieren | ||||
| \item \texttt{wc} (\ref{wc}): Zeilen, W<>rter oder Zeichen z<>hlen | ||||
| \end{itemize} | ||||
|  | ||||
| grep | ||||
| sed | ||||
| awk | ||||
| sort | ||||
| tee | ||||
| wc | ||||
| \index{Pipe|)} | ||||
|  | ||||
|  | ||||
| \subsection{Proze<EFBFBD>management}\label{prozessmanagement} | ||||
|  | ||||
| TODO!! | ||||
| Oft werden Shell-Skripte benutzt um Prozesse zu steuern oder zu <20>berwachen. So | ||||
| werden Systemdienste <20>blicherweise <20>ber die Init-Skripte hoch- oder | ||||
| heruntergefahren. Es ist auch nicht sonderlich schwer, mit einem Skript einen | ||||
| `Wachhund' zu implementieren, der regelm<6C><6D>ig kontrolliert ob ein Proze<7A> noch | ||||
| l<EFBFBD>uft und ihn bei bedarf nachstartet. | ||||
|  | ||||
| ps | ||||
| pgrep | ||||
| pkill | ||||
| kill | ||||
| F<EFBFBD>r Aufgaben in diesem Bereich stehen unter anderem die folgenden Kommandos zur | ||||
| Verf<EFBFBD>gung. | ||||
|  | ||||
| \begin{itemize} | ||||
| \item \texttt{kill} (\ref{kill}): Signal an einen Proze<7A> schicken | ||||
| \item \texttt{killall} (\ref{killall}): Signal an mehrere Prozesse schicken | ||||
| \item \texttt{ps} (\ref{ps}): Proze<7A>liste ausgeben | ||||
| \item \texttt{pgrep} (\ref{pgrep}): Bestimmte Prozesse suchen | ||||
| \item \texttt{pkill} (\ref{pkill}): Bestimmte Prozesse t<>ten | ||||
| \end{itemize} | ||||
|  | ||||
|  | ||||
| \section{... und H<>mmer}\label{haemmer} | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{awk}\label{awk}\index{awk=\texttt{awk}|(textbf} | ||||
|  | ||||
| \subsection{awk} | ||||
| TODO!!! awk | ||||
|  | ||||
| TODO!! | ||||
| \index{awk=\texttt{awk}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{basename}\label{basename}\index{basename=\texttt{basename}|(textbf} | ||||
|  | ||||
| Dem Tool \texttt{basename} wird als Parameter ein Pfad zu einer Datei | ||||
| <EFBFBD>bergeben. Der in der Angabe enthaltene Pfad wird abgeschnitten, nur der Name | ||||
| der eigentlichen Datei wird zur<75>ckgegeben. | ||||
| der eigentlichen Datei wird zur<75>ckgegeben. Siehe auch \texttt{dirname} | ||||
| (\ref{dirname}). | ||||
|  | ||||
| \index{basename=\texttt{basename}|)} | ||||
|  | ||||
|  | ||||
| \subsection{bc} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{bc}\label{bc}\index{bc=\texttt{bc}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| Mit dem Kommando \texttt{bc} verf<72>gt die Shell praktisch <20>ber einen | ||||
| Taschenrechner. Die Man-Page verr<72>t, da<64> es sich hierbei um ein erstaunlich | ||||
| komplexes Programm handelt, in der Praxis findet man allerdings meistens | ||||
| einfache Anwendungen wie das inkrementieren einer Laufvariable (\texttt{i=`bc | ||||
| \$i + 1`}). | ||||
|  | ||||
| Bei Multiplikationen ist darauf zu achten, da<64> der Stern in der Shell eine | ||||
| Sonderbedeutung hat, er mu<6D> also gequoted werden: \texttt{i=`bc \$i | ||||
| \textbackslash{}* 3`}. | ||||
|  | ||||
| Eine andere M<>glichkeit f<>r einfache Rechnungen besteht in der sogenannten | ||||
| Arithmetik-Expansion (Siehe \ref{arithmetikexpansion}). | ||||
|  | ||||
| \index{bc=\texttt{bc}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{cat}\label{cat}\index{cat=\texttt{cat}|(textbf} | ||||
|  | ||||
| Auch \texttt{cat} ist ein oft unterbewertetes Tool. Seine Aufgabe besteht zwar | ||||
| @@ -139,24 +203,25 @@ Au | ||||
| Daten an ein Programm <20>bergeben, das nur von der Standardeingabe lesen kann | ||||
| (Filter). | ||||
|  | ||||
| \texttt{cat} verf<72>gt <20>ber eine Reige von Parametern, um die Ausgabe zu | ||||
| formatieren, so k<>nnen mit \texttt{-n} bzw. \texttt{-b} die Zeilen nummeriert | ||||
| \texttt{cat} verf<72>gt <20>ber eine Reihe von Parametern, um die Ausgabe zu | ||||
| formatieren, so k<>nnen mit \texttt{-n} bzw. \texttt{-b} die Zeilen numeriert | ||||
| werden, oder mit \texttt{-s} mehrere Zeilen zu einer einzigen zusammengefa<66>t | ||||
| werden. | ||||
|  | ||||
| \index{cat=\texttt{cat}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{chpasswd}\label{script}\index{chpasswd=\texttt{chpasswd}|(textbf} | ||||
|  | ||||
| Mit diesem Kommando bietet sich dem Administrator des Systems die M<>glichkeit, | ||||
| scriptgesteuert die Pa<50>w<EFBFBD>rter f<>r neue Benutzer zu vergeben. Manuell <20>ndert man | ||||
| ein Pa<50>wort mit dem Kommando \texttt{passwd}\index{passwd=\texttt{passwd}}, | ||||
| allerdings l<>scht (flusht) dieses Programm die Standard-Eingabe, bevor es das | ||||
| neue Pa<50>wort erwartet. Somit lassen sich Pa<50>w<EFBFBD>rter mit \texttt{passwd} nur | ||||
| interaktiv <20>ndern\footnote{Es gibt auch einen anderen Weg: Man kann | ||||
| \texttt{passwd} auch mittels \texttt{expect} fernsteuern. Allerdings ist diese | ||||
| Methode weniger elegant.}. | ||||
| Mit diesem Kommando bietet sich dem Administrator des Systems die | ||||
| M<EFBFBD>g\-lich\-keit, scriptgesteuert die Pa<50>w<EFBFBD>rter f<>r neue Benutzer zu vergeben. | ||||
| Manuell <20>ndert man ein Pa<50>wort mit dem Kommando | ||||
| \texttt{passwd}\index{passwd=\texttt{passwd}}, allerdings l<>scht (flusht) | ||||
| dieses Programm die Standard-Eingabe, bevor es das neue Pa<50>wort erwartet. Somit | ||||
| lassen sich Pa<50>w<EFBFBD>rter mit \texttt{passwd} nur interaktiv <20>ndern\footnote{Es | ||||
| gibt auch einen anderen Weg: Man kann \texttt{passwd} auch mittels | ||||
| \texttt{expect} fernsteuern. Allerdings ist diese Methode weniger elegant.}. | ||||
|  | ||||
| Das Kommando wird in der Form | ||||
|  | ||||
| @@ -171,14 +236,48 @@ Allerdings sollte dabei aus Sicherheitsgr | ||||
| diese Datei nicht allgemein lesbar ist. | ||||
|  | ||||
| \index{chpasswd=\texttt{chpasswd}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{cp}\label{cp}\index{cp=\texttt{cp}|(textbf} | ||||
|  | ||||
| Mit \texttt{cp} werden Dateien kopiert. Die wichtigsten Optionen im | ||||
| Zusammenhang mit Skripten sind \texttt{-f} und \texttt{-R}. Ersteres erzwingt | ||||
| (force) das Kopieren, falls an der Zielstelle schon Dateien existieren werden | ||||
| sie <20>berschrieben. Letzteres erm<72>glicht ein rekursives Kopieren. | ||||
| Verzeichnisse~---~auch leere~---~k<>nnen nur mit \texttt{-R} kopiert werden. | ||||
|  | ||||
| \index{cp=\texttt{cp}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{cut}\label{cut}\index{cut=\texttt{cut}|(textbf} | ||||
|  | ||||
| Wie der Name (fast) schon sagt, kann man mit diesem Kommando Zeilen | ||||
| zerschneiden. Mit den Parametern \texttt{-c} (Character) oder \texttt{-f} | ||||
| (Field) wird bestimmt, in welcher Einheit die Schnittstellen abgesteckt werden | ||||
| sollen. Falls die Zeilen in Felder zerteilt werden sollen, kann zus<75>tzlich | ||||
| mittels \texttt{-d} der Delimiter, also das Trennzeichen bestimmt werden. Wird | ||||
| das nicht explizit getan, wird der Tabulator benutzt. | ||||
|  | ||||
| Dieser Definition folgt die Angabe des zu behaltenden Bereichs. Daf<61>r kann eins | ||||
| der Formate N, N-, N-M oder -M benutzt werden. | ||||
|  | ||||
| \LTXtable{\textwidth}{tab_kommandos_cut_beispiele.tex} | ||||
|  | ||||
| \index{cut=\texttt{cut}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{dirname}\label{dirname}\index{dirname=\texttt{dirname}|(textbf} | ||||
|  | ||||
| Analog zu \texttt{basename} gibt \texttt{dirname} nur die Pfad-Komponente einer | ||||
| angegebenen Datei zur<75>ck. | ||||
| Analog zu \texttt{basename} (\ref{basename}) gibt \texttt{dirname} nur die | ||||
| Pfad-Komponente einer angegebenen Datei zur<75>ck. | ||||
|  | ||||
| \index{dirname=\texttt{dirname}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{echo}\label{echo}\index{echo=\texttt{echo}|(textbf} | ||||
|  | ||||
| Dies ist wohl der grundlegendste Befehl, der in einem Skript verwendet werden | ||||
| @@ -196,49 +295,42 @@ der Praxis oft als sehr hilfreich: | ||||
| \index{echo=\texttt{echo}|)} | ||||
|  | ||||
|  | ||||
| \subsection{expr} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{expr}\label{expr}\index{expr=\texttt{expr}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! expr | ||||
|  | ||||
| \index{expr=\texttt{expr}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{find}\label{find}\index{find=\texttt{find}|(textbf} | ||||
|  | ||||
| TODO!!! find | ||||
|  | ||||
| Siehe auch: Abschnitt \ref{beispiele_suchen_dateien}. | ||||
|  | ||||
| \index{find=\texttt{find}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{grep}\label{grep}\index{grep=\texttt{grep}|(textbf} | ||||
|  | ||||
| Das Tool \texttt{grep} stammt aus dem Standard-Repertoire eines jeden | ||||
| Systemadministrators. Mit seiner Hilfe kann in einer oder mehreren Dateien, | ||||
| Sys\-tem\-ad\-mi\-ni\-stra\-tors. Mit seiner Hilfe kann in einer oder mehreren Dateien, | ||||
| oder eben auch in einem Datenstrom nach dem Auftreten bestimmter regul<75>rer | ||||
| Ausdr<EFBFBD>cke (siehe \ref{mustererkennung}) gesucht werden. | ||||
|  | ||||
| TODO!!! | ||||
|  | ||||
| Die folgende Tabelle stellt einige der vielen Parameter vor: | ||||
|  | ||||
| \LTXtable{\textwidth}{tab_kommandos_grep_parameter.tex} | ||||
|  | ||||
| Im Zusammenhang mit grep st<73><74>t fast jeder Shell-Skripter fr<66>her oder sp<73>ter auf | ||||
| das Problem, da<64> er irgendwas davon abh<62>ngig machen will, ob ein bestimmter | ||||
| Proze<EFBFBD> l<>uft oder nicht. Im Normalfall wird er zuerst folgendes ausprobieren, | ||||
| was aber oft (nicht immer) in die Hose gehen wird: | ||||
|  | ||||
| \texttt{ps aux | grep }\textit{prozessname}\texttt{ \&\& echo \dq}\textit{l<EFBFBD>uft | ||||
| schon}\texttt{\dq} | ||||
|  | ||||
| Der Grund daf<61>r ist, da<64> unter Umst<73>nden in der Ausgabe von \texttt{ps} auch | ||||
| das \texttt{grep}-Kommando samt Parameter (\textit{prozessname}) aufgelistet | ||||
| wird. So findet das \texttt{grep}-Kommando sich quasi selbst. | ||||
|  | ||||
| Abhilfe schafft das folgende Konstrukt: | ||||
|  | ||||
| \texttt{ps aux | grep \dq}\textit{[p]rozessname}\texttt{\dq~\&\& echo | ||||
| \dq}\textit{l<EFBFBD>uft schon}\texttt{\dq} | ||||
|  | ||||
| Das p ist jetzt als eine Zeichenmenge (regul<75>rer Ausdruck) angegeben worden. | ||||
| Jetzt sucht \texttt{grep} also nach dem String \textit{prozessname}, in der | ||||
| Ausgabe von \texttt{ps} erscheint das \texttt{grep}-Kommando allerdings mit | ||||
| \textit{[p]rozessname} und wird somit ignoriert. | ||||
| Siehe auch: Abschnitt \ref{beispiele_suchen}. | ||||
|  | ||||
| \index{grep=\texttt{grep}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{head}\label{head}\index{head=\texttt{head}|(textbf} | ||||
|  | ||||
| \texttt{head} ist das Gegenst<73>ck zu \texttt{tail} (Siehe \ref{tail}). Hier | ||||
| @@ -247,16 +339,71 @@ werden allerdings nicht die letzten Zeilen angezeigt, sondern die ersten. | ||||
| \index{head=\texttt{head}|)} | ||||
|  | ||||
|  | ||||
| \subsection{kill} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{kill}\label{kill}\index{kill=\texttt{kill}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! kill | ||||
|  | ||||
| <EFBFBD>brigens: Die landl<64>ufige Annahme ist, da<64> man mit dem | ||||
| \texttt{kill}-Kom\-man\-do Prozesse `umbringt'. Das ist zwar wahr, aber nicht | ||||
| die ganze Wahrheit. | ||||
|  | ||||
| \index{kill=\texttt{kill}|)} | ||||
|  | ||||
|  | ||||
| \subsection{printf} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{killall}\label{killall}\index{killall=\texttt{killall}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! killall | ||||
|  | ||||
| \index{killall=\texttt{killall}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{mv}\label{mv}\index{mv=\texttt{mv}|(textbf} | ||||
|  | ||||
| TODO!!! mv | ||||
|  | ||||
| \index{mv=\texttt{mv}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf} | ||||
|  | ||||
| TODO!!! pgrep | ||||
|  | ||||
| Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}. | ||||
|  | ||||
| \index{pgrep=\texttt{pgrep}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{pkill}\label{pkill}\index{pkill=\texttt{pkill}|(textbf} | ||||
|  | ||||
| TODO!!! pkill | ||||
|  | ||||
| \index{pkill=\texttt{pkill}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{printf}\label{printf}\index{printf=\texttt{printf}|(textbf} | ||||
|  | ||||
| TODO!!! printf | ||||
|  | ||||
| \index{printf=\texttt{printf}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{ps}\label{ps}\index{ps=\texttt{ps}|(textbf} | ||||
|  | ||||
| TODO!!! ps | ||||
|  | ||||
| Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}. | ||||
|  | ||||
| \index{ps=\texttt{ps}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{read}\label{read}\index{read=\texttt{read}|(textbf} | ||||
|  | ||||
| Mit dem Kommando \texttt{read} kann man Eingaben von der | ||||
| @@ -280,7 +427,9 @@ Leerzeichen in die Variable \texttt{var} ein. | ||||
|  | ||||
| Wenn nur eine bestimmte Zahl von Zeichen gelesen werden soll, kann diese durch | ||||
| den Parameter \texttt{-n} angegeben werden. Der Befehl \texttt{read -n 5 var} | ||||
| liest die ersten f<>nf Zeichen in die Variable \texttt{var} ein. | ||||
| liest die ersten f<>nf Zeichen in die Variable \texttt{var} ein. Demzufolge kann | ||||
| ein Skript durch ein \texttt{read -n 1} dazu gebracht werden, auf einen | ||||
| einzelnen Tastendruck~---~nicht zwingend ein Return~---~zu warten. | ||||
|  | ||||
| Mit dem Parameter \texttt{-p} kann man einen Prompt, also eine | ||||
| Eingabeaufforderung ausgeben lassen. \texttt{read -p \dq{}Gib was ein:\dq~var} | ||||
| @@ -308,6 +457,15 @@ Timeout oder ein EOF auf. | ||||
| \index{read=\texttt{read}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{rm}\label{rm}\index{rm=\texttt{rm}|(textbf} | ||||
|  | ||||
| TODO!!! rm | ||||
|  | ||||
| \index{rm=\texttt{rm}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{script}\label{script}\index{script=\texttt{script}|(textbf} | ||||
|  | ||||
| Dieses Kommando eignet sich vorz<72>glich f<>r das Debuggen fertiger Skripte. Man | ||||
| @@ -323,32 +481,45 @@ debuggen, da sowohl Ein- als auch Ausgaben in dem Logfile sichtbar sind. | ||||
| \index{script=\texttt{script}|)} | ||||
|  | ||||
|  | ||||
| \subsection{sed} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{sed}\label{sed}\index{sed=\texttt{sed}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! sed | ||||
|  | ||||
| \index{sed=\texttt{sed}|)} | ||||
|  | ||||
|  | ||||
| \subsection{seq} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{seq}\label{seq}\index{seq=\texttt{seq}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! seq | ||||
|  | ||||
| \index{seq=\texttt{seq}|)} | ||||
|  | ||||
|  | ||||
| \subsection{sleep} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{sleep}\label{sleep}\index{sleep=\texttt{sleep}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! sleep | ||||
|  | ||||
| \index{sleep=\texttt{sleep}|)} | ||||
|  | ||||
|  | ||||
| \subsection{sort} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{sort}\label{sort}\index{sort=\texttt{sort}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! sort | ||||
|  | ||||
| \index{sort=\texttt{sort}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{tail}\label{tail}\index{tail=\texttt{tail}|(textbf} | ||||
|  | ||||
| Der Befehl \texttt{tail} gibt die letzten zehn Zeilen einer Datei aus. Wenn | ||||
| kein Dateiname (oder ein \texttt{-}) angegeben wird, liest \texttt{tail} von | ||||
| der Standard-Eingabe. Man kann die Anzahl der ausgegebenen Zeilen mit dem | ||||
| Parameter \texttt{-l} steuern. | ||||
| Parameter \texttt{-n} steuern. | ||||
|  | ||||
| Mit dem Parameter \texttt{-f} (follow) gibt \texttt{tail} neue Zeilen aus, | ||||
| sobald sie an die Datei angeh<65>ngt werden. | ||||
| @@ -356,11 +527,15 @@ sobald sie an die Datei angeh | ||||
| \index{tail=\texttt{tail}|)} | ||||
|  | ||||
|  | ||||
| \subsection{tee} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{tee}\label{tee}\index{tee=\texttt{tee}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! tee | ||||
|  | ||||
| \index{tee=\texttt{tee}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{touch}\label{touch}\index{touch=\texttt{touch}|(textbf} | ||||
|  | ||||
| Mit diesem Kommando kann man einerseits Dateien anlegen wenn sie nicht | ||||
| @@ -380,11 +555,25 @@ Referenzdatei angepa | ||||
| \index{touch=\texttt{touch}|)} | ||||
|  | ||||
|  | ||||
| \subsection{wc} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{wc}\label{wc}\index{wc=\texttt{wc}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! wc | ||||
|  | ||||
| \index{wc=\texttt{wc}|)} | ||||
|  | ||||
|  | ||||
| \subsection{who} | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{who}\label{who}\index{who=\texttt{who}|(textbf} | ||||
|  | ||||
| TODO!!! | ||||
| TODO!!! who | ||||
|  | ||||
| \index{who=\texttt{who}|)} | ||||
|  | ||||
|  | ||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||
| \subsection{xargs}\label{xargs}\index{xargs=\texttt{xargs}|(textbf} | ||||
|  | ||||
| TODO!!! xargs | ||||
|  | ||||
| \index{xargs=\texttt{xargs}|)} | ||||
|   | ||||
| @@ -247,6 +247,23 @@ erzeugen. | ||||
| \index{Klammer-Expansion|)} | ||||
|  | ||||
|  | ||||
| \section{Arithmetik-Expansion\label{arithmetikexpansion}\index{Arithmetik-Expansion|(textbf}} | ||||
|  | ||||
| Auch hier werden Klammern expandiert. Allerdings gleich doppelte Klammern. Mit | ||||
| einem Konstrukt in der Form \texttt{i=\$((\$i + 1))} k<>nnen einfache | ||||
| Berechnungen angestellt werden. | ||||
|  | ||||
| Dabei wird der Ausdruck in den Klammern bewertet als ob er in doppelten | ||||
| Anf<EFBFBD>hrungszeichen stehen w<>rde. Das bedeutet zum Einen, da<64> man auch mit | ||||
| Variablen rechnen kann, zum anderen macht es das Quoten des Sternchens | ||||
| <EFBFBD>berfl<EFBFBD>ssig. | ||||
|  | ||||
| F<EFBFBD>r komplexere Berechnungen steht das Tool \texttt{bc} (Siehe Abschnitt | ||||
| \ref{bc}) zur Verf<72>gung. | ||||
|  | ||||
| \index{Arithmetik-Expansion|)} | ||||
|  | ||||
|  | ||||
| \section{Programmablaufkontrolle} | ||||
|  | ||||
| Bei der Shell-Programmierung verf<72>gt man <20>ber <20>hnliche Konstrukte wie bei anderen Programmiersprachen, um den Ablauf des Programms zu steuern. Dazu geh<65>ren Funktionsaufrufe, Schleifen, Fallunterscheidungen und dergleichen.\nopagebreak | ||||
| @@ -401,8 +418,8 @@ In anderen Sprachen kann man mit der | ||||
| Laufvariable\index{Laufvariable} <20>ber einen bestimmten Wertebereich iterieren | ||||
| lassen (\texttt{for i = 1 to 100...next}). Da das mit der \texttt{for}-Schleife | ||||
| der Shell nicht geht\footnote{Auf einigen Systemen steht f<>r diesen Zweck auch | ||||
| das Kommando \texttt{seq}\index{seq=\texttt{seq}} zur Verf<72>gung.}, | ||||
| ersetzt man die Funktion durch geschickte Anwendung der | ||||
| das Kommando \texttt{seq} (Siehe Abschnitt \ref{seq}) zur Verf<72>gung.}, ersetzt | ||||
| man die Funktion durch geschickte Anwendung der | ||||
| \texttt{while}-Schleife:\nopagebreak | ||||
|  | ||||
| \LTXtable{\textwidth}{tab_beisp_while_for.tex} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user