Viele Aenderungen
This commit is contained in:
		| @@ -27,6 +27,7 @@ haben. | |||||||
| TODO!!! tar-Br<42>cke | TODO!!! tar-Br<42>cke | ||||||
|  |  | ||||||
| %ssh 192.168.2.1 tar clf - / | (cd /mnt; tar xf - ) | %ssh 192.168.2.1 tar clf - / | (cd /mnt; tar xf - ) | ||||||
|  | %tar cf - $j | rsh $i "(mkdir -p $PWD ;cd $PWD; tar xf -)" | ||||||
|  |  | ||||||
|  |  | ||||||
| \section{Binaries inside} | \section{Binaries inside} | ||||||
| @@ -49,7 +50,7 @@ TODO!!! Dateien, die es nicht gibt | |||||||
|  |  | ||||||
| TODO!!! Speichern in nicht existente Dateien | TODO!!! Speichern in nicht existente Dateien | ||||||
|  |  | ||||||
| \subsection{Subshell-Schleifen vermeiden} | \subsection{Subshell-Schleifen vermeiden}\label{subshellschleifen} | ||||||
|  |  | ||||||
| Wir wollen ein Skript schreiben, das die \texttt{/etc/passwd} liest und dabei | Wir wollen ein Skript schreiben, das die \texttt{/etc/passwd} liest und dabei | ||||||
| z<EFBFBD>hlt, wie viele Benutzer eine UID kleiner als 100 haben. | z<EFBFBD>hlt, wie viele Benutzer eine UID kleiner als 100 haben. | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								shell.tex
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								shell.tex
									
									
									
									
									
								
							| @@ -23,9 +23,15 @@ | |||||||
| \usepackage{german}                    % deutsches Paket f<>r Umlaute | \usepackage{german}                    % deutsches Paket f<>r Umlaute | ||||||
| \usepackage[latin1]{inputenc}          % Codepage latin1 | \usepackage[latin1]{inputenc}          % Codepage latin1 | ||||||
|  |  | ||||||
| %\usepackage{graphicx}                  % Grafikpaket f<>r Bilder laden | \usepackage{mathptmx}                  % Andere Schriften benutzen | ||||||
|  | \usepackage[scaled=.90]{helvet} | ||||||
|  | \usepackage{courier} | ||||||
|  |  | ||||||
|  | %\usepackage[dvips]{graphicx}           % Grafikpaket f<>r Bilder laden | ||||||
|  | %\usepackage{epstopdf}                  % .eps bei Bedarf nach .pdf wandeln | ||||||
| %\DeclareGraphicsRule{.tif}{bmp}{}{}    % Grafikformate | %\DeclareGraphicsRule{.tif}{bmp}{}{}    % Grafikformate | ||||||
|  |  | ||||||
|  |  | ||||||
| \usepackage{tabularx}                  % f<>r Tabellen <20>ber die Seitenbreite | \usepackage{tabularx}                  % f<>r Tabellen <20>ber die Seitenbreite | ||||||
| \usepackage{longtable}                 % f<>r Tabellen <20>ber die Seitenbreite | \usepackage{longtable}                 % f<>r Tabellen <20>ber die Seitenbreite | ||||||
| \usepackage{supertabular}              % f<>r Tabellen <20>ber die Seitenbreite | \usepackage{supertabular}              % f<>r Tabellen <20>ber die Seitenbreite | ||||||
| @@ -93,8 +99,8 @@ TODO: Vern | |||||||
|  |  | ||||||
| %\texttt{${}$Id${}$}\bigskip | %\texttt{${}$Id${}$}\bigskip | ||||||
|  |  | ||||||
| Die aktuellste Version dieses Dokumentes befindet sich im World Wide Web auf | Die aktuellste Version dieses Dokumentes befindet sich auf | ||||||
| meiner Homepage (\texttt{http://www.schatenseite.de/}).\bigskip | \texttt{http://www.schatenseite.de/}.\bigskip | ||||||
|  |  | ||||||
| Dieses Dokument ist entstanden, weil ich f<>r mich selbst eine kompakte | Dieses Dokument ist entstanden, weil ich f<>r mich selbst eine kompakte | ||||||
| <EFBFBD>bersicht zu diesem Thema haben wollte. Ich beabsichtige nicht, damit in | <EFBFBD>bersicht zu diesem Thema haben wollte. Ich beabsichtige nicht, damit in | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ | |||||||
| \texttt{\$ cd; ls} & Sequentieller Ablauf \tabularnewline\STRUT | \texttt{\$ cd; ls} & Sequentieller Ablauf \tabularnewline\STRUT | ||||||
| \texttt{\$ (date; who; pwd) > logfile}\index{!>=\texttt{!>}} & F<>hrt die Befehle in einer Subshell\index{Subshell} aus und lenkt alle Ausgaben um \tabularnewline\STRUT | \texttt{\$ (date; who; pwd) > logfile}\index{!>=\texttt{!>}} & F<>hrt die Befehle in einer Subshell\index{Subshell} aus und lenkt alle Ausgaben um \tabularnewline\STRUT | ||||||
| \texttt{\$ \{ date; who; pwd; \} > logfile}\index{!>=\texttt{!>}} & Lenkt alle Ausgaben um \tabularnewline\STRUT | \texttt{\$ \{ date; who; pwd; \} > logfile}\index{!>=\texttt{!>}} & Lenkt alle Ausgaben um \tabularnewline\STRUT | ||||||
|  | \texttt{\$ time \{ date; who; pwd; \}}\index{time=\texttt{time}} & Summiert die Laufzeit der drei Kommandos\tabularnewline\STRUT | ||||||
| \texttt{\$ sort }\textsl{Datei}\texttt{ | lp} & Sortiert die \textsl{Datei} und druckt sie\index{sort=\texttt{sort}} \tabularnewline\STRUT | \texttt{\$ sort }\textsl{Datei}\texttt{ | lp} & Sortiert die \textsl{Datei} und druckt sie\index{sort=\texttt{sort}} \tabularnewline\STRUT | ||||||
| \texttt{\$ vi `grep -l ifdef *.c`}\index{*=\texttt{*}}\index{grep=\texttt{grep}} & Editiert die mittels grep gefundenen Dateien \tabularnewline\STRUT | \texttt{\$ vi `grep -l ifdef *.c`}\index{*=\texttt{*}}\index{grep=\texttt{grep}} & Editiert die mittels grep gefundenen Dateien \tabularnewline\STRUT | ||||||
| \texttt{\$ grep }\textsl{XX Datei}\texttt{ \&\& lp }\textsl{Datei}\index{grep=\texttt{grep}} & Druckt die \textsl{Datei}, wenn sie \textsl{XX} enth<74>lt\index{AND} \tabularnewline\STRUT | \texttt{\$ grep }\textsl{XX Datei}\texttt{ \&\& lp }\textsl{Datei}\index{grep=\texttt{grep}} & Druckt die \textsl{Datei}, wenn sie \textsl{XX} enth<74>lt\index{AND} \tabularnewline\STRUT | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								tab_kommandos_uniq_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tab_kommandos_uniq_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{-c} & Anzahl der Vorkommnisse vor die Zeilen schreiben \tabularnewline\STRUT | ||||||
|  | \texttt{-d} & Nur doppelte Zeilen ausgeben, jede nur einmal \tabularnewline\STRUT | ||||||
|  | \texttt{-D} & Alle doppelten Zeilen ausgeben \tabularnewline\STRUT | ||||||
|  | \texttt{-f }\textsl{n} & Die ersten \textsl{n} Felder ignorieren \tabularnewline\STRUT | ||||||
|  | \texttt{-i} & Gro<72>- / Kleinschreibung ignorieren \tabularnewline\STRUT | ||||||
|  | \texttt{-s }\textsl{n} & Die ersten \textsl{n} Zeichen ignorieren \tabularnewline\STRUT | ||||||
|  | \texttt{-u} & Nur einfach vorkommende Zeilen ausgeben \tabularnewline\STRUT | ||||||
|  | \texttt{-w }\textsl{n} & Nur die ersten \textsl{n} Zeichen betrachten | ||||||
|  | \end{longtable} | ||||||
| @@ -17,7 +17,7 @@ | |||||||
| \texttt{\$!} & Proze<7A>nummer des letzten Hintergrundprozesses \tabularnewline\STRUT | \texttt{\$!} & Proze<7A>nummer des letzten Hintergrundprozesses \tabularnewline\STRUT | ||||||
| \texttt{\$ERRNO} & Fehlernummer des letzten fehlgeschlagenen Systemaufrufs \tabularnewline\STRUT | \texttt{\$ERRNO} & Fehlernummer des letzten fehlgeschlagenen Systemaufrufs \tabularnewline\STRUT | ||||||
| \texttt{\$IFS} & Feldseparator, wird beispielsweise beim Lesen mittels \texttt{read} benutzt \tabularnewline\STRUT | \texttt{\$IFS} & Feldseparator, wird beispielsweise beim Lesen mittels \texttt{read} benutzt \tabularnewline\STRUT | ||||||
| \texttt{\$PATH} & Pfad, in dem nach ausf<73>hrbaren Kommandos gesucht wird.  Mehrere Eintr<74>ge werden durch Doppelpunkte getrennt angegeben \tabularnewline\STRUT | \texttt{\$PATH} & Pfad, in dem nach ausf<73>hrbaren Kommandos gesucht wird\footnote{Mit dem Kommando \texttt{type}\index{type=\texttt{type}} findet man heraus, welches Executable tats<74>chlich verwendet wird.}.  Mehrere Eintr<74>ge werden durch Doppelpunkte getrennt angegeben \tabularnewline\STRUT | ||||||
| \texttt{\$PWD} & Aktuelles Verzeichnis (wird durch \texttt{cd} gesetzt\footnote{Durch das Kommando \texttt{cd} wird das aktuelle Verzeichnis gewechselt, siehe Abschnitt \ref{cd}.}) \tabularnewline\STRUT | \texttt{\$PWD} & Aktuelles Verzeichnis (wird durch \texttt{cd} gesetzt\footnote{Durch das Kommando \texttt{cd} wird das aktuelle Verzeichnis gewechselt, siehe Abschnitt \ref{cd}.}) \tabularnewline\STRUT | ||||||
| \texttt{\$OLDPWD} & Vorheriges Verzeichnis (wird durch \texttt{cd} gesetzt) | \texttt{\$OLDPWD} & Vorheriges Verzeichnis (wird durch \texttt{cd} gesetzt) | ||||||
| \end{longtable} | \end{longtable} | ||||||
|   | |||||||
| @@ -69,7 +69,8 @@ Subshells zu vererben. | |||||||
| Annehmlichkeiten wie die Korn-Shell, lehnt sich aber in der Syntax sehr stark | Annehmlichkeiten wie die Korn-Shell, lehnt sich aber in der Syntax sehr stark | ||||||
| an die Programmiersprache C an. Sie sollte nach M<>glichkeit nicht zur | an die Programmiersprache C an. Sie sollte nach M<>glichkeit nicht zur | ||||||
| Shell-Programmierung benutzt werden, da sie an vielen Stellen nicht so | Shell-Programmierung benutzt werden, da sie an vielen Stellen nicht so | ||||||
| reagiert, wie man es erwarten sollte.  \end{itemize} | reagiert, wie man es erwarten sollte. | ||||||
|  | \end{itemize} | ||||||
|  |  | ||||||
| \medskip\emph{Komfort-Shells:}\nopagebreak | \medskip\emph{Komfort-Shells:}\nopagebreak | ||||||
|  |  | ||||||
| @@ -90,7 +91,7 @@ indizierte Arrays\index{Array}. | |||||||
| TENEX-C-Shell\index{TENEX-C-Shell|textbf}\index{Shell>TENEX-C-|see{TENEX-C-Shell}} | TENEX-C-Shell\index{TENEX-C-Shell|textbf}\index{Shell>TENEX-C-|see{TENEX-C-Shell}} | ||||||
| (\texttt{tcsh}\index{tcsh=\texttt{tcsh}|see{TENEX-C-Shell}}) verh<72>lt sich zur | (\texttt{tcsh}\index{tcsh=\texttt{tcsh}|see{TENEX-C-Shell}}) verh<72>lt sich zur | ||||||
| C-Shell wie die Bourne-Again-Shell zur Standard-Shell. Sie ist voll kompatibel, | C-Shell wie die Bourne-Again-Shell zur Standard-Shell. Sie ist voll kompatibel, | ||||||
| bietet aber Kom\-fort-Funk\-tio\-nen wie Kommandozeilen-Editierung, | bietet aber Kom\-fort-Funk\-tio\-nen wie Kom\-man\-do\-zei\-len-Edi\-tie\-rung, | ||||||
| programmierbare Auto-Completion\index{Auto-Completion}, | programmierbare Auto-Completion\index{Auto-Completion}, | ||||||
| Recht\-schreib\-hil\-fen und eine History. | Recht\-schreib\-hil\-fen und eine History. | ||||||
|  |  | ||||||
| @@ -114,6 +115,6 @@ C- | |||||||
| und schnell, bietet eine Lisp-<2D>hnliche Sprache), | und schnell, bietet eine Lisp-<2D>hnliche Sprache), | ||||||
| \texttt{sash}\index{sash|textbf}\index{Shell>sash=\texttt{sash}|see{sash}} | \texttt{sash}\index{sash|textbf}\index{Shell>sash=\texttt{sash}|see{sash}} | ||||||
| (System Administrator's Shell - eine statisch gelinkte Shell mit integrierten | (System Administrator's Shell - eine statisch gelinkte Shell mit integrierten | ||||||
| Standard-Kommandos.). | Stan\-dard-Kom\-man\-dos.). | ||||||
|  |  | ||||||
| Diese Liste ist bei weitem nicht vollst<73>ndig. | Diese Liste ist bei weitem nicht vollst<73>ndig. | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| % $Id$ | % $Id$ | ||||||
| \chapter{N<EFBFBD>tzliche Shell-Kommandos}\label{nuetzliche_shell-kommandos} | \chapter{Werkzeugkasten}\label{werkzeugkasten} | ||||||
| Durch die gezeigten Steuerungsm<73>glichkeiten stehen dem Shell-Pro\-grammie\-rer | Durch die gezeigten Steuerungsm<73>glichkeiten stehen dem Shell-Pro\-grammie\-rer | ||||||
| M<EFBFBD>g\-lich\-kei\-ten offen, fast alle g<>ngigen Algorithmen zu implementieren. Es | M<EFBFBD>g\-lich\-kei\-ten offen, fast alle g<>ngigen Algorithmen zu implementieren. Es | ||||||
| ist tats<74>chlich in der Shell m<>glich, Sortier- oder Suchfunktionen zu | ist tats<74>chlich in der Shell m<>glich, Sortier- oder Suchfunktionen zu | ||||||
| @@ -68,11 +68,30 @@ Dateien auf der Festplatte. | |||||||
| \item \texttt{head} (\ref{head}): Dateianfang ausgeben | \item \texttt{head} (\ref{head}): Dateianfang ausgeben | ||||||
| \item \texttt{printf} (\ref{printf}): Formatierte Datenausgabe | \item \texttt{printf} (\ref{printf}): Formatierte Datenausgabe | ||||||
| \item \texttt{read} (\ref{read}): Zeilen einlesen | \item \texttt{read} (\ref{read}): Zeilen einlesen | ||||||
| \item \texttt{sort} (\ref{sort}): Zeilenweises Sortieren |  | ||||||
| \item \texttt{tail} (\ref{tail}): Dateiende ausgeben | \item \texttt{tail} (\ref{tail}): Dateiende ausgeben | ||||||
| \end{itemize} | \end{itemize} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | \subsection{Dateiinhalte bearbeiten}\label{dateiinhalte} | ||||||
|  |  | ||||||
|  | Nat<EFBFBD>rlich bietet die Shell eine Reihe von Befehlen, um die Inhalte von Dateien | ||||||
|  | zu bearbeiten. Diese Auflistung ist in weiten Teilen deckungsgleich mit der | ||||||
|  | Liste der Tools zur Manipulation von Pipes, auch diese Kommandos kommen also | ||||||
|  | in mehreren Situationen zum Einsatz. | ||||||
|  |  | ||||||
|  | \begin{itemize} | ||||||
|  | \item \texttt{awk} (\ref{awk}): In einer Pipe editieren | ||||||
|  | \item \texttt{cmp} (\ref{cmp}): Bin<69>re Dateien vergleichen | ||||||
|  | \item \texttt{cut} (\ref{cut}): Teile einer Zeile ausschneiden | ||||||
|  | \item \texttt{diff} (\ref{diff}): Textdateien vergleichen | ||||||
|  | \item \texttt{paste} (\ref{paste}): Dateien zusammenf<6E>hren | ||||||
|  | \item \texttt{sed} (\ref{sed}): In einer Pipe editieren | ||||||
|  | \item \texttt{sort} (\ref{sort}): Zeilenweises Sortieren | ||||||
|  | \item \texttt{tr} (\ref{tr}): Zeichen ersetzen | ||||||
|  | \item \texttt{uniq} (\ref{uniq}): Doppelte Zeilen suchen | ||||||
|  | \end{itemize} | ||||||
|  |  | ||||||
|  |  | ||||||
| \subsection{Pfade und Dateien}\label{pfade_und_dateien} | \subsection{Pfade und Dateien}\label{pfade_und_dateien} | ||||||
|  |  | ||||||
| Eine der Hauptaufgaben von Shell-Skripten ist nat<61>rlich das Hantieren mit | Eine der Hauptaufgaben von Shell-Skripten ist nat<61>rlich das Hantieren mit | ||||||
| @@ -85,10 +104,12 @@ Datei kann viel mehr sein als nur ein paar Daten im Filesystem. | |||||||
|  |  | ||||||
| \begin{itemize} | \begin{itemize} | ||||||
| \item \texttt{basename} (\ref{basename}): Den Namen einer Datei (ohne Pfad) ausgeben | \item \texttt{basename} (\ref{basename}): Den Namen einer Datei (ohne Pfad) ausgeben | ||||||
|  | \item \texttt{cd} (\ref{cd}): Verzeichnis wechseln | ||||||
| \item \texttt{cp} (\ref{cp}): Dateien kopieren | \item \texttt{cp} (\ref{cp}): Dateien kopieren | ||||||
| \item \texttt{chgrp} (\ref{chgrp}): Gruppen-ID einer Datei <20>ndern | \item \texttt{chgrp} (\ref{chgrp}): Gruppen-ID einer Datei <20>ndern | ||||||
| \item \texttt{chmod} (\ref{chmod}): Zugriffsrechte einer Datei <20>ndern | \item \texttt{chmod} (\ref{chmod}): Zugriffsrechte einer Datei <20>ndern | ||||||
| \item \texttt{chown} (\ref{chown}): Eigent<6E>mer einer Datei <20>ndern | \item \texttt{chown} (\ref{chown}): Eigent<6E>mer einer Datei <20>ndern | ||||||
|  | \item \texttt{cmp} (\ref{cmp}): Bin<69>re Dateien vergleichen | ||||||
| \item \texttt{dirname} (\ref{dirname}): Den Pfad zu einer Datei (ohne den Namen) ausgeben | \item \texttt{dirname} (\ref{dirname}): Den Pfad zu einer Datei (ohne den Namen) ausgeben | ||||||
| \item \texttt{find} (\ref{find}): Dateien suchen | \item \texttt{find} (\ref{find}): Dateien suchen | ||||||
| \item \texttt{mkdir} (\ref{mkdir}): Verzeichnisse anlegen | \item \texttt{mkdir} (\ref{mkdir}): Verzeichnisse anlegen | ||||||
| @@ -96,6 +117,7 @@ Datei kann viel mehr sein als nur ein paar Daten im Filesystem. | |||||||
| \item \texttt{rm} (\ref{rm}): Dateien l<>schen | \item \texttt{rm} (\ref{rm}): Dateien l<>schen | ||||||
| \item \texttt{rmdir} (\ref{rmdir}): Verzeichnisse l<>schen | \item \texttt{rmdir} (\ref{rmdir}): Verzeichnisse l<>schen | ||||||
| \item \texttt{touch} (\ref{touch}): Eine leere Datei anlegen, bzw. das Zugriffsdatum einer Datei <20>ndern | \item \texttt{touch} (\ref{touch}): Eine leere Datei anlegen, bzw. das Zugriffsdatum einer Datei <20>ndern | ||||||
|  | \item \texttt{which} (\ref{which}): Ausf<73>hrbare Dateien suchen | ||||||
| \item \texttt{xargs} (\ref{xargs}): Ausgaben eines Kommandos als Parameter eines anderen Kommandos benutzen | \item \texttt{xargs} (\ref{xargs}): Ausgaben eines Kommandos als Parameter eines anderen Kommandos benutzen | ||||||
| \end{itemize} | \end{itemize} | ||||||
|  |  | ||||||
| @@ -120,12 +142,14 @@ und ausgef | |||||||
| kleinsten geeigneten Hammer nehmen. | kleinsten geeigneten Hammer nehmen. | ||||||
|  |  | ||||||
| \begin{itemize} | \begin{itemize} | ||||||
|  | \item \texttt{awk} (\ref{awk}): In einer Pipe editieren | ||||||
| \item \texttt{cut} (\ref{cut}): Teile einer Zeile ausschneiden | \item \texttt{cut} (\ref{cut}): Teile einer Zeile ausschneiden | ||||||
| \item \texttt{grep} (\ref{grep}): In einer Pipe suchen | \item \texttt{grep} (\ref{grep}): In einer Pipe suchen | ||||||
| \item \texttt{sed} (\ref{sed}): In einer Pipe editieren | \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{sort} (\ref{sort}): Zeilenweises Sortieren | ||||||
| \item \texttt{tee} (\ref{tee}): Datenstrom in einer Datei protokollieren | \item \texttt{tee} (\ref{tee}): Datenstrom in einer Datei protokollieren | ||||||
|  | \item \texttt{tr} (\ref{tr}): Zeichen ersetzen | ||||||
|  | \item \texttt{uniq} (\ref{uniq}): Doppelte Zeilen suchen | ||||||
| \item \texttt{wc} (\ref{wc}): Zeilen, W<>rter oder Zeichen z<>hlen | \item \texttt{wc} (\ref{wc}): Zeilen, W<>rter oder Zeichen z<>hlen | ||||||
| \end{itemize} | \end{itemize} | ||||||
|  |  | ||||||
| @@ -149,6 +173,7 @@ Verf | |||||||
| \item \texttt{ps} (\ref{ps}): Proze<7A>liste ausgeben | \item \texttt{ps} (\ref{ps}): Proze<7A>liste ausgeben | ||||||
| \item \texttt{pgrep} (\ref{pgrep}): Bestimmte Prozesse suchen | \item \texttt{pgrep} (\ref{pgrep}): Bestimmte Prozesse suchen | ||||||
| \item \texttt{pkill} (\ref{pkill}): Bestimmte Prozesse t<>ten | \item \texttt{pkill} (\ref{pkill}): Bestimmte Prozesse t<>ten | ||||||
|  | \item \texttt{trap} (\ref{trap}): Auf Signale reagieren | ||||||
| \end{itemize} | \end{itemize} | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -164,7 +189,154 @@ ausgiebigere Informationen empfehle ich entsprechende B | |||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{awk}\label{awk}\index{awk=\texttt{awk}|(textbf} | \subsection{awk}\label{awk}\index{awk=\texttt{awk}|(textbf} | ||||||
|  |  | ||||||
| TODO!!! awk | <EFBFBD>ber die Skriptsprache \texttt{awk} wurden schon ganze B<>cher geschrieben, eine | ||||||
|  | vollst<EFBFBD>ndige Beschreibung w<>rde den Rahmen dieses Dokumentes bei weitem | ||||||
|  | sprengen. Hier werden nur ein paar grundlegende Techniken beschrieben, die | ||||||
|  | h<EFBFBD>ufig im Zusammenhang mit Shell-Skripten auftauchen. | ||||||
|  |  | ||||||
|  | Oben wurde \texttt{awk} `Skriptsprache' genannt. Das ist insofern richtig, als | ||||||
|  | da<EFBFBD> es eine m<>chtige und komplexe Syntax zur Verf<72>gung stellt, um Texte | ||||||
|  | automatisiert zu bearbeiten. Es f<>llt somit in die gleiche Tool-Kategorie wie | ||||||
|  | \texttt{sed} (Abschnitt \ref{sed}). | ||||||
|  |  | ||||||
|  | Es unterscheidet sich aber in seinen grundlegenden Prinzipien entscheidend von | ||||||
|  | den meisten anderen Programmiersprachen: \texttt{awk} arbeitet `Datenbasiert'. | ||||||
|  | Das bedeutet, da<64> zun<75>chst die Daten spezifiziert werden mit denen gearbeitet | ||||||
|  | werden soll, dann folgen die auszuf<75>hrenden Kommandos. Das Prinzip wird schnell | ||||||
|  | klar, wenn man sich einige der Beispiele weiter unten ansieht. | ||||||
|  |  | ||||||
|  | \subsubsection{Aufruf} | ||||||
|  |  | ||||||
|  | Auch der Aufruf erfolgt analog zu \texttt{sed}: Bei einfachen Aufgaben kann das | ||||||
|  | \texttt{awk}-Programm direkt an der Kommandozeile mitgegeben werden, komplexere | ||||||
|  | Programme werden in Dateien gespeichert und von dort gelesen. | ||||||
|  |  | ||||||
|  | Eine weitere Gemeinsamkeit ist die Art der Ein- und Ausgabe. Wenn eine | ||||||
|  | Eingabedatei angegeben wird, wird diese verarbeitet. Ansonsten wird die | ||||||
|  | Standard-Eingabe gelesen. Ausgaben erfolgen immer auf der Standard-Ausgabe. | ||||||
|  |  | ||||||
|  | \footnotesize | ||||||
|  | \begin{listing}[2]{1} | ||||||
|  | # Aufruf als Filter: | ||||||
|  | kommando1 | awk '{ print $1; print $2 }' | kommando2 | ||||||
|  |  | ||||||
|  | # Aufruf mit einer zu bearbeitenden Datei: | ||||||
|  | awk '{ print $1; print $2 }' datei.txt | ||||||
|  |  | ||||||
|  | # In einem Skript kann das Kommando auch <20>ber mehrere Zeilen gehen: | ||||||
|  | awk ' | ||||||
|  | { | ||||||
|  |   print $1; | ||||||
|  |   print $2; | ||||||
|  | }' datei.txt | ||||||
|  |  | ||||||
|  | # Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert und | ||||||
|  | # <20>ber den Parameter -f eingebunden werden: | ||||||
|  | awk -f script.awk datei.txt | ||||||
|  | \end{listing} | ||||||
|  | \normalsize | ||||||
|  |  | ||||||
|  | Neben dem Parameter \texttt{-f} zum Einlesen der Programmdatei gibt es noch den | ||||||
|  | Parameter \texttt{-F} mit dem der Feld-Trenner angegeben werden kann. Die | ||||||
|  | folgende Zeile gibt beispielsweise alle Benutzernamen und deren User-IDs aus | ||||||
|  | der Doppelpunktseparierten Datei \texttt{/etc/passwd} aus: | ||||||
|  |  | ||||||
|  | \texttt{awk -F: '\{ print \$1\dq hat ID \dq\$3 \}' /etc/passwd} | ||||||
|  |  | ||||||
|  | \subsubsection{Muster und Prozeduren} | ||||||
|  |  | ||||||
|  | Die Skripte f<>r \texttt{awk} bestehen aus Bl<42>cken von Mustern und Prozeduren. | ||||||
|  | Ein Block hat den folgenden Aufbau: | ||||||
|  |  | ||||||
|  | \textsl{muster}\texttt{ \{ }\textsl{prozedur}\texttt{ \}} | ||||||
|  |  | ||||||
|  | Dabei sind beide Bestandteile des Blockes Optional: Wird das Muster | ||||||
|  | weggelassen, wird die Prozedur auf alle Textbestandteile angewandt. Und wird | ||||||
|  | keine Prozedur angegeben, wird der betroffene Text einfach ausgegeben. | ||||||
|  |  | ||||||
|  | Das Muster kann dabei auf verschiedene Weise angegeben werden: | ||||||
|  | \begin{itemize} | ||||||
|  | \item Als regul<75>rer Ausdruck (siehe Abschnitt \ref{mustererkennung}), | ||||||
|  | eingebettet in Slashes: \texttt{/}\textsl{muster}\texttt{/} | ||||||
|  | \item Als relationaler Ausdruck, bei dem bestimmte Kriterien auf die | ||||||
|  | Eingabedaten zutreffen m<>ssen. Mit \texttt{\$2>\$1} werden beispielsweise | ||||||
|  | Zeilen angesprochen, deren zweites Feld einen gr<67><72>eren Wert hat als das erste. | ||||||
|  | \item Mit Operatoren f<>r das Pattern-Matching, <20>hnlich wie in Perl (\texttt{\~} | ||||||
|  | oder \texttt{!\~}) | ||||||
|  | \item \texttt{BEGIN} kennzeichnet Prozeduren, die vor der Bearbeitung anderer | ||||||
|  | Bl<EFBFBD>cke zum Tragen kommen sollen. | ||||||
|  | \item Analog dazu gibt es ein \texttt{END}, mit dem abschlie<69>ende Aktionen | ||||||
|  | gekennzeichnet werden. | ||||||
|  | \end{itemize} | ||||||
|  |  | ||||||
|  | Abgesehen von \texttt{BEGIN} und \texttt{END} k<>nnen die Muster auch durch | ||||||
|  | logische Operatoren (\texttt{\&\&}, \texttt{||} oder \texttt{!}) kombiniert | ||||||
|  | werden. Durch Komma getrennt besteht die M<>glichkeit, Wirkungsbereiche zu | ||||||
|  | definieren. | ||||||
|  |  | ||||||
|  | Die Prozeduren k<>nnen Variablen- oder Array-Zuweisungen, Ausgabeanweisungen, | ||||||
|  | Funktionsaufrufe oder Kontrollstrukturen enthalten. | ||||||
|  |  | ||||||
|  | \subsubsection{Variablen} | ||||||
|  |  | ||||||
|  | Es gibt in \texttt{awk} eine Reihe eingebauter Variablen, die in Mustern oder | ||||||
|  | Prozeduren verwendet werden k<>nnen: | ||||||
|  |  | ||||||
|  | \LTXtable{\textwidth}{tab_kommandos_awk_variablen.tex} | ||||||
|  |  | ||||||
|  | Eigene Variablen k<>nnen nach Belieben verwendet werden, siehe dazu das Beispiel | ||||||
|  | mit den TeX-Dateien weiter unten. | ||||||
|  |  | ||||||
|  | \subsubsection{Beispiele} | ||||||
|  |  | ||||||
|  | Hier ein paar Einfache Beispiele f<>r Blocks aus Mustern und Prozeduren: | ||||||
|  |  | ||||||
|  | \footnotesize | ||||||
|  | \begin{listing}[2]{1} | ||||||
|  | # Das erste Feld jeder Zeile ausgeben: | ||||||
|  | { print $1 } | ||||||
|  |  | ||||||
|  | # Alle Zeilen ausgeben, die 'regexp' enthalten: | ||||||
|  | /regexp/ | ||||||
|  |  | ||||||
|  | # Das erste Feld jeder Zeile ausgeben, die 'regexp' enth<74>lt: | ||||||
|  | /regexp/ { print $1 } | ||||||
|  |  | ||||||
|  | # Datens<6E>tze mit mehr als zwei Feldern ausw<73>hlen: | ||||||
|  | NF > 2 | ||||||
|  |  | ||||||
|  | # Das dritte und das zweite Feld jeder Zeile ausgeben, deren erstes Feld den | ||||||
|  | # String 'WICHTIG' enth<74>lt: | ||||||
|  | $1 ~ /WICHTIG/ { print $3, $2 } | ||||||
|  |  | ||||||
|  | # Die Vorkommen von 'muster' z<>hlen, und deren Anzahl ausgeben: | ||||||
|  | /muster/ { ++x } | ||||||
|  | END { print x } | ||||||
|  |  | ||||||
|  | # Alle Zeilen mit weniger als 23 Zeichen ausgeben: | ||||||
|  | length($0) < 23 | ||||||
|  |  | ||||||
|  | # Alle Zeilen ausgeben, die mit 'Name:' anfangen und exakt sieben Felder | ||||||
|  | # enthalten: | ||||||
|  | NF == 7 && /^Name:/ | ||||||
|  |  | ||||||
|  | # Alle Felder der Eingabedaten zeilenweise in umgekehrter Reihenfolge ausgeben: | ||||||
|  | { | ||||||
|  |   for (i = NF; i >= 1; i--) | ||||||
|  |     print $i | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Die Gr<47><72>e aller TeX-Dateien addieren, die Summe in kB umrechnen und ausgeben, | ||||||
|  | # verarbeitet die Ausgabe von 'ls -l': | ||||||
|  | /.*tex/ { summe += $5 } | ||||||
|  | END { summe /= 1024; print "Die Gr<47><72>e aller TeX-Files betr<74>gt", summe, "kB" } | ||||||
|  |  | ||||||
|  | # Pipe-Separierte Liste aller gemounteten Partitionen und derer F<>llst<73>nde | ||||||
|  | # ausgeben, verarbeitet die Ausgabe von 'df': | ||||||
|  | BEGIN { OFS="|" } | ||||||
|  | /^\/dev\// { print $1,$5 } | ||||||
|  | \end{listing} | ||||||
|  | \normalsize | ||||||
|  |  | ||||||
| \index{awk=\texttt{awk}|)} | \index{awk=\texttt{awk}|)} | ||||||
|  |  | ||||||
| @@ -220,6 +392,14 @@ werden. | |||||||
| \index{cat=\texttt{cat}|)} | \index{cat=\texttt{cat}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | \subsection{cd}\label{cd}\index{cd=\texttt{cd}|(textbf} | ||||||
|  |  | ||||||
|  | Mit dem Kommando \texttt{cd} wird das aktuelle Verzeichnis gewechselt. | ||||||
|  |  | ||||||
|  | \index{cd=\texttt{cd}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{chgrp}\label{chgrp}\index{chgrp=\texttt{chgrp}|(textbf} | \subsection{chgrp}\label{chgrp}\index{chgrp=\texttt{chgrp}|(textbf} | ||||||
|  |  | ||||||
| @@ -328,6 +508,14 @@ diese Datei nicht allgemein lesbar ist. | |||||||
| \index{chpasswd=\texttt{chpasswd}|)} | \index{chpasswd=\texttt{chpasswd}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | \subsection{cmp}\label{cmp}\index{cmp=\texttt{cmp}|(textbf} | ||||||
|  |  | ||||||
|  | TODO!!! cmp GNU? | ||||||
|  |  | ||||||
|  | \index{cmp=\texttt{cmp}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{cp}\label{cp}\index{cp=\texttt{cp}|(textbf} | \subsection{cp}\label{cp}\index{cp=\texttt{cp}|(textbf} | ||||||
|  |  | ||||||
| @@ -355,9 +543,20 @@ der Formate N, N-, N-M oder -M benutzt werden. | |||||||
|  |  | ||||||
| \LTXtable{\textwidth}{tab_kommandos_cut_beispiele.tex} | \LTXtable{\textwidth}{tab_kommandos_cut_beispiele.tex} | ||||||
|  |  | ||||||
|  | Praktisch das Gegenst<73>ck zu \texttt{cut} ist \texttt{paste}, damit werden | ||||||
|  | Dateien in Spalten zusammengef<65>hrt. N<>hrers dazu in Abschnitt \ref{paste}. | ||||||
|  |  | ||||||
| \index{cut=\texttt{cut}|)} | \index{cut=\texttt{cut}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | \subsection{diff}\label{diff}\index{diff=\texttt{diff}|(textbf} | ||||||
|  |  | ||||||
|  | TODO!!! diff | ||||||
|  |  | ||||||
|  | \index{diff=\texttt{diff}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{dirname}\label{dirname}\index{dirname=\texttt{dirname}|(textbf} | \subsection{dirname}\label{dirname}\index{dirname=\texttt{dirname}|(textbf} | ||||||
|  |  | ||||||
| @@ -437,7 +636,72 @@ Arith\-me\-tik-Ex\-pan\-sion (Siehe \ref{arithmetikexpansion}). | |||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{find}\label{find}\index{find=\texttt{find}|(textbf} | \subsection{find}\label{find}\index{find=\texttt{find}|(textbf} | ||||||
|  |  | ||||||
| TODO!!! find | Auf einem modernen System sind nicht selten mehrere zehn- oder hunderttausend | ||||||
|  | Dateien vorhanden. Um eine bestimmte Datei anhand komplexer Kriterien ausfindig | ||||||
|  | zu machen benutzt man \texttt{find}. | ||||||
|  |  | ||||||
|  | Bei einem Aufruf wird zuerst das zu durchsuchende Verzeichnis, dann die | ||||||
|  | Suchkriterien und eventuell abschlie<69>end die durchzuf<75>hrenden Aktionen | ||||||
|  | angegeben. | ||||||
|  |  | ||||||
|  | Die Angabe der Suchkriterien ist sehr vielseitig, hier werden nur die | ||||||
|  | wichtigsten Optionen beschrieben. Wie immer empfehle ich das Studium der | ||||||
|  | Man-Page oder eines entsprechenden Buches. | ||||||
|  |  | ||||||
|  | \LTXtable{\textwidth}{tab_kommandos_find_parameter.tex} | ||||||
|  |  | ||||||
|  | Die verschiedenen Suchkriterien k<>nnen kombiniert werden. Mit \texttt{-a} oder | ||||||
|  | \texttt{-o} erreicht man eine logische AND- bzw. OR-Verkn<6B>pfung, mit einem | ||||||
|  | vorangestellten \texttt{!} k<>nnen Kriterien negiert werden. Die AND-Verkn<6B>pfung | ||||||
|  | mu<EFBFBD> nicht explizit angegeben werden, wenn mehrere Kriterien verwandt werden. | ||||||
|  | Komplexere Ausdr<64>cke k<>nnen durch runde Klammern gruppiert werden, dabei ist | ||||||
|  | jedoch deren Sonderbedeutung in der Shell entsprechend zu quoten (Siehe | ||||||
|  | Abschnitt \ref{quoting}). | ||||||
|  |  | ||||||
|  | Bei der Angabe numerischer Parameter zu den Suchkriterien wird normalerweise | ||||||
|  | nach dem exakten Wert gesucht. Statt eines einfachen \textsl{n} kann jedoch | ||||||
|  | auch \textsl{+n} oder \textsl{-n} angegeben werden, damit wird dann nach | ||||||
|  | Vorkommen gr<67><72>er bzw. kleiner als \textsl{n} gesucht. | ||||||
|  |  | ||||||
|  | Da die reine Beschreibung der Parameter manchmal etwas verwirrend ist, folgen | ||||||
|  | hier ein paar praktische Beispiele: | ||||||
|  |  | ||||||
|  | \footnotesize | ||||||
|  | \begin{listing}[2]{1} | ||||||
|  | # Suche alle Eintr<74>ge in bzw. unter dem aktuellen Verzeichnis: | ||||||
|  | find . | ||||||
|  | # Suche alle normalen Dateien mit der Endung txt unter /home: | ||||||
|  | find /home -type f -name \*.txt | ||||||
|  | # Suche alle Eintr<74>ge au<61>er symbolischen Links, in die jeder schreiben darf: | ||||||
|  | find / \! -type l -perm 777 | ||||||
|  | # Suche alle Dateien unter dem Homeverzeichnis, deren Gr<47><72>e 10000000 Bytes | ||||||
|  | # <20>bersteigt und gib sie ausf<73>hrlich aus: | ||||||
|  | find ~ -size +10000000c -exec ls -l {} \; | ||||||
|  | # Suche alle Eintr<74>ge im Homeverzeichnis, die innerhalb der letzten zwei Tage | ||||||
|  | # ge<67>ndert wurden: | ||||||
|  | find ~ -mtime -2 | ||||||
|  | \end{listing} | ||||||
|  | \normalsize | ||||||
|  |  | ||||||
|  | Wenn mittels \texttt{-exec} weitere Kommandos gestartet werden, sollte beachtet | ||||||
|  | werden da<64> mindestens ein Proze<7A> pro Fundstelle gestartet wird. Das kostet sehr | ||||||
|  | viel, unter Umst<73>nden macht der Einsatz von \texttt{xargs} (Abschnitt | ||||||
|  | \ref{xargs}) Sinn. | ||||||
|  |  | ||||||
|  | Die Ausf<73>hrung von \texttt{find} erzeugt unter Umst<73>nden sehr viel Last auf der | ||||||
|  | Festplatte, bei Netzlaufwerken auch Netzwerkbandbreite. In einigen F<>llen | ||||||
|  | bieten sich alternative Suchverfahren an: | ||||||
|  |  | ||||||
|  | \textbf{Alternative 1:} Falls man den Namen der zu suchenden Datei kennt, und | ||||||
|  | das Locate-System installiert ist kann man die Datei auch mittels | ||||||
|  | \texttt{locate} suchen. Das ist ressourcenschonender, da nicht `live' das | ||||||
|  | Filesystem durchforstet wird, sondern nur die Locate-Datenbank. Diese wird | ||||||
|  | allerdings im Regelfall nur einmal t<>glich aktualisiert, die Suche taugt nicht | ||||||
|  | f<EFBFBD>r schnell wechselnde Best<73>nde. | ||||||
|  |  | ||||||
|  | \textbf{Alternative 2:} Sucht man nach einer ausf<73>hrbaren Datei, die im Pfad | ||||||
|  | vorhanden ist (`Wo liegt eigentlich Firefox?'), dann sucht man mittels | ||||||
|  | \texttt{which} (Abschnitt \ref{which}). | ||||||
|  |  | ||||||
| Siehe auch: Abschnitt \ref{beispiele_suchen_dateien}. | Siehe auch: Abschnitt \ref{beispiele_suchen_dateien}. | ||||||
|  |  | ||||||
| @@ -473,11 +737,44 @@ werden allerdings nicht die letzten Zeilen angezeigt, sondern die ersten. | |||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{kill}\label{kill}\index{kill=\texttt{kill}|(textbf} | \subsection{kill}\label{kill}\index{kill=\texttt{kill}|(textbf} | ||||||
|  |  | ||||||
| TODO!!! kill | 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. | ||||||
|  |  | ||||||
| <EFBFBD>brigens: Die landl<64>ufige Annahme ist, da<64> man mit dem | Im Prinzip sendet \texttt{kill} lediglich ein Signal an einen Proze<7A>. Ohne | ||||||
| \texttt{kill}-Kom\-man\-do Prozesse `umbringt'. Das ist zwar wahr, aber nicht | weitere Parameter ist das tats<74>chlich ein SIGTERM, das den Proze<7A> im Regelfall | ||||||
| die ganze Wahrheit. | dazu bewegt sich zu beenden. Jeder Admin kennt das Verfahren, einem h<>ngenden | ||||||
|  | Proze<EFBFBD> mittels \texttt{kill -9} den Gnadenschu<68> zu geben. Die 9 steht dabei f<>r | ||||||
|  | das Signal mit der Nummer 9, SIGKILL. Noch ein gebr<62>uchliches Signal ist SIGHUP | ||||||
|  | (1), der `Hangup'. Historisch wurde das gesendet wenn die Leitung zum Rechner | ||||||
|  | aufgelegt wurde, mittlerweile ist es g<>ngige Praxis damit einen Daemon neu zu | ||||||
|  | initialisieren. | ||||||
|  |  | ||||||
|  | Daneben stehen noch eine Reihe weiterer Signale zur Verf<72>gung. Mit \texttt{kill | ||||||
|  | -l} kann man sich eine Liste ansehen.  | ||||||
|  |  | ||||||
|  | Es gibt verschiedene Wege, das Signal abzusetzen. Welchen man w<>hlt ist | ||||||
|  | Geschmackssache. Hier ein paar Beispiele: | ||||||
|  |  | ||||||
|  | \footnotesize | ||||||
|  | \begin{listing}[2]{1} | ||||||
|  | # Die folgenden Befehle sind gleichwertig. Alle senden ein HUP an Proze<7A>-ID 42: | ||||||
|  | kill -1 42 | ||||||
|  | kill -HUP 42 | ||||||
|  | kill -SIGHUP 42 | ||||||
|  | kill -s 1 42 | ||||||
|  | kill -s HUP 42 | ||||||
|  | kill -s SIGHUP 42 | ||||||
|  |  | ||||||
|  | # virtueller Selbstmord: Alle Prozesse umbringen, die man umbringen kann: | ||||||
|  | kill -9 -1 | ||||||
|  |  | ||||||
|  | # SIGTERM an mehrere Prozesse senden: | ||||||
|  | kill 123 456 789 | ||||||
|  | \end{listing} | ||||||
|  | \normalsize | ||||||
|  |  | ||||||
|  | Siehe auch: Das Beispiel `Fallensteller' in Abschnitt \ref{traps} zeigt, wie | ||||||
|  | ein Skript auf Signale reagieren kann. | ||||||
|  |  | ||||||
| \index{kill=\texttt{kill}|)} | \index{kill=\texttt{kill}|)} | ||||||
|  |  | ||||||
| @@ -509,14 +806,45 @@ zur Verf | |||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{ls}\label{ls}\index{ls=\texttt{ls}|(textbf} | \subsection{ls}\label{ls}\index{ls=\texttt{ls}|(textbf} | ||||||
|  |  | ||||||
|  | Den Inhalt von Verzeichnissen im Dateisystem bringt man mit \texttt{ls} in | ||||||
|  | Erfahrung. Ein einfacher Aufruf listet lediglich die Dateinamen im aktuellen | ||||||
|  | oder angegebenen Verzeichnis auf, das Kommando hat aber auch sehr viele | ||||||
|  | Parameter mit denen sich die Ausgabe anpassen l<><6C>t. Hier sind die wichtigsten, | ||||||
|  | eine vollst<73>ndige Auflistung bietet wie immer die Man-Page: | ||||||
|  |  | ||||||
|  | \LTXtable{\textwidth}{tab_kommandos_ls_parameter.tex} | ||||||
|  |  | ||||||
|  | Besonders informativ gibt sich der Parameter \texttt{-l}, da damit auch die | ||||||
|  | Eigent<EFBFBD>mer und die Berechtigungen der Dateien angezeigt werden. Die Ausgabe hat | ||||||
|  | die folgende Form: | ||||||
|  |  | ||||||
|  | \texttt{-rw-r--r--  1 rschaten users 6252 Nov 19 14:14 shell.tex} | ||||||
|  |  | ||||||
| Die linke Spalte der Ausgabe zeigt die bestehenden Berechtigungen. Es ist ein | Die linke Spalte der Ausgabe zeigt die bestehenden Berechtigungen. Es ist ein | ||||||
| Block in der Form `drwxrwxrwx'. An Stelle des d k<>nnen auch andere Buchstaben | Block in der Form `drwxrwxrwx'. An Stelle des d k<>nnen auch andere Buchstaben | ||||||
| stehen, hier wird der Dateityp angegeben, also ob es sich um eine einfache | stehen, hier wird der Dateityp angegeben, also ob es sich um eine einfache | ||||||
| Datei (-), ein Verzeichnis (d), einen Link (l) oder <20>hnliches\footnote{Siehe | Datei (-), ein Verzeichnis (d), einen Link (l) oder <20>hnliches\footnote{Siehe | ||||||
| Man-Page} handelt. An Stelle der rwx-Bl<42>cke k<>nnen auch Striche stehen, die | Man-Page} handelt. Die rwx-Bl<42>cke geben die Dateiberechtigungen jeweils f<>r den | ||||||
| stehen f<>r nicht gesetzte Attribute. | Besitzer, die Gruppe und andere User an. Dabei steht das r f<>r read, w f<>r | ||||||
|  | write und x f<>r execute. An ihrer Stelle k<>nnen auch Striche stehen, die | ||||||
|  | repr<EFBFBD>sentieren nicht gesetzte Attribute. Die Datei im Beispiel ist also f<>r | ||||||
|  | ihren Besitzer les- und schreibbar, f<>r alle anderen nur lesbar. Die | ||||||
|  | Berechtigungen werden mit dem Kommando \texttt{chmod} (Abschnitt \ref{chmod}) | ||||||
|  | gesetzt. | ||||||
|  |  | ||||||
| TODO!!! ls | Die n<>chste Spalte stellt die Anzahl der Links dar, die auf diese Datei | ||||||
|  | verweisen, im Beispiel existiert die Datei an nur einer Stelle im Filesystem. | ||||||
|  |  | ||||||
|  | Dann folgen der Benutzer und die Gruppe, denen die Datei geh<65>rt. Diese | ||||||
|  | Parameter werden mit \texttt{chown} (Abschnitt \ref{chown}) bzw. \texttt{chgrp} | ||||||
|  | (Abschnitt \ref{chgrp}) gesetzt. | ||||||
|  |  | ||||||
|  | Es folgt die Gr<47><72>e der Datei in Bytes, sowie das Datum der letzten <20>nderung. | ||||||
|  | Liegt dieses mehr als ein halbes Jahr zur<75>ck wird an Stelle der Uhrzeit die | ||||||
|  | Jahreszahl angegeben, es gilt also Vorsicht walten zu lassen, wenn dieser Wert | ||||||
|  | in Skripten benutzt werden soll. | ||||||
|  |  | ||||||
|  | Abschlie<EFBFBD>end wird der Name der jeweiligen Datei ausgegeben. | ||||||
|  |  | ||||||
| \index{ls=\texttt{ls}|)} | \index{ls=\texttt{ls}|)} | ||||||
|  |  | ||||||
| @@ -545,6 +873,25 @@ wird der Vorgang interaktiv, vor jeder Dateibewegung wird nachgefragt. | |||||||
| \index{mv=\texttt{mv}|)} | \index{mv=\texttt{mv}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | \subsection{paste}\label{paste}\index{paste=\texttt{paste}|(textbf} | ||||||
|  |  | ||||||
|  | W<EFBFBD>hrend mit \texttt{cut} (Abschnitt \ref{cut}) Dateien spaltenweise zerlegt | ||||||
|  | werden, werden sie mit \texttt{paste} zusammengef<65>hrt. Die Dateinamen werden | ||||||
|  | als Parameter <20>bergeben, woraufhin Zeile f<>r Zeile die Inhalte aller Dateien zu | ||||||
|  | einer Tabelle gemacht werden. | ||||||
|  |  | ||||||
|  | Die Spalten werden standardm<64><6D>ig durch Tabulatorzeichen getrennt, man kann mit | ||||||
|  | dem Parameter \texttt{-d} auch ein oder mehrere andere Trennzeichen definieren. | ||||||
|  | Werden mehrere Zeichen angegeben, werden sie der Reihe nach zum trennen der | ||||||
|  | Spalten benutzt. | ||||||
|  |  | ||||||
|  | Mit \texttt{-s} wird die Tabelle transponiert, also praktisch um 90 Grad | ||||||
|  | gedreht. | ||||||
|  |  | ||||||
|  | \index{paste=\texttt{paste}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf} | \subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf} | ||||||
|  |  | ||||||
| @@ -640,7 +987,65 @@ dazu steht im Abschnitt  | |||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{ps}\label{ps}\index{ps=\texttt{ps}|(textbf} | \subsection{ps}\label{ps}\index{ps=\texttt{ps}|(textbf} | ||||||
|  |  | ||||||
| TODO!!! ps | Mit \texttt{ps} gibt man einen Schnappschu<68> des Zustandes der aktuell laufenden | ||||||
|  | Prozesse aus\footnote{Wenn man interaktiv den Zustand der laufenden Prozesse | ||||||
|  | beobachten m<>chte, benutzt man \texttt{top}, das eignet sich jedoch nicht zur | ||||||
|  | Shell-Programmierung und wird deshalb nicht ausf<73>hrlich beschrieben.}. | ||||||
|  |  | ||||||
|  | Ohne weitere Parameter listet \texttt{ps} alle Prozesse auf, die dem | ||||||
|  | aufrufenden Benutzer geh<65>ren und die mit dem aktuellen Terminal assoziiert | ||||||
|  | sind. Angezeigt werden dann die Proze<7A>-ID, das Terminal, die verbrauchte | ||||||
|  | CPU-Zeit und der Name des laufenden Kommandos. | ||||||
|  |  | ||||||
|  | In Skripten m<>chte man <20>blicherweise feststellen, ob ein bestimmtes Kommando | ||||||
|  | aktiv ist, ob also zum Beispiel ein bestimmter Serverdienst l<>uft. Dazu macht | ||||||
|  | man \texttt{ps} <20>ber Optionen gespr<70>chiger. | ||||||
|  |  | ||||||
|  | Das Kommando versteht in der GNU-Version zwei unterschiedliche Arten von | ||||||
|  | Optionen. Den sogenannten Unix- bzw. Posix-Stil und den BSD-Stil. Zus<75>tzlich | ||||||
|  | gibt es noch ausf<73>hrliche Parameter, aber die sollen hier nicht beschrieben | ||||||
|  | werden. Die jeweiligen Formen stehen nicht auf allen Systemen zur Verf<72>gung, | ||||||
|  | wenn ein Skript beispielsweise auch unter Solaris benutzt werden soll ist man | ||||||
|  | gezwungen, die Unix-Parametrisierung zu benutzen. | ||||||
|  |  | ||||||
|  | Unix-Parameter zeichnen sich durch die <20>bliche Angabe mit Bindestrich aus. | ||||||
|  | BSD-Pa\-ra\-me\-ter werden ohne Bindestrich angegeben, was neben den meisten | ||||||
|  | anderen Kommandos etwas ungewohnt aussieht. | ||||||
|  |  | ||||||
|  | Es gibt sehr viele verschiedene Parameter, die beste Informationsquelle ist wie | ||||||
|  | immer die Man-Page bzw. ein entsprechendes Buch. Hier werden nur ein paar | ||||||
|  | typische Aufrufbeispiele gezeigt, deren Ausgabe sich jeder selber ansehen kann: | ||||||
|  |  | ||||||
|  | \footnotesize | ||||||
|  | \begin{listing}[2]{1} | ||||||
|  | # Alle Prozesse auflisten, Unix-Syntax: | ||||||
|  | ps -e | ||||||
|  | ps -ef | ||||||
|  | ps -eF | ||||||
|  | ps -ely | ||||||
|  |  | ||||||
|  | # Alle Prozesse auflisten, BSD-Syntax: | ||||||
|  | ps ax | ||||||
|  | ps axu | ||||||
|  |  | ||||||
|  | # Proze<7A>baum ausgeben. Das ist in Skripten weniger Sinnvoll, wird hier aber | ||||||
|  | # angegeben weil es so eine praktische Funktion ist... :-) | ||||||
|  | ps -ejH | ||||||
|  | ps axjf | ||||||
|  |  | ||||||
|  | # Alle Prozesse ausgeben, die nicht dem Benutzer `root' geh<65>ren: | ||||||
|  | ps -U root -u root -N | ||||||
|  |  | ||||||
|  | # Nur die Proze<7A>-ID von Syslog ausgeben: | ||||||
|  | ps -C syslogd -o pid= | ||||||
|  |  | ||||||
|  | # Nur den Namen des Prozesses mit der ID 42 ausgeben: | ||||||
|  | ps -p 42 -o comm= | ||||||
|  | \end{listing} | ||||||
|  | \normalsize | ||||||
|  |  | ||||||
|  | F<EFBFBD>r die Suche nach Prozessen bestimmten Namens steht auf manchen Systemen auch | ||||||
|  | das Kommando \texttt{pgrep} (Abschnitt \ref{pgrep}) zur Verf<72>gung. | ||||||
|  |  | ||||||
| Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}. | Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}. | ||||||
|  |  | ||||||
| @@ -755,7 +1160,203 @@ debuggen, da sowohl Ein- als auch Ausgaben in dem Logfile sichtbar sind. | |||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{sed}\label{sed}\index{sed=\texttt{sed}|(textbf} | \subsection{sed}\label{sed}\index{sed=\texttt{sed}|(textbf} | ||||||
|  |  | ||||||
| TODO!!! sed | Der `Stream Editor' \texttt{sed} stellt, <20>hnlich wie \texttt{awk} (Abschnitt | ||||||
|  | \ref{awk}) eigentlich eine eigene Skriptsprache dar. Er wird auch | ||||||
|  | `nicht-interaktiver Editor' genannt. Die Kommandos sind minimalistisch, aber | ||||||
|  | exakt auf die Aufgabe zugeschnitten. | ||||||
|  |  | ||||||
|  | \texttt{sed} liest Zeilenweise aus einer Datei, wenn keine Datei angegeben | ||||||
|  | wurde wird von der Standard-Eingabe gelesen. Auf die eingelesenen Zeilen wird | ||||||
|  | dann ein mehr oder weniger kompliziertes \texttt{sed}-Skript angewendet, bevor | ||||||
|  | auf der Standard-Ausgabe die Resultate ausgegeben werden. | ||||||
|  |  | ||||||
|  | Eine vollst<73>ndige Beschreibung von \texttt{sed} w<>rde an dieser Stelle den | ||||||
|  | Rahmen sprengen, es gibt aber im Handel gute B<>cher zu dem Thema. Hier sollen | ||||||
|  | nur die g<>ngigsten Kommandos und einige Anwendungsbeispiele genannt werden. | ||||||
|  |  | ||||||
|  | \subsubsection{Aufruf} | ||||||
|  |  | ||||||
|  | \footnotesize | ||||||
|  | \begin{listing}[2]{1} | ||||||
|  | # Aufruf als Stream-Editor: | ||||||
|  | kommando1 | sed 's/alt/neu/' | kommando2 | ||||||
|  |  | ||||||
|  | # Aufruf mit einer zu bearbeitenden Datei: | ||||||
|  | sed 's/alt/neu/' datei.txt | ||||||
|  |  | ||||||
|  | # Wenn mehr als ein Kommando ausgef<65>hrt werden soll, mu<6D> der Parameter -e | ||||||
|  | # verwendet werden: | ||||||
|  | sed -e 's/alt/neu/' -e '/loeschen/d' datei.txt | ||||||
|  |  | ||||||
|  | # Man kann auch mehrere Kommandos mit einem -e aufrufen, wenn sie durch ein | ||||||
|  | # Semikolon getrennt werden: | ||||||
|  | sed 's/alt/neu/; /loeschen/d' datei.txt | ||||||
|  |  | ||||||
|  | # In einem Skript kann das Kommando auch <20>ber mehrere Zeilen gehen: | ||||||
|  | sed ' | ||||||
|  | s/alt/neu/ | ||||||
|  | /loeschen/d' datei.txt | ||||||
|  |  | ||||||
|  | # Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert und | ||||||
|  | # <20>ber den Parameter -f eingebunden werden: | ||||||
|  | sed -f script.sed datei.txt | ||||||
|  | \end{listing} | ||||||
|  | \normalsize | ||||||
|  |  | ||||||
|  | Neben den oben erw<72>hnten Parametern kann \texttt{sed} auch mit \texttt{-n} | ||||||
|  | ruhig gestellt werden. Damit werden die Zeilen nur dann ausgegeben, wenn das | ||||||
|  | mittels `p' explizit gefordert wird. Die GNU-Version stellt noch ein paar | ||||||
|  | Parameter zur Verf<72>gung, die Man-Page verr<72>t n<>heres. | ||||||
|  |  | ||||||
|  | \subsubsection{Addressierung} | ||||||
|  |  | ||||||
|  | Durch die Adressierung k<>nnen Befehle gezielt auf bestimmte Zeilen angewandt | ||||||
|  | werden. Dabei k<>nnen einem Befehl keine, eine oder zwei Adressen mitgegeben | ||||||
|  | werden. | ||||||
|  |  | ||||||
|  | Wenn keine Zeilen adressiert werden, wirkt der Befehl auf alle Zeilen. | ||||||
|  |  | ||||||
|  | Wenn eine Adresse mitgegeben wird, wirkt der Befehl auf alle Zeilen die durch | ||||||
|  | diese Adresse angesprochen werden. Das k<>nnen, zum Beispiel bei einem regul<75>ren | ||||||
|  | Ausdruck, auch mehrere Zeilen sein. | ||||||
|  |  | ||||||
|  | Werden zwei Adressen angegeben, wirkt der Befehl auf die erste betroffene | ||||||
|  | Zeile, sowie auf alle weiteren bis zur zweiten angegebenen Zeile. Die beiden | ||||||
|  | Adressen m<>ssen durch ein Komma getrennt angegeben werden. | ||||||
|  |  | ||||||
|  | Die Auswahl der Zeilen kann durch ein an die Adresse angeh<65>ngtes Rufzeichen | ||||||
|  | negiert werden, der Befehl wirkt dann also auf alle Zeilen die \textbf{nicht} | ||||||
|  | adressiert wurden. | ||||||
|  |  | ||||||
|  | Aber wie sehen solche Adre<72>angeben aus? Die folgende Tabelle zeigt einige | ||||||
|  | Beispiele anhand des Kommandos `d', mit dem Zeilen gel<65>scht werden: | ||||||
|  |  | ||||||
|  | \LTXtable{\textwidth}{tab_kommandos_sed_adressen.tex} | ||||||
|  |  | ||||||
|  | Adressen k<>nnen auch vor geschweiften Klammern stehen, dann wirken sie auf die | ||||||
|  | komplette Befehlsfolge innerhalb der Klammern. | ||||||
|  |  | ||||||
|  | \subsubsection{Kommandos} | ||||||
|  |  | ||||||
|  | Es gibt eine ganze Reihe von Kommandos, diese Beschreibung konzentriert sich | ||||||
|  | aber auf die wichtigsten `Brot und Butter-Kommandos'. In den Beispielen weiter | ||||||
|  | unten kommen auch andere Kommandos vor, die k<>nnen bei Bedarf anhand der | ||||||
|  | einschl<EFBFBD>gigen Quellen nachgeschlagen werden. | ||||||
|  |  | ||||||
|  | \LTXtable{\textwidth}{tab_kommandos_sed_kommandos.tex} | ||||||
|  |  | ||||||
|  | Mit \texttt{s} wird substituiert. Das hei<65>t, in der Eingabezeile wird nach | ||||||
|  | einem Muster gesucht, und im Erfolgsfall wird es ersetzt. Wichtigster | ||||||
|  | Modifikator f<>r dieses Kommando ist \texttt{g}, damit wird `global' ersetzt, | ||||||
|  | falls mehrere Fundstellen in einer Zeile vorkommen. Der Aufruf sieht wie folgt | ||||||
|  | aus: | ||||||
|  |  | ||||||
|  | \texttt{s/Suchmuster/Ersatzmuster/g} | ||||||
|  |  | ||||||
|  | Im Ersatzmuster k<>nnen auch Teile der Fundstelle wieder vorkommen, wenn sie | ||||||
|  | durch Klammern in einen Puffer kopiert werden: | ||||||
|  |  | ||||||
|  | \texttt{s/Seite ([0-9]*) von ([0-9]*)/\textbackslash{}1 aus \textbackslash{}2/} | ||||||
|  |  | ||||||
|  | Mit \texttt{y} hingegen werden einzelne Buchstaben durch andere vertauscht. Das | ||||||
|  | folgende Kommando wandelt alle eingehenden Kleinbuchstaben in Gro<72>buchstaben | ||||||
|  | um\footnote{Umlaute und Sonderzeichen ausgeschlossen}: | ||||||
|  |  | ||||||
|  | \texttt{y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/} | ||||||
|  |  | ||||||
|  | Normalerweise werden alle Eingabezeilen nach der Bearbeitung wieder ausgegeben, | ||||||
|  | unabh<EFBFBD>ngig davon ob sie ver<65>ndert wurden oder nicht. Das Verhalten kann <20>ber | ||||||
|  | den Kommandozeilenparameter \texttt{-n} abgeschaltet werden. Da dann allerdings | ||||||
|  | nichts mehr ausgegeben wird kann durch ein an ein Kommando angeh<65>ngtes | ||||||
|  | \texttt{p} bestimmt werden, da<64> die Ver<65>nderten Zeilen~--~und nur | ||||||
|  | die~--~ausgegeben werden. | ||||||
|  |  | ||||||
|  | \subsubsection{Beispiele} | ||||||
|  |  | ||||||
|  | Da es in diesem Text nicht um \texttt{sed}-Skripte, sondern um Shell-Skripte | ||||||
|  | gehen soll werden hier keine komplexen Sachen vorgestellt, sondern nur ein paar | ||||||
|  | Einzeiler. Nichtsdestotrotz k<>nnen es auch diese unscheinbaren Aufrufe in sich | ||||||
|  | haben. | ||||||
|  |  | ||||||
|  | \footnotesize | ||||||
|  | \begin{listing}[2]{1} | ||||||
|  | ### SUCHEN UND ERSETZEN | ||||||
|  |  | ||||||
|  | # Im kompletten Text 'rot' durch 'blau' ersetzen: | ||||||
|  | sed 's/rot/blau/'   # Ersetzt nur das erste Vorkommen in jeder Zeile | ||||||
|  | sed 's/rot/blau/4'  # Ersetzt nur das vierte Vorkommen in jeder Zeile | ||||||
|  | sed 's/rot/blau/g'  # Ersetzt nur jedes Vorkommen in jeder Zeile | ||||||
|  |  | ||||||
|  | # 'rot' durch 'blau' ersetzen, aber NUR in Zeilen die auch 'gelb' enthalten: | ||||||
|  | sed '/gelb/s/rot/blau/g' | ||||||
|  |  | ||||||
|  | # 'rot' durch 'blau' ersetzen, AUSSER in Zeilen die auch 'gelb' enthalten: | ||||||
|  | sed '/gelb/!s/rot/blau/g' | ||||||
|  |  | ||||||
|  | # 'rosa', 'hellrot' und 'magenta' durch 'pink' ersetzen: | ||||||
|  | sed 's/rosa/pink/g;s/hellrot/pink/g;s/magenta/pink/g' | ||||||
|  | gsed 's/rosa\|hellrot\|magenta/pink/g'                # nur in GNU sed | ||||||
|  |  | ||||||
|  | # Jede Zeile um f<>nf Leerzeichen einr<6E>cken: | ||||||
|  | # lies: 'ersetze jeden Zeilenanfang durch f<>nf Leerzeichen' | ||||||
|  | sed 's/^/     /' | ||||||
|  |  | ||||||
|  | # F<>hrende Blanks (Leerzeichen, Tabulatoren) von den Zeilenanf<6E>ngen l<>schen: | ||||||
|  | # ACHTUNG: An Stelle des \t mu<6D> der Tabulator gedr<64>ckt werden, die Darstellung | ||||||
|  | #          als \t versteht nicht jedes sed! | ||||||
|  | sed 's/^[ \t]*//' | ||||||
|  |  | ||||||
|  | # Schliessende Blanks vom Zeilenende l<>schen, siehe oben: | ||||||
|  | sed 's/[ \t]*$//' | ||||||
|  |  | ||||||
|  | # F<>hrende und schlie<69>ende Blanks l<>schen: | ||||||
|  | sed 's/^[ \t]*//;s/[ \t]*$//' | ||||||
|  |  | ||||||
|  | # Wenn eine Zeile mit Backslash aufh<66>rt den Zeilenumbruch entfernen: | ||||||
|  | sed -e :a -e '/\\$/N; s/\\\n//; ta' | ||||||
|  |  | ||||||
|  | ### BESTIMMTE ZEILEN AUSGEBEN | ||||||
|  |  | ||||||
|  | # Nur Zeile 42 ausgeben: | ||||||
|  | sed -n '42p'                 # Methode 1 | ||||||
|  | sed '42!d'                   # Methode 2 | ||||||
|  |  | ||||||
|  | # Nur die Zeilen 23-42 ausgeben (inklusive): | ||||||
|  | sed -n '23,42p'              # Methode 1 | ||||||
|  | sed '23,42!d'                # Methode 2 | ||||||
|  |  | ||||||
|  | # Von einem regul<75>ren Ausdruck bis zum Dateiende ausgeben: | ||||||
|  | sed -n '/regexp/,$p' | ||||||
|  |  | ||||||
|  | # Den Bereich zwischen zwei regul<75>ren Ausdr<64>cken ausgeben (inklusive): | ||||||
|  | sed -n '/rot/,/blau/p' | ||||||
|  |  | ||||||
|  | # Nur Zeilen mit mindestens 42 Zeichen ausgeben: | ||||||
|  | sed -n '/^.\{42\}/p' | ||||||
|  |  | ||||||
|  | # Nur Zeilen mit h<>chstens 42 Zeichen ausgeben: | ||||||
|  | sed -n '/^.\{42\}/!p'        # Methode 1, analog zu oben | ||||||
|  | sed '/^.\{42\}/d'            # Methode 2, einfachere Syntax | ||||||
|  |  | ||||||
|  | ### BESTIMMTE ZEILEN L<>SCHEN | ||||||
|  |  | ||||||
|  | # Die ersten zehn Zeilen l<>schen: | ||||||
|  | sed '1,10d' | ||||||
|  |  | ||||||
|  | # Die letzte Zeile l<>schen: | ||||||
|  | sed '$d' | ||||||
|  |  | ||||||
|  | # Alles au<61>er dem Bereich zwischen zwei regul<75>ren Ausdr<64>cken ausgeben: | ||||||
|  | sed '/rot/,/blau/d' | ||||||
|  |  | ||||||
|  | # Alle Leerzeilen l<>schen: | ||||||
|  | sed '/^$/d'                           # Methode 1 | ||||||
|  | sed '/./!d'                           # Methode 2 | ||||||
|  |  | ||||||
|  | # Alle Leerzeilen am Dateianfang l<>schen: | ||||||
|  | sed '/./,$!d' | ||||||
|  | \end{listing} | ||||||
|  | \normalsize | ||||||
|  |  | ||||||
| \index{sed=\texttt{sed}|)} | \index{sed=\texttt{sed}|)} | ||||||
|  |  | ||||||
| @@ -882,6 +1483,113 @@ Referenzdatei angepa | |||||||
| \index{touch=\texttt{touch}|)} | \index{touch=\texttt{touch}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | \subsection{tr}\label{tr}\index{tr=\texttt{tr}|(textbf} | ||||||
|  |  | ||||||
|  | Will man ganze Worte oder komplexe Muster in Dateien oder Pipes suchen und | ||||||
|  | ersetzen, greift man <20>blicherweise zu \texttt{sed} (Abschnitt \ref{sed}). F<>r | ||||||
|  | einzelne Buchstaben nimmt man hingegen \texttt{tr}. | ||||||
|  |  | ||||||
|  | Normalerweise wird \texttt{tr} mit zwei Zeichenketten als Parametern | ||||||
|  | aufgerufen und <20>bernimmt die zu konvertierenden Daten von der Standard-Eingabe. | ||||||
|  | Jedes Zeichen im eingehenden Datenstrom wird anhand der beiden Zeichenketten | ||||||
|  | ersetzt, dabei wird das erste Zeichen der ersten Kette durch das erste Zeichen | ||||||
|  | der zweiten Kette ersetzt, das zweite durch das zweite, und so weiter. | ||||||
|  |  | ||||||
|  | Ist die zweite Zeichenkette l<>nger als die erste, werden <20>bersch<63>ssige Zeichen | ||||||
|  | ignoriert. Ist die zweite Zeichenkette k<>rzer als die erste, wird ihr letztes | ||||||
|  | Zeichen so lange wiederholt bis sie gleich sind. Durch den Parameter | ||||||
|  | \texttt{-t} kann dieses Verhalten abgeschaltet werden, so da<64> <20>bersch<63>ssige | ||||||
|  | Zeichen abgeschnitten werden. | ||||||
|  |  | ||||||
|  | Mit dem Parameter \texttt{-c} wird die erste Zeichenkette `invertiert', es | ||||||
|  | werden also alle Zeichen ersetzt die nicht darin vorkommen. | ||||||
|  |  | ||||||
|  | \texttt{tr} kann aber auch mit nur einer Zeichenkette aufgerufen werden, wenn | ||||||
|  | die Parameter \texttt{-d} oder \texttt{-s} benutzt werden. Mit \texttt{-d} | ||||||
|  | werden alle Zeichen aus dem Eingabestrom gel<65>scht, die in der Zeichenkette | ||||||
|  | vorkommen. Mit \texttt{-s} werden doppelt vorkommende Zeichen durch ein | ||||||
|  | einzelnes ersetzt. | ||||||
|  |  | ||||||
|  | Die Zeichenketten an sich k<>nnen <20>brigens nicht nur Buchstaben oder Zahlen | ||||||
|  | enthalten, sondern auch Sonderzeichen oder Zeichenklassen. N<>heres dazu steht | ||||||
|  | in der Man-Page. | ||||||
|  |  | ||||||
|  | Die folgenden Beispiele verdeutlichen die Anwendung: | ||||||
|  |  | ||||||
|  | \footnotesize | ||||||
|  | \begin{listing}[2]{1} | ||||||
|  | text="Dies ist ein Testtext" | ||||||
|  |  | ||||||
|  | # kleine Umlaute durch grosse ersetzen: | ||||||
|  | echo "$text" | tr aeiou AEIOU | ||||||
|  | # -> DIEs Ist EIn TEsttExt | ||||||
|  |  | ||||||
|  | # Kleinbuchstaben durch Gro<72>buchstaben ersetzen: | ||||||
|  | echo "$text" | tr a-z A-Z | ||||||
|  | # -> DIES IST EIN TESTTEXT | ||||||
|  |  | ||||||
|  | # alle Vokale durch Unterstriche ersetzen: | ||||||
|  | echo "$text" | tr aeiouAEIOU _ | ||||||
|  | # -> D__s _st __n T_stt_xt | ||||||
|  |  | ||||||
|  | # Gro<72>buchstaben l<>schen: | ||||||
|  | echo "$text" | tr -d A-Z | ||||||
|  | # -> ies ist ein esttext | ||||||
|  |  | ||||||
|  | # doppelte Buchstaben l<>schen: | ||||||
|  | echo "$text" | tr -s "a-zA-Z" | ||||||
|  | # -> Dies ist ein Testext | ||||||
|  |  | ||||||
|  | # doppelte Buchstaben l<>schen, mit Zeichenklasse: | ||||||
|  | echo "$text" | tr -s "[:alpha:]" | ||||||
|  | # -> Dies ist ein Testext | ||||||
|  | \end{listing} | ||||||
|  | \normalsize | ||||||
|  |  | ||||||
|  | \index{tr=\texttt{tr}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | \subsection{trap}\label{trap}\index{trap=\texttt{trap}|(textbf} | ||||||
|  |  | ||||||
|  | Wie alle anderen Prozesse in einem Unix-System auch, so k<>nnen auch | ||||||
|  | Shell-Skripte Signale empfangen. Diese k<>nnen durch Kommandos wie \texttt{kill} | ||||||
|  | (Abschnitt \ref{kill}) geschickt worden sein, oder zum Beispiel durch einen | ||||||
|  | Tastatur-Interrupt. | ||||||
|  |  | ||||||
|  | Mit \texttt{trap} kann ein Skript darauf vorbereitet werden, ein oder mehrere | ||||||
|  | Signale zu empfangen. Beim Aufruf wird eine Aktion mitgegeben, und eine oder | ||||||
|  | mehrere Bedingungen die zum Ausf<73>hren der Aktion f<>hren sollen. Das folgende | ||||||
|  | Kommando gibt zm Beispiel eine Fehlermeldung aus wenn sein Skript ein Signal 1 | ||||||
|  | (HUP), 2 (INT) oder 15 (TERM) erh<72>lt: | ||||||
|  |  | ||||||
|  | \texttt{trap 'echo \dq`basename \$0`: Ooops...\dq 1>\&2' 1 2 15} | ||||||
|  |  | ||||||
|  | Die Zeile ist dem Beispiel aus Abschnitt \ref{traps} entnommen, dort findet | ||||||
|  | sich auch nochmal eine ausf<73>hrliche Erkl<6B>rung. | ||||||
|  |  | ||||||
|  | \index{trap=\texttt{trap}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | \subsection{uniq}\label{uniq}\index{uniq=\texttt{uniq}|(textbf} | ||||||
|  |  | ||||||
|  | Mit dem Kommando \texttt{uniq} werden doppelt vorkommende Zeilen in einer | ||||||
|  | Eingabedatei oder der eingehenden Pipe (Standard-Eingabe) bearbeitet. Per | ||||||
|  | default steht `bearbeitet' an dieser Stelle f<>r `gel<65>scht', aber durch | ||||||
|  | Parameter kann dieses Verhalten angepa<70>t werden: | ||||||
|  |  | ||||||
|  | \LTXtable{\textwidth}{tab_kommandos_uniq_parameter.tex} | ||||||
|  |  | ||||||
|  | Achtung: \texttt{uniq} betrachtet beim Vergleich nur direkt aufeinander | ||||||
|  | folgende Zeilen. Sollen alle Duplikate Dateiweit betrachtet werden, bietet sich | ||||||
|  | ein `vorsortieren' mit \texttt{sort} (Abschnitt \ref{sort}) an, vielleicht | ||||||
|  | sogar ausschlie<69>lich ein \texttt{sort -u}. | ||||||
|  |  | ||||||
|  | \index{uniq=\texttt{uniq}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{wc}\label{wc}\index{wc=\texttt{wc}|(textbf} | \subsection{wc}\label{wc}\index{wc=\texttt{wc}|(textbf} | ||||||
|  |  | ||||||
| @@ -898,6 +1606,19 @@ Der Parameter \texttt{-L} gibt die L | |||||||
| \index{wc=\texttt{wc}|)} | \index{wc=\texttt{wc}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | \subsection{which}\label{which}\index{which=\texttt{which}|(textbf} | ||||||
|  |  | ||||||
|  | Sucht im Pfad (vordefinierte Variable | ||||||
|  | \texttt{\$PATH}\index{\$PATH=\texttt{\$PATH}}, siehe Abschnitt | ||||||
|  | \ref{vordefinierte_variablen}) nach einer Ausf<73>hrbaren Datei. Wenn mehrere | ||||||
|  | Dateien auf das Suchwort passen wird die erste Fundstelle ausgegeben, also die | ||||||
|  | Datei die tats<74>chlich ausgef<65>hrt w<>rde. Mit \texttt{-a} werden alle Fundstellen | ||||||
|  | ausgegeben. | ||||||
|  |  | ||||||
|  | \index{which=\texttt{which}|)} | ||||||
|  |  | ||||||
|  |  | ||||||
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
| \subsection{who}\label{who}\index{who=\texttt{who}|(textbf} | \subsection{who}\label{who}\index{who=\texttt{who}|(textbf} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,27 +2,31 @@ | |||||||
| \chapter{Wie sieht ein Shell-Skript aus?} | \chapter{Wie sieht ein Shell-Skript aus?} | ||||||
| Wie schon erw<72>hnt, kann ein Shell-Skript beinahe alles, was eine `richtige' | Wie schon erw<72>hnt, kann ein Shell-Skript beinahe alles, was eine `richtige' | ||||||
| Programmiersprache auch kann. Bei der Entwicklung sollte man nur bedenken, da<64> | Programmiersprache auch kann. Bei der Entwicklung sollte man nur bedenken, da<64> | ||||||
| gerade die Ausf<EFBFBD>hrung von externen Kommandos~--~und das ist eine der | gerade die Aus\-f<EFBFBD>h\-rung von externen Kommandos~--~und das ist eine der | ||||||
| Standard-Techniken bei der Shell-Programmierung~--~nur sehr langsam vonstatten | Standard-Techniken bei der Shell-Pro\-gram\-mie\-rung~--~nur sehr langsam | ||||||
| geht. F<>r Anwendungen bei denen z. B. viele Rechnungen oder Stringbearbeitungen | vonstatten geht. F<>r Anwendungen bei denen z. B. viele Rechnungen oder | ||||||
| gemacht werden m<>ssen, sollte man also ggf. die Benutzung einer anderen | Stringbearbeitungen gemacht werden m<>ssen, sollte man also ggf. die Benutzung | ||||||
| Sprache, beispielsweise Perl\index{Perl}, in Erw<72>gung ziehen. | einer anderen Sprache, beispielsweise Perl\index{Perl}, in Erw<72>gung ziehen. | ||||||
|  |  | ||||||
| In der Shell stehen viele Mechanismen zur Verf<72>gung, die auch aus anderen Sprachen bekannt sind. Um den Umfang dieses Dokuments nicht zu sprengen, werden an dieser Stelle nur die wichtigsten vorgestellt. | In der Shell stehen viele Mechanismen zur Verf<72>gung, die auch aus anderen Sprachen bekannt sind. Um den Umfang dieses Dokuments nicht zu sprengen, werden an dieser Stelle nur die wichtigsten vorgestellt. | ||||||
|  |  | ||||||
|  |  | ||||||
| \section{Grunds<EFBFBD>tzliches} | \section{HowTo} | ||||||
|  |  | ||||||
| Zun<EFBFBD>chst soll die Frage gekl<6B>rt werden, wie man <20>berhaupt ein ausf<73>hrbares Shell-Skript schreibt. Dabei wird vorausgesetzt, da<64> dem Benutzer der Umgang mit mindestens einem Texteditor\index{Texteditor} (\texttt{vi}\index{vi=\texttt{vi}}, \texttt{emacs}\index{emacs=\texttt{emacs}} etc.) bekannt ist. | Zun<EFBFBD>chst soll die Frage gekl<6B>rt werden, wie man <20>berhaupt ein ausf<73>hrbares | ||||||
|  | Shell-Skript schreibt. Dabei wird vorausgesetzt, da<64> dem Benutzer der Umgang | ||||||
|  | mit mindestens einem Texteditor\index{Texteditor} | ||||||
|  | (\texttt{vi}\index{vi=\texttt{vi}}, \texttt{emacs}\index{emacs=\texttt{emacs}} | ||||||
|  | etc.) bekannt ist. | ||||||
|  |  | ||||||
| Bei der Erstellung oder Bearbeitung von Shell-Skripten mu<6D> darauf geachtet | Zun<EFBFBD>chst mu<6D> mit Hilfe des Editors eine Textdatei angelegt werden, in die der | ||||||
| werden, da<64> sich keine CR/LF-Zeilenumbr<62>che einschleichen, wie dies leicht bei | `Quelltext' geschrieben wird. Dabei mu<6D> darauf geachtet werden, da<64> sich keine | ||||||
| der Benutzung von MS-DOS bzw. Windows-Systemen zur Bearbeitung von Skripten | CR/LF-Zei\-len\-um\-br<EFBFBD>\-che einschleichen, wie dies leicht bei der Benutzung | ||||||
| <EFBFBD>ber das Netzwerk passieren kann. | von MS-DOS bzw. Windows-Systemen zur Bearbeitung von Skripten <EFBFBD>ber das Netzwerk | ||||||
|  | passieren kann. Wie der Quelltext aussieht, sollte man anhand der folgenden | ||||||
| \subsection{HowTo} | Abschnitte und der Beispiele im Anhang erkennen k<>nnen. Beim Schreiben sollte | ||||||
|  | man nicht mit den Kommentaren\index{Kommentar} geizen, da ein Shell-Skript auch | ||||||
| Zun<EFBFBD>chst mu<6D> mit Hilfe des Editors eine Textdatei angelegt werden, in die der `Quelltext' geschrieben wird. Wie der aussieht, sollte man anhand der folgenden Abschnitte und der Beispiele im Anhang erkennen k<>nnen. Beim Schreiben sollte man nicht mit den Kommentaren\index{Kommentar} geizen, da ein Shell-Skript auch schon mal sehr unleserlich werden kann. | schon mal sehr unleserlich werden kann. | ||||||
|  |  | ||||||
| Nach dem Abspeichern der Datei unter einem geeigneten Namen\footnote{Bitte | Nach dem Abspeichern der Datei unter einem geeigneten Namen\footnote{Bitte | ||||||
| \emph{nicht} den Namen \texttt{test}\index{test=\texttt{test}} verwenden. Es | \emph{nicht} den Namen \texttt{test}\index{test=\texttt{test}} verwenden. Es | ||||||
| @@ -32,25 +36,16 @@ ausgef | |||||||
| zugleich einer der verwirrendsten Anf<6E>ngerfehler. Mehr zu dem | zugleich einer der verwirrendsten Anf<6E>ngerfehler. Mehr zu dem | ||||||
| \texttt{test}-Kommando unter \ref{bedingungen}.} mu<6D> die sie ausf<73>hrbar gemacht | \texttt{test}-Kommando unter \ref{bedingungen}.} mu<6D> die sie ausf<73>hrbar gemacht | ||||||
| werden. Das geht mit dem Unix-Kommando | werden. Das geht mit dem Unix-Kommando | ||||||
| \texttt{chmod}\index{chmod=\texttt{chmod}}. Rechte k<>nnen unter Unix getrennt | \texttt{chmod}\index{chmod=\texttt{chmod}} und wird in Abschnitt \ref{chmod} | ||||||
| f<EFBFBD>r den Benutzer (user, \texttt{u}), die Gruppe (group, \texttt{g}) oder andere | ausf<EFBFBD>hrlich beschrieben. An dieser Stelle reicht uns ein Aufruf in der Form | ||||||
| (others, \texttt{o}) vergeben werden.  Au<41>erdem kann man die Rechte f<>r alle | \texttt{chmod 755 dateiname}, um das Skript f<>r alle Benutzer ausf<73>hrbar zu | ||||||
| Gruppen zusammen (all, a) setzen.  Man kann getrennt die Rechte f<>r das lesen | machen. | ||||||
| (read, \texttt{r}), das schreiben (write, \texttt{w}) und die Ausf<73>hrung |  | ||||||
| (execution, \texttt{x}) vergeben. Damit die Datei f<>r einen Benutzer wirklich |  | ||||||
| ausf<EFBFBD>hrbar ist, mu<6D> er das Lese- und das |  | ||||||
| Ausf<EFBFBD>hrungsrecht\index{Aus<EFBFBD>hrungsrecht} haben. Um die Rechte zu setzen, mu<6D> man |  | ||||||
| \texttt{chmod} in Parametern mitgeben, worauf sich das Kommando bezieht, ob das |  | ||||||
| Recht gesetzt (\texttt{+}) oder weggenommen (\texttt{-}) werden soll, und |  | ||||||
| welche Rechte gemeint sind. Damit alle Benutzer das Skript ausf<73>hren d<>rfen, |  | ||||||
| benutzt man das Kommando \texttt{chmod ugo+rx name} oder einfach \texttt{chmod |  | ||||||
| +rx name}.  Mit \texttt{chmod u+x name} hat nur der Besitzer der Datei |  | ||||||
| Ausf<EFBFBD>hrungsrechte. |  | ||||||
|  |  | ||||||
| Um ein Shell-Skript ausf<73>hren zu k<>nnen braucht es aus der Sicht des | Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgr<67>nden auf den | ||||||
| ausf<EFBFBD>hrenden Benutzers mindestens die Rechte zum Lesen (r) und Ausf<73>hren (x). | meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet, | ||||||
|  | mu<EFBFBD> man der Shell noch mitteilen, wo sie zu suchen hat: Mit \texttt{./name} | ||||||
| Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgr<67>nden auf den meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet, mu<6D> man der Shell noch mitteilen, wo sie zu suchen hat: Mit \texttt{./name} wird versucht, im aktuellen Verzeichnis (\texttt{./}) ein Programm namens \texttt{name} auszuf<75>hren. | wird versucht, im aktuellen Verzeichnis (\texttt{./}) ein Programm namens | ||||||
|  | \texttt{name} auszuf<75>hren. | ||||||
|  |  | ||||||
| Auf den meisten Systemen befindet sich im Pfad ein Verweis auf das Verzeichnis | Auf den meisten Systemen befindet sich im Pfad ein Verweis auf das Verzeichnis | ||||||
| \texttt{bin} unterhalb des Home-Verzeichnisses eines Benutzers. Das bedeutet | \texttt{bin} unterhalb des Home-Verzeichnisses eines Benutzers. Das bedeutet | ||||||
| @@ -60,7 +55,7 @@ kann man an der Shell durch Eingabe von \texttt{echo | |||||||
| \$PATH}\index{\$PATH=\texttt{\$PATH}} herausfinden. | \$PATH}\index{\$PATH=\texttt{\$PATH}} herausfinden. | ||||||
|  |  | ||||||
|  |  | ||||||
| \subsection{R<EFBFBD>ckgabewerte}\label{exitcode}\index{R<EFBFBD>ckgabewert|(textbf}\index{Exit-Code|see{R<EFBFBD>ckgabewert}}\index{Exit-Status|see{R<EFBFBD>ckgabewert}} | \section{R<EFBFBD>ckgabewerte}\label{exitcode}\index{R<EFBFBD>ckgabewert|(textbf}\index{Exit-Code|see{R<EFBFBD>ckgabewert}}\index{Exit-Status|see{R<EFBFBD>ckgabewert}} | ||||||
|  |  | ||||||
| Wenn unter Unix ein Proze<7A> beendet wird, gibt er einen R<>ckgabewert (auch | Wenn unter Unix ein Proze<7A> beendet wird, gibt er einen R<>ckgabewert (auch | ||||||
| Exit-Code oder Exit-Status genannt) an seinen aufrufenden Proze<7A> zur<75>ck. So | Exit-Code oder Exit-Status genannt) an seinen aufrufenden Proze<7A> zur<75>ck. So | ||||||
| @@ -281,7 +276,9 @@ Ausdruck}}\index{Ausdruck|see{Regul | |||||||
| wesentlich mehr M<>glichkeiten als die relativ einfachen Wildcards f<>r | wesentlich mehr M<>glichkeiten als die relativ einfachen Wildcards f<>r | ||||||
| Dateinamen. | Dateinamen. | ||||||
|  |  | ||||||
| In der folgenden Tabelle wird gezeigt, in welchen Unix-Tools welche Zeichen zur Verf<72>gung stehen. Eine ausf<73>hrlichere Beschreibung der Eintr<74>ge findet sich auf Seite \pageref{beschreibung_der_muster}. \nopagebreak | In der folgenden Tabelle wird gezeigt, in welchen Unix-Tools welche Zeichen zur | ||||||
|  | Ver\-f<EFBFBD>\-gung stehen. Eine ausf<73>hrlichere Beschreibung der Eintr<74>ge findet sich | ||||||
|  | auf Seite \pageref{beschreibung_der_muster}. \nopagebreak | ||||||
| \LTXtable{\textwidth}{tab_mustererkennung_muster.tex} | \LTXtable{\textwidth}{tab_mustererkennung_muster.tex} | ||||||
|  |  | ||||||
| Bei einigen Tools (\texttt{ex}, \texttt{sed} und \texttt{ed}) werden zwei Muster angegeben: Ein Suchmuster (links) und ein Ersatzmuster (rechts). Nur die folgenden Zeichen sind in einem Ersatzmuster g<>ltig:\nopagebreak | Bei einigen Tools (\texttt{ex}, \texttt{sed} und \texttt{ed}) werden zwei Muster angegeben: Ein Suchmuster (links) und ein Ersatzmuster (rechts). Nur die folgenden Zeichen sind in einem Ersatzmuster g<>ltig:\nopagebreak | ||||||
| @@ -358,6 +355,54 @@ F | |||||||
| \index{Arithmetik-Expansion|)} | \index{Arithmetik-Expansion|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | \section{Eltern und Kinder: Proze<7A>ordnung\label{prozessordnung}\index{Prozess|(textbf}\index{PID|see{Prozess}}\index{Parent-Prozess|see{Prozess}}\index{PPID|see{Prozess}}\index{Subshell|(textbf}} | ||||||
|  |  | ||||||
|  | Jedes laufende Programm auf einem Unixoiden System besteht aus einem oder | ||||||
|  | mehreren Prozessen, die jeweils eine eigene Proze<7A>-ID (PID) haben. Erzeugt ein | ||||||
|  | Programm mehrere Prozesse, sind die zu einer Proze<7A>gruppe zusammengefa<66>t. Jeder | ||||||
|  | laufende Proze<7A>\footnote{Es gibt eine Ausnahme: der Init-Proze<7A>, der immer die | ||||||
|  | PID 1 hat, hat keine Eltern. Er stammt direkt vom Kernel ab.} verf<72>gt <20>ber | ||||||
|  | genau eine Parent-Proze<7A>-ID (PPID). Das ist die ID des Prozesses, der den | ||||||
|  | jeweiligen Proze<7A> erzeugt hat. Man spricht in diesem Zusammenhang tats<74>chlich | ||||||
|  | von Eltern- bzw. Kind-Prozessen. | ||||||
|  |  | ||||||
|  | Diese Zusammenh<6E>nge lassen sich sehr sch<63>n durch die Ausgabe des Kommandos | ||||||
|  | \texttt{pstree} oder \texttt{ps -efH} darstellen, letzteres zeigt auch gleich | ||||||
|  | die PIDs und die PPIDs an. | ||||||
|  |  | ||||||
|  | Wenn in einer Shell ein Kommando gestartet wird, ist es ein Kind dieser Shell. | ||||||
|  | Wird ein Skript gestartet, <20>ffnet es sich seine eigene Shell (siehe | ||||||
|  | \ref{auswahl_der_shell}) und f<>hrt sich innerhalb dieser aus. Die Shell des | ||||||
|  | Skriptes ist dabei ein Kind der interaktiven Shell, die einzelnen Kommandos des | ||||||
|  | Skriptes sind Kinder der Skript-Shell. | ||||||
|  |  | ||||||
|  | Eine solche Shell-in-Shell-Umgebung wird `Subshell' genannt, dieser | ||||||
|  | Mechanismus~--~und somit auch der Begriff~--~tauchen immer wieder auf. | ||||||
|  |  | ||||||
|  | Wichtig in diesem Zusammenhang ist das Verst<73>ndnis f<>r die Vererbung zwischen | ||||||
|  | den beteiligten Prozessen. Wenn in einer Shell eine Variable definiert und | ||||||
|  | exportiert wird, existiert diese auch f<>r die Kind-Prozesse. Gleiches gilt | ||||||
|  | beispielsweise f<>r einen Verzeichnis-Wechsel. Umgekehrt gilt dies nicht: ein | ||||||
|  | Proze<EFBFBD> kann die Umgebung des Parent-Prozesses nicht ver<65>ndern. Das geschieht | ||||||
|  | nicht zuletzt aus Sicherheitsgr<67>nden so. | ||||||
|  |  | ||||||
|  | Will man die <20>nderungen eines Skriptes <20>bernehmen~--~beispielsweise wenn ein | ||||||
|  | Skript die Benutzerumgebung konfigurieren soll (.bashrc, .profile und | ||||||
|  | Konsorten)~--~mu<6D> das explizit angefordert werden. Dazu ruft man es mit einem | ||||||
|  | vorangestellten \texttt{source}\index{source=\texttt{source}} bzw. in der | ||||||
|  | Kurzform mit einem vorangestellten Punkt auf. Weiteres zu dem Thema findet sich | ||||||
|  | im Abschnitt \ref{source}. | ||||||
|  |  | ||||||
|  | Besonders mu<6D> man diesen Umstand im Hinterkopf behalten, wenn mit | ||||||
|  | Pipelines\index{Pipe} (siehe Abschnitt \ref{befehlsformen}) gearbeitet wird. | ||||||
|  | Dabei werden auch Kommandos in Subshells ausgef<65>hrt, was dann dazu f<>hrt da<64> | ||||||
|  | Variablen belegt werden die dann nach Ausf<73>hrung der Pipeline pl<70>tzlich wieder | ||||||
|  | leer sind. Die Abschnitte \ref{subshellschleifen} und \ref{daten_hochreichen} | ||||||
|  | widmen sich diesem mitunter recht <20>rgerlichen Thema. | ||||||
|  |  | ||||||
|  | \index{Prozess|)}\index{Subshell|)} | ||||||
|  |  | ||||||
|  |  | ||||||
| \section{Programmablaufkontrolle} | \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 | 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 | ||||||
|   | |||||||
| @@ -1,6 +1,12 @@ | |||||||
| % $Id$ | % $Id$ | ||||||
| \chapter{Wof<EFBFBD>r Shell-Programmierung?} | \chapter{Wof<EFBFBD>r Shell-Programmierung?} | ||||||
|  |  | ||||||
|  | Nat<EFBFBD>rlich stellt sich die Frage, in welchen Situationen ein Shell-Skript der | ||||||
|  | richtige Weg ist, und wann man vielleicht doch besser zu einer interpretierten | ||||||
|  | oder compilierten Sprache greift. | ||||||
|  |  | ||||||
|  | \section{Wof<EFBFBD>r?} | ||||||
|  |  | ||||||
| Die Shell ist der perfekte Baukasten f<>r das Unix-Paradigma `small is | Die Shell ist der perfekte Baukasten f<>r das Unix-Paradigma `small is | ||||||
| beautiful'. Die mitgelieferten Unix-Standardkommandos sind einfach gehalten, | beautiful'. Die mitgelieferten Unix-Standardkommandos sind einfach gehalten, | ||||||
| erledigen aber auf effiziente Weise die Arbeit f<>r die sie programmiert wurden. | erledigen aber auf effiziente Weise die Arbeit f<>r die sie programmiert wurden. | ||||||
| @@ -23,3 +29,19 @@ Befehlen ausf | |||||||
| Beispiel eine Audio-CD kopieren soll, sollte das Brennprogramm nur dann | Beispiel eine Audio-CD kopieren soll, sollte das Brennprogramm nur dann | ||||||
| aufrufen, wenn der Einlesevorgang erfolgreich abgeschlossen wurde. | aufrufen, wenn der Einlesevorgang erfolgreich abgeschlossen wurde. | ||||||
|  |  | ||||||
|  | \section{Wof<EFBFBD>r nicht?} | ||||||
|  |  | ||||||
|  | Ein Shell-Skript besteht aus einer Abfolge von System-Tool-Aufrufen. Das hei<65>t, | ||||||
|  | f<EFBFBD>r jeden Schritt in einem Skript wird ein neuer Proze<7A> gestartet. Das kostet | ||||||
|  | eine Menge Systemzeit, die Skripte laufen also vergleichsweise langsam. F<>r | ||||||
|  | komplexe, zeitkritische oder langwierige Aufgaben sollte man also besser zu | ||||||
|  | Perl, Python oder in Extremf<6D>llen zu C / C++ greifen. | ||||||
|  |  | ||||||
|  | Shell-Skripte k<>nnen als imperativ angesehen werden, f<>r viele Aufgaben ist | ||||||
|  | aber ein objektorientierter Ansatz wesentlich geeigneter. Auch hier ist also | ||||||
|  | der Griff zu einer anderen Sprache angeraten. | ||||||
|  |  | ||||||
|  | Es gibt zwar ein paar Tools\footnote{Zum Beispiel dialog im Textmodus, oder | ||||||
|  | xmessage unter X.}, mit denen auch Shell-Skripte eine grafische oder | ||||||
|  | textorientierte Benutzeroberfl<66>che (GUI) bekommen k<>nnen, aber das ist trotzdem | ||||||
|  | nicht das nat<61>rliche Terrain der Shell-Programmierung. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user