Viele ueberarbeitungen

This commit is contained in:
rschaten 2004-11-12 12:07:32 +00:00
parent 7eea8ed0e9
commit 14dec49967
13 changed files with 568 additions and 52 deletions

View File

@ -1,5 +1,5 @@
% $Id$ % $Id$
\chapter{Quellen} \chapter{Quellen}\label{quellen}
\begin{itemize} \begin{itemize}
\item Bash Reference Manual (\texttt{http://www.gnu.org/manual/bash-2.02/\\bashref.html}) \item Bash Reference Manual (\texttt{http://www.gnu.org/manual/bash-2.02/\\bashref.html})
@ -11,6 +11,8 @@
TODO!!! Andere URL angeben (http://www.tldp.org...) TODO!!! Andere URL angeben (http://www.tldp.org...)
\item Bash Guide for Beginners (\texttt{http://tldp.org/LDP/Bash-Beginners-Guide/})
\item Advanced Bash-Scripting Guide (\texttt{http://tldp.org/LDP/abs/})
\item ... und eine Menge Skripte, die ich im Laufe der Zeit gelesen habe (das \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ört...). kann ich nur jedem empfehlen - es ist spannender als es sich anhört...).
\end{itemize} \end{itemize}

View File

@ -26,6 +26,8 @@ haben.
TODO!!! tar-Brücke TODO!!! tar-Brücke
%ssh 192.168.2.1 tar clf - / | (cd /mnt; tar xf - )
\section{Binaries inside} \section{Binaries inside}

View File

@ -119,8 +119,8 @@ irgendeiner Form Kommerz zu machen. Ich stelle es frei zur Verf
Hoffnung, daß andere Leute daraus vielleicht einen Nutzen ziehen können. Hoffnung, daß andere Leute daraus vielleicht einen Nutzen ziehen können.
\textbf{Aber ich übernehme keine Garantie für die Korrektheit der hier \textbf{Aber ich übernehme keine Garantie für die Korrektheit der hier
dargestellten Dinge.} Mit der Formulierung \textsl{`daraus vielleicht einen dargestellten Dinge.} Mit der Formulierung \textsl{`daraus vielleicht einen
Nutzen ziehen können'} meine ich nicht, daß dieses Dokument~---~oder Teile Nutzen ziehen können'} meine ich nicht, daß dieses Dokument~--~oder Teile
daraus~---~verkauft werden darf. \textbf{Dieses Dokument darf nur kostenlos daraus~--~verkauft werden darf. \textbf{Dieses Dokument darf nur kostenlos
weitergegeben werden.}\bigskip weitergegeben werden.}\bigskip
Ich danke folgenden Personen, die mir bei der Durchsicht behilflich waren und Ich danke folgenden Personen, die mir bei der Durchsicht behilflich waren und
@ -157,6 +157,7 @@ R
\include{beispiele} \include{beispiele}
\include{schmutzige_tricks} \include{schmutzige_tricks}
\include{quellen} \include{quellen}
\include{todo}
\printindex % Index einfügen \printindex % Index einfügen

View File

@ -10,5 +10,5 @@
\texttt{\$ ls neu*} & Listet alle Dateien, die mit `neu' anfangen \tabularnewline\STRUT \texttt{\$ ls neu*} & Listet alle Dateien, die mit `neu' anfangen \tabularnewline\STRUT
\texttt{\$ ls neu?} & Listet `neuX', `neu4', aber nicht `neu10' \tabularnewline\STRUT \texttt{\$ ls neu?} & Listet `neuX', `neu4', aber nicht `neu10' \tabularnewline\STRUT
\texttt{\$ ls [D-R]*} & Listet alle Dateien, die mit einem Großbuchstaben\index{Großbuchstaben}\footnote{Natürlich wird in Shell-Skripten --- wie überall in der Unix-Welt --- zwischen Groß- und Kleinschreibung unterschieden.} zwischen D und R anfangen \texttt{\$ ls [D-R]*} & Listet alle Dateien, die mit einem Großbuchstaben\index{Großbuchstaben}\footnote{Natürlich wird in Shell-Skripten~--~wie (fast) überall in der Unix-Welt~--~zwischen Groß- und Kleinschreibung unterschieden.} zwischen D und R anfangen
\end{longtable} \end{longtable}

View File

@ -0,0 +1,16 @@
% $Id$
\begin{longtable}{|l|l|X|}
% KILLED & LINE!!!! \kill
\hline
\endfirsthead
\endhead
\endfoot
\hline
\endlastfoot
a-x & & Allen Benutzern werden die Ausführungsrechte genommen \tabularnewline\STRUT
ug+rw & & Dem Besitzer und der Gruppe werden Lese- und Schreibrechte gegeben \tabularnewline\STRUT
u=rw,go-rwx & 600 & Nur der Besitzer kann die Datei lesen \tabularnewline\STRUT
u=rw,go=r & 644 & Der Besitzer darf lesen und schreiben, alle anderen nur lesen \tabularnewline\STRUT
u=rwx,go=rx & 755 & Der Besitzer darf lesen, schreiben und ausführen, alle anderen nur lesen und ausführen
\end{longtable}

View File

@ -0,0 +1,16 @@
% $Id$
\begin{longtable}{|l|X|}
% KILLED & LINE!!!! \kill
\hline
\endfirsthead
\endhead
\endfoot
\hline
\endlastfoot
\textsl{s=\dq{}Dies ist ein Test\dq{}} & ~ \tabularnewline\STRUT
\texttt{echo \dq{}\$s\dq{} | cut -c 2-6} & gibt `ies i' aus \tabularnewline\STRUT
\texttt{echo \dq{}\$s\dq{} | cut -d \dq{}~\dq{} -f 2} & gibt `ist' aus \tabularnewline\STRUT
\texttt{echo \dq{}\$s\dq{} | cut -d \dq{}~\dq{} -f 2-3} & gibt `ist ein' aus \tabularnewline\STRUT
\texttt{echo \dq{}\$s\dq{} | cut -d \dq{}~\dq{} -f 2-} & gibt `ist ein Test' aus
\end{longtable}

View File

@ -0,0 +1,29 @@
% $Id$
\begin{longtable}{|l|X|}
% KILLED & LINE!!!! \kill
\hline
\endfirsthead
\endhead
\endfoot
\hline
\endlastfoot
\texttt{|} & logisches `oder' \tabularnewline\STRUT
\texttt{\&} & logisches `und' \tabularnewline\STRUT
\texttt{<} & kleiner als \tabularnewline\STRUT
\texttt{<=} & kleiner als oder gleich \tabularnewline\STRUT
\texttt{=} & gleich \tabularnewline\STRUT
\texttt{!=} & ungleich \tabularnewline\STRUT
\texttt{>=} & größer als oder gleich \tabularnewline\STRUT
\texttt{>} & größer als \tabularnewline\STRUT
\texttt{+} & Addition \tabularnewline\STRUT
\texttt{-} & Subtraktion \tabularnewline\STRUT
\texttt{*} & Multiplikation \tabularnewline\STRUT
\texttt{/} & Division \tabularnewline\STRUT
\texttt{\%} & Modulo (`Divisionsrest') \tabularnewline\STRUT
\texttt{:} & Pattern-Match mit regulären Ausdrücken \tabularnewline\STRUT
\texttt{match} & Analog zu `:' \tabularnewline\STRUT
\texttt{substr} & Teil einer Zeichenkette zurückgeben \tabularnewline\STRUT
\texttt{index} & Position einer Zeichenkette in einer anderen finden \tabularnewline\STRUT
\texttt{length} & Länge einer Zeichenkette
\end{longtable}

View File

@ -0,0 +1,15 @@
% $Id$
\begin{longtable}{|l|X|}
% KILLED & LINE!!!! \kill
\hline
\endfirsthead
\endhead
\endfoot
\hline
\endlastfoot
\texttt{-f} & Normalerweise wird nur nach Prozeß-Namen gesucht, mit diesem Parameter wird das volle Kommando (incl. Pfad und Parametern) betrachtet\tabularnewline\STRUT
\texttt{-l} & Nicht nur die Prozeß-ID, sondern das volle Kommando wird ausgegeben\tabularnewline\STRUT
\texttt{-v} & Findet alle Zeilen, in denen das Suchmuster \emph{nicht} vorkommt\tabularnewline\STRUT
\texttt{-x} & Sucht nach Kommandos, deren Name dem Muster \emph{exakt} entspricht
\end{longtable}

View File

@ -0,0 +1,16 @@
% $Id$
\begin{longtable}{|l|X|}
% KILLED & LINE!!!! \kill
\hline
\endfirsthead
\endhead
\endfoot
\hline
\endlastfoot
\texttt{-k 3} & Sortiert nach dem dritten Feld \tabularnewline\STRUT
\texttt{-k 3.5} & Sortiert nach dem fünften Zeichen des dritten Feldes \tabularnewline\STRUT
\texttt{-k 3.5r} & Sortiert rückwärts nach dem fünften Zeichen des dritten Feldes \tabularnewline\STRUT
\texttt{-k 3,5} & Beachtet bei der Sortierung nur das dritte bis fünfte Feld \tabularnewline\STRUT
\texttt{-k 3.5,3.8} & Beachtet die Zeichen fünf bis acht des dritten Feldes
\end{longtable}

View File

@ -0,0 +1,20 @@
% $Id$
\begin{longtable}{|l|X|}
% KILLED & LINE!!!! \kill
\hline
\endfirsthead
\endhead
\endfoot
\hline
\endlastfoot
\texttt{-b} & Ignoriert führende Leerzeichen \tabularnewline\STRUT
\texttt{-c} & Prüft nur, ob die Eingabedaten bereits sortiert sind \tabularnewline\STRUT
\texttt{-f} & Groß- / Kleinschreibung nicht beachten \tabularnewline\STRUT
\texttt{-i} & Nur `printable' Zeichen beachten \tabularnewline\STRUT
\texttt{-k} & Sortiert nicht nach der ersten, sondern nach der angegebenen Spalte (siehe unten) \tabularnewline\STRUT
\texttt{-n} & Numerische Sortierung \tabularnewline\STRUT
\texttt{-r} & Sortierreihenfolge umkehren \tabularnewline\STRUT
\texttt{-t} & Normalerweise fängt ein Feld (siehe \texttt{-k}) beim Übergang von `blank' nach `non-blank' an, mit diesem Parameter können ander Feld-Trenner definiert werden \tabularnewline\STRUT
\texttt{-u} & Gibt bei identischen Zeilen nur die erste Fundstelle aus (unique)
\end{longtable}

29
todo.tex Normal file
View File

@ -0,0 +1,29 @@
% $Id$
\chapter{Routenplanung - Die Zukunft dieses Dokuments}
Ich werde in dieser Version des Dokumentes nicht alles umgesetzt haben, was mir
sinnvoll erscheint. An dieser Stelle sammele ich Ideen für eine nächste
Version. Kommentare dazu nehme ich jederzeit dankend entgegen.
\begin{itemize}
\item \textbf{GNU / Posix:} Bessere Abgrenzung der GNU-Erweiterungen
ge\-gen\-ü\-ber dem Posix-Standard, damit die Skripte portabel bleiben und
nicht nur auf Linux laufen.
\item \textbf{Performance:} Ein Kapitel mit Hinweisen, wie Skripte nicht
unnötig langsam werden.
\item \textbf{Interaktive Shell:} Exkurs zur interaktiven Benutzung der Bash.
Es gibt da eine Reihe hilfreicher Tastenkombinationen, die längst nicht jedem
bekannt sind.
\item \textbf{HTML-Version:} Ich würde gerne eine HTML-Version zur Verfügung
stellen, bin mir aber noch nicht sicher ob das aus den \LaTeX-Quellen geht. Mir
liegt dabei die Indizierung der Stichworte am Herzen, die sollte nicht
verloren gehen.
\item \textbf{Glossar:} Verzeichnis von Begriffen wie PID, Prompt, GID, UID,
Cron, usw.
\end{itemize}

View File

@ -24,9 +24,10 @@ Shell-Programmierer nicht sinnvoll um den Einsatz dieser Programme herum.
In diesem Abschnitt sollen einige dieser Programme mit typischen In diesem Abschnitt sollen einige dieser Programme mit typischen
Einsatzmöglichkeiten vorgestellt werden. Eine vollständige Beschreibung wäre Einsatzmöglichkeiten vorgestellt werden. Eine vollständige Beschreibung wäre
(wenn überhaupt möglich) viel zu lang, um an dieser Stelle untergebracht zu (wenn überhaupt möglich) viel zu lang, um an dieser Stelle untergebracht zu
werden. Für ausführlichere Beschreibungen empfiehlt sich das Studium der werden. \textbf{Dies ist also nur ein grober Überblick, nicht mal annähernd
Man-Pages oder der Kauf eines entsprechenden Buches. Am besten macht man eine vollständige Referenz!} Für ausführlichere Beschreibungen empfiehlt sich
natürlich beides. ;-) das Studium der Man-Pages oder der Kauf eines entsprechenden Buches (Siehe
Anhang \ref{quellen}, `Quellen'). Am besten macht man natürlich beides. ;-)
Eine globale Beschreibung aller gängigen Kommandos würde den Rahmen dieses Eine globale Beschreibung aller gängigen Kommandos würde den Rahmen dieses
Textes sprengen. Außerdem wäre es nicht leicht, das zu einer Aufgabe passende Textes sprengen. Außerdem wäre es nicht leicht, das zu einer Aufgabe passende
@ -85,10 +86,15 @@ 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{cp} (\ref{cp}): Dateien kopieren \item \texttt{cp} (\ref{cp}): Dateien kopieren
\item \texttt{chgrp} (\ref{chgrp}): Gruppen-ID einer Datei ändern
\item \texttt{chmod} (\ref{chmod}): Zugriffsrechte einer Datei ändern
\item \texttt{chown} (\ref{chown}): Eigentümer einer Datei ändern
\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{mv} (\ref{mv}): Dateien verschieben \item \texttt{mv} (\ref{mv}): Dateien verschieben
\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{touch} (\ref{touch}): Eine leere Datei anlegen, bzw. das Zugriffsdatum einer Datei ändern \item \texttt{touch} (\ref{touch}): Eine leere Datei anlegen, bzw. das Zugriffsdatum einer Datei ändern
\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}
@ -148,6 +154,13 @@ Verf
\section{... und Hämmer}\label{haemmer} \section{... und Hämmer}\label{haemmer}
Um es noch einmal zu betonen: \textbf{Dies ist keine vollständige
Kommandoreferenz!} Es werden nur die wichtigsten Kommandos vorgestellt, und
deren Funktion wird in den meisten Fällen auch nur kurz angerissen. Für
ausgiebigere Informationen empfehle ich entsprechende Bücher (siehe Anhang
\ref{quellen}, `Quellen') und vor allem die Man-Pages.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{awk}\label{awk}\index{awk=\texttt{awk}|(textbf} \subsection{awk}\label{awk}\index{awk=\texttt{awk}|(textbf}
@ -170,18 +183,14 @@ der eigentlichen Datei wird zur
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{bc}\label{bc}\index{bc=\texttt{bc}|(textbf} \subsection{bc}\label{bc}\index{bc=\texttt{bc}|(textbf}
Mit dem Kommando \texttt{bc} verfügt die Shell praktisch über einen Bei \texttt{bc} handelt es sich, ähnlich wie bei \texttt{expr} um einen
Taschenrechner. Die Man-Page verrät, daß es sich hierbei um ein erstaunlich Taschenrechner. Allerdings verfügt dieses Kommando um eine vergleichsweise
komplexes Programm handelt, in der Praxis findet man allerdings meistens komplexe Syntax, die auch Berechnungen mit hoher Genauigkeit zulassen.
einfache Anwendungen wie das inkrementieren einer Laufvariable (\texttt{i=`bc
\$i + 1`}).
Bei Multiplikationen ist darauf zu achten, daß der Stern in der Shell eine Für einfache Grundrechenaufgaben wie das Inkrementieren von Variablen sollte
Sonderbedeutung hat, er muß also gequoted werden: \texttt{i=`bc \$i man entweder die eingebaute Arithmetik-Expansion der Shell (Siehe
\textbackslash{}* 3`}. \ref{arithmetikexpansion}) oder das wesentlich ressourcenfreundlichere
\texttt{expr} (Siehe \ref{expr}) benutzen.
Eine andere Möglichkeit für einfache Rechnungen besteht in der sogenannten
Arithmetik-Expansion (Siehe \ref{arithmetikexpansion}).
\index{bc=\texttt{bc}|)} \index{bc=\texttt{bc}|)}
@ -211,6 +220,87 @@ werden.
\index{cat=\texttt{cat}|)} \index{cat=\texttt{cat}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{chgrp}\label{chgrp}\index{chgrp=\texttt{chgrp}|(textbf}
Jede Datei gehört einem Benutzer und einer Gruppe. Letzteres läßt sich mit
\texttt{chgrp} einstellen. Als Parameter wird der Name oder die ID der Gruppe,
sowie ein oder mehrere Dateinamen übergeben. Verzeichnisse können rekursiv mit
dem Parameter \texttt{-R} bearbeitet werden.
Der Eingentümer der Datei wird mit \texttt{chown} (Abschnitt \ref{chown})
festgelegt.
\index{chgrp=\texttt{chgrp}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{chmod}\label{chmod}\index{chmod=\texttt{chmod}|(textbf}
In unixoiden Systemen verfügt jede Datei über eine Reihe von Attributen. Damit
kann eine Menge gemacht werden, für den vollen Funktionsumfang empfiehlt sich
das Studium der Man-Page oder einer umfangreicheren Kommandoreferenz. Hier nur
das wichtigste in Kürze:
Die Syntax lautet \texttt{chmod [options] mode file...}.
Die einzig wichtige Option ist, analog zu \texttt{chgrp} und \texttt{chown} der
Parameter \texttt{-R} für die rekursive Bearbeitung von Verzeichnissen.
In der Syntax steht `file' für einen oder mehrere Dateinamen.
Den Modus einer Datei sieht man, indem man \texttt{ls -l} darauf ansetzt, die
Ausgabe wird im entsprechenden Abschnitt (\ref{ls}) beschrieben.
Dort ist von den drei `rwx-Blöcken' die Rede, die die Berechtigungen für User
(u), Group (g) und Other (o) angeben. Genau die können mittels \texttt{chmod}
gesteuert werden. Zusätzlich gibt es hier noch die Angabe All (a), mit denen
die Rechte für alle Benutzer verändert werden können.
Hier wird der Modus gesteuert, indem direkt angegeben wird für wen welche
Rechte gelten sollen. Mit `+' werden die Rechte erweitert, `-' nimmt Rechte
und mit `=' werden die Rechte hart gesetzt.
\texttt{chmod u+x datei} macht die Datei für den Besitzer ausführbar. Mit
\texttt{chmod u=rw,go=r datei} werden die Rechte auf `rw-r--r--' gesetzt, der
Besitzer kann lesen und schreiben, alle anderen nur lesen.
Neben dieser Art der Notation gibt es noch eine~--~wesentlich
gängigere~--~numerische Schreibweise. Dabei werden die Berechtigungen in Form
von Zahlen angegeben. Dabei werden drei Zahlen von eins bis sieben benutzt.
Deren Bedeutung ergibt sich, wenn man sich die drei Stellen `rwx' als Binärzahl
vorstellt. Das x steht an der niederwertigsten Stelle, erhält also den Wert 1.
Das w steht für die 2 und r für 4. In Summe ergeben diese Zahlen die
Berechtigung. Also ist `rwx' gleichbedeutend mit 4+2+1=7. `rw' entspricht
4+2=6. Die reine Leseberechtigung `r' bleibt als 4 stehen.
Zur Verdeutlichung ein paar Beispiele, wo es möglich ist in beiden Notationen:
\LTXtable{\textwidth}{tab_kommandos_chmod_beispiele.tex}
Am wichtigsten sind also die Aufrufe \texttt{chmod 644 datei} und \texttt{chmod
755 datei}, je nachdem ob die Datei ausführbar sein soll oder nicht.
\index{chmod=\texttt{chmod}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{chown}\label{chown}\index{chown=\texttt{chown}|(textbf}
Mit \texttt{chown} lassen sich Benutzer- und Gruppen-ID von Dateien und
Verzeichnissen festlegen. Mit dem Parameter \texttt{-R} sogar rekursiv für
Verzeichnisse.
Ein einzelner Parameter gibt die User-ID oder den Namen des zukünfigen
Benutzers an, in der Form name:gruppe können sowohl User- als auch Gruppen-ID
gleichzeitig geändert werden.
Will man lediglich die Gruppen-ID ändern, benutzt man das Kommando
\texttt{chgrp} (Abschnitt \ref{chgrp}).
\index{chown=\texttt{chown}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{chpasswd}\label{script}\index{chpasswd=\texttt{chpasswd}|(textbf} \subsection{chpasswd}\label{script}\index{chpasswd=\texttt{chpasswd}|(textbf}
@ -245,7 +335,7 @@ Mit \texttt{cp} werden Dateien kopiert. Die wichtigsten Optionen im
Zusammenhang mit Skripten sind \texttt{-f} und \texttt{-R}. Ersteres erzwingt Zusammenhang mit Skripten sind \texttt{-f} und \texttt{-R}. Ersteres erzwingt
(force) das Kopieren, falls an der Zielstelle schon Dateien existieren werden (force) das Kopieren, falls an der Zielstelle schon Dateien existieren werden
sie überschrieben. Letzteres ermöglicht ein rekursives Kopieren. sie überschrieben. Letzteres ermöglicht ein rekursives Kopieren.
Verzeichnisse~---~auch leere~---~können nur mit \texttt{-R} kopiert werden. Verzeichnisse~--~auch leere~--~können nur mit \texttt{-R} kopiert werden.
\index{cp=\texttt{cp}|)} \index{cp=\texttt{cp}|)}
@ -295,10 +385,34 @@ der Praxis oft als sehr hilfreich:
\index{echo=\texttt{echo}|)} \index{echo=\texttt{echo}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{eval}\label{eval}\index{eval=\texttt{eval}|(textbf}
TODO!!! eval
\index{eval=\texttt{eval}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{expr}\label{expr}\index{expr=\texttt{expr}|(textbf} \subsection{expr}\label{expr}\index{expr=\texttt{expr}|(textbf}
TODO!!! expr Mit dem Kommando \texttt{expr} verfügt die Shell praktisch über einen
Taschenrechner für einfache Berechnungen. Für komplexe Aufgaben bietet sich das
Tool \texttt{bc} an, näheres dazu steht in Abschnitt \ref{bc}.
Genau genommen kann man mit \texttt{expr} nicht nur Berechnungen
durch\-füh\-ren, sondern ganz allgemein `Ausdrücke evaluieren'. Damit ist
gemeint, daß es zum Beispiel auch Operatoren für Pattern-Matching gibt. Die
wichtigsten Operatoren lauten wie folgt:
\LTXtable{\textwidth}{tab_kommandos_expr_parameter.tex}
Bei einigen Sonderzeichen ist deren Bedeutung in der Shell zu berücksichtigen,
sie sind also durch Anführungszeichen oder Backslashes zu quoten:
\texttt{i=`expr \$i \textbackslash{}* 3`}.
Eine andere Möglichkeit für einfache Rechnungen besteht in der sogenannten
Arithmetik-Expansion (Siehe \ref{arithmetikexpansion}).
\index{expr=\texttt{expr}|)} \index{expr=\texttt{expr}|)}
@ -317,9 +431,9 @@ Siehe auch: Abschnitt \ref{beispiele_suchen_dateien}.
\subsection{grep}\label{grep}\index{grep=\texttt{grep}|(textbf} \subsection{grep}\label{grep}\index{grep=\texttt{grep}|(textbf}
Das Tool \texttt{grep} stammt aus dem Standard-Repertoire eines jeden Das Tool \texttt{grep} stammt aus dem Standard-Repertoire eines jeden
Sys\-tem\-ad\-mi\-ni\-stra\-tors. Mit seiner Hilfe kann in einer oder mehreren Dateien, Sys\-tem\-ad\-mi\-ni\-stra\-tors. Mit seiner Hilfe kann in einer oder mehreren
oder eben auch in einem Datenstrom nach dem Auftreten bestimmter regulärer Dateien, oder eben auch in einem Datenstrom nach dem Auftreten bestimmter
Ausdrücke (siehe \ref{mustererkennung}) gesucht werden. regulärer Ausdrücke (siehe \ref{mustererkennung}) gesucht werden.
Die folgende Tabelle stellt einige der vielen Parameter vor: Die folgende Tabelle stellt einige der vielen Parameter vor:
@ -354,15 +468,62 @@ die ganze Wahrheit.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{killall}\label{killall}\index{killall=\texttt{killall}|(textbf} \subsection{killall}\label{killall}\index{killall=\texttt{killall}|(textbf}
TODO!!! killall Im Abschnitt über \texttt{kill} (\ref{kill}) wird beschrieben, wie man ein
Signal an einen Prozeß schickt, dessen ID bekannt ist. Kennt man die ID nicht,
oder will man das Signal an mehrere Prozesse schicken, kann dieses Kommando
eine große Hilfe darstellen.
Mit dem Parameter \texttt{-i} wird vor jedem Signal interaktiv gefragt, ob es
geschickt werden soll. Mit \texttt{-v} wird angegeben, ob die Signale
erfolgreich versandt wurden, \texttt{-q} hingegen unterdrückt die Ausgaben.
Da ein Prozeß nach einem Signal nicht notwendigerweise sofort stirbt, gibt es
eine Option \texttt{-w}. Diese Veranlaßt \texttt{killall} zu warten, bis alle
Empfänger tot sind. Dieser Parameter ist allerdings mit Vorsicht zu genießen:
Wenn der Prozeß sich weigert zu sterben, wartet \texttt{killall} ewig.
Eine ähnliche Funktionalität bietet auch das Kommando \texttt{pkill} (Abschnitt
\ref{pkill}), \texttt{killall} hat aber den Vorteil daß es auf mehr Systemen
zur Verfügung steht.
\index{killall=\texttt{killall}|)} \index{killall=\texttt{killall}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{ls}\label{ls}\index{ls=\texttt{ls}|(textbf}
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
stehen, hier wird der Dateityp angegeben, also ob es sich um eine einfache
Datei (-), ein Verzeichnis (d), einen Link (l) oder ähnliches\footnote{Siehe
Man-Page} handelt. An Stelle der rwx-Blöcke können auch Striche stehen, die
stehen für nicht gesetzte Attribute.
TODO!!! ls
\index{ls=\texttt{ls}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{mkdir}\label{mkdir}\index{mkdir=\texttt{mkdir}|(textbf}
Mit diesem Kommando werden Verzeichnisse angelegt. Dabei kann mit \texttt{-m}
angegeben werden, welche Berechtigungen das Verzeichnis bekommen soll. Mit
\texttt{-p} werden bei Bedarf auch Parent-Verzeichnisse angelegt, es entsteht
also ein kompletter Pfad.
Entfernen lassen sich Verzeichnisse mit \texttt{rmdir} (Abschnitt \ref{rmdir}).
\index{mkdir=\texttt{mkdir}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{mv}\label{mv}\index{mv=\texttt{mv}|(textbf} \subsection{mv}\label{mv}\index{mv=\texttt{mv}|(textbf}
TODO!!! mv Dateien und Verzeichnisse können mit dem Kommando \texttt{mv} verschoben
werden. Falls am Ziel schon Dateien existieren erzwingt der Parameter
\texttt{-f} die Aktion, die alten Dateien werden überschrieben. Mit \texttt{-i}
wird der Vorgang interaktiv, vor jeder Dateibewegung wird nachgefragt.
\index{mv=\texttt{mv}|)} \index{mv=\texttt{mv}|)}
@ -370,7 +531,24 @@ TODO!!! mv
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf} \subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf}
TODO!!! pgrep Eine häufig wiederkehrende Aufgabe ist es, zu sehen ob ein bestimmter Prozeß
existiert oder nicht. Falls das Kommando \texttt{pgrep} zur Verfügung steht,
kannn man auf das Konstrukt mit \texttt{ps} und \texttt{grep} verzichten. Der
folgende Aufruf liefert alle Prozeß-IDs, deren Name httpd enthält, inclusive
des vollen Kommandos:
\texttt{pgrep -lf httpd}
Über weitere Parameter läßt sich genauer spezifizieren, wonach gesucht werden
soll, hier die wichtigsten:
\LTXtable{\textwidth}{tab_kommandos_pgrep_parameter.tex}
Die Ausgabe enthält per Default nur die Prozeß-IDs der Fundstellen. Diese läßt
sich als Parameter für andere Programme benutzen. Das folgende Beispiel liefert
detaillierte Informationen über alle xterm-Prozesse:
\texttt{ps -fp \$(pgrep -d, -x xterm)}
Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}. Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}.
@ -380,7 +558,24 @@ Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{pkill}\label{pkill}\index{pkill=\texttt{pkill}|(textbf} \subsection{pkill}\label{pkill}\index{pkill=\texttt{pkill}|(textbf}
TODO!!! pkill Dieses Kommando ist eng verwandt mit \texttt{pgrep} (Siehe Abschnitt
\ref{pgrep}), es versteht im Wesentlichen die gleichen Parameter. Allerdings
werden die Fundstellen hier nicht ausgegeben. Wie der Name schon andeutet,
werden hiermit Prozesse umgebracht. Da man hier mit einem Kommando unter
Umständen viele Prozesse beendet, sollten \textbf{die verwendeten Parameter
genau unter die Lupe} genommen werden, um `Kollateralschäden' zu vermeiden. :-)
Es besteht auch die Möglichkeit, den Prozessen andere Signale zuzuschicken,
diese Funktion wird im Abschnitt zu \texttt{kill} (\ref{kill}) näher
beschrieben. Das folgende Kommando veranlaßt beispielsweise den Syslog-Daemon,
seine Konfiguration neu einzulesen:
\texttt{pkill -HUP syslogd}
Das Kommando \texttt{killall} (Abschnitt \ref{killall}) bietet eine ähnliche
Funktionalität, allerdings fehlen ihm einige Parameter. Trotzdem sollte im
Zweifel \texttt{killall} benutzt werden, da es auf mehr Systemen zur Verfügung
steht.
\index{pkill=\texttt{pkill}|)} \index{pkill=\texttt{pkill}|)}
@ -429,7 +624,7 @@ 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} 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. Demzufolge kann 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 ein Skript durch ein \texttt{read -n 1} dazu gebracht werden, auf einen
einzelnen Tastendruck~---~nicht zwingend ein Return~---~zu warten. einzelnen Tastendruck~--~nicht zwingend ein Return~--~zu warten.
Mit dem Parameter \texttt{-p} kann man einen Prompt, also eine Mit dem Parameter \texttt{-p} kann man einen Prompt, also eine
Eingabeaufforderung ausgeben lassen. \texttt{read -p \dq{}Gib was ein:\dq~var} Eingabeaufforderung ausgeben lassen. \texttt{read -p \dq{}Gib was ein:\dq~var}
@ -460,11 +655,37 @@ Timeout oder ein EOF auf.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{rm}\label{rm}\index{rm=\texttt{rm}|(textbf} \subsection{rm}\label{rm}\index{rm=\texttt{rm}|(textbf}
TODO!!! rm Mit diesem Kommando können Dateien und Verzeichnisse gelöscht werden. Dabei
kann man vorsichtig vorgehen, indem man mit \texttt{-i} dafür sorgt, daß jeder
Löschvorgang bestätigt werden muß. Oder rabiat, indem man mit \texttt{-f} das
Löschen erzwingt.
Verzeichnisse können mit dem Parameter \texttt{-R} entfernt werden, im
Gegensatz zu \texttt{rmdir} werden dann auch sämtliche enthaltenen Dateien und
Unterverzeichnisse gelöscht.
Die GNU-Version von \texttt{rm} unterstützt zusätzlich den Parameter
\texttt{-v}, mit dem jeder Löschvorgang ausgegeben wird.
\index{rm=\texttt{rm}|)} \index{rm=\texttt{rm}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{rmdir}\label{rmdir}\index{rmdir=\texttt{rmdir}|(textbf}
Mit \texttt{rmdir} werden Verzeichnisse gelöscht. Das funktioniert nur, wenn
sie leer sind. Mit \texttt{-p} kann ein kompletter Verzeichnispfad gelöscht
werden, will sagen: Alle höher liegenden Verzeichnisse im angegebenen Pfad
werden gelöscht. Voraussetzung ist hier natürlich auch, daß die Verzeichnisse
nichts außer dem angegebenen Unterverzeichnis enthalten.
Angelegt werden Verzeichnisse mit \texttt{mkdir} (Abschnitt \ref{mkdir}),
nicht-leere Verzeichnisse können rekursiv mit \texttt{rm -r} (Abschnitt
\ref{rm}) gelöscht werden.
\index{rmdir=\texttt{rmdir}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{script}\label{script}\index{script=\texttt{script}|(textbf} \subsection{script}\label{script}\index{script=\texttt{script}|(textbf}
@ -492,7 +713,22 @@ TODO!!! sed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{seq}\label{seq}\index{seq=\texttt{seq}|(textbf} \subsection{seq}\label{seq}\index{seq=\texttt{seq}|(textbf}
TODO!!! seq Oft wird eine auf- oder absteigende Sequenz aufeinanderfolgender Zahlen
benötigt, beispielsweise um eine Schleife 100 mal zu durchlaufen. Es ist nicht
sehr performant bei jedem Schleifendurchlauf hochzuzählen und dann die
entstandene Zahl mit dem Limit zu vergleichen. Daher nimmt man an der Stelle
\texttt{seq} zur Hilfe.
Die zu zählenden Werte werden durch drei unterschiedliche Arten der
Parametrisierung definiert: Ein Aufruf in der Form \texttt{seq 10} gibt die
Zahlen von 1 bis 10 aus. Mit \texttt{seq 10 20} wird von 10 bis 20 gezählt, und
\texttt{seq 20 -2 10} zählt in zweierschritten rückwärts von 20 nach 10.
Per default kommen die Werte zeilenweise, mit dem Parameter \texttt{-s} kann
aber auch ein anderes Trennzeichen definiert werden. Will man etwas numerieren
und später nach den Zahlen sortieren, ist es sinnvoll wenn `schmalere' Zahlen
mit führenden Nullen aufgefüllt werden. Das erreicht man mit dem Parameter
\texttt{-w}.
\index{seq=\texttt{seq}|)} \index{seq=\texttt{seq}|)}
@ -500,7 +736,16 @@ TODO!!! seq
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{sleep}\label{sleep}\index{sleep=\texttt{sleep}|(textbf} \subsection{sleep}\label{sleep}\index{sleep=\texttt{sleep}|(textbf}
TODO!!! sleep Das Kommando \texttt{sleep} veranlaßt die Shell, für eine angegebene Zeit zu
warten. Die Zeit wird dabei in Sekunden angegeben.
In der GNU-Variante von \texttt{sleep} kann die Einheit der angegebenen
Zeitspanne durch Suffixe definiert werden: \texttt{sleep 10s} schläft zehn
Sekunden, \texttt{sleep 10m} zehn Minuten. Genauso werden Stunden (h) und Tage
(d) definiert.
Außerdem kann die GNU-Variante auch mit nicht-Integer Zeiten arbeiten:
\texttt{sleep 0.5} schläft eine halbe Sekunde.
\index{sleep=\texttt{sleep}|)} \index{sleep=\texttt{sleep}|)}
@ -508,7 +753,34 @@ TODO!!! sleep
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{sort}\label{sort}\index{sort=\texttt{sort}|(textbf} \subsection{sort}\label{sort}\index{sort=\texttt{sort}|(textbf}
TODO!!! sort Mit diesem Befehl wird wie der Name schon andeutet sortiert. Wenn kein
Dateiname als Parameter angegeben wird, liest \texttt{sort} von der
Standard-Eingabe. Geschrieben wird immer auf der Standard-Ausgabe.
Man kann sich vorstellen, daß ein solches Kommando recht flexibel sein muß,
daher stehen eine Menge Parameter zur Verfügung:
\LTXtable{\textwidth}{tab_kommandos_sort_parameter.tex}
Die Sortierung nach der Spalte (mit \texttt{-k}) ist etwas tricky. Die genaue
Syntax wird in der Man-Page mit \texttt{-k POS1[,POS2]} angegeben, das bedeutet
man muß einen Parameter angeben, man kann bei Bedarf einen zweiten angeben.
Bei der Sortierung wird dann der Bereich ab POS1, bzw. der Bereich zwischen
POS1 und POS2 berücksichtigt.
Dabei lautet die Syntax für POS \texttt{F[.C][OPTS]}. Dabei gibt F die
Feldnummer an (siehe Parameter \texttt{-t}). Wenn nicht nach dem Feld an sich
sortiert werden soll, kann C die Position des Zeichens innerhalb des Feldes
angeben. Und als ob das noch nicht kompliziert genug wäre, kann man dem ganzen
Konstrukt noch einen einbuchstabigen Parameter für die Sortier-Option mitgeben.
Wenn das angegebene Feld nicht existiert wird nach der ganzen Zeile sortiert.
OK, Beispiele:
\LTXtable{\textwidth}{tab_kommandos_sort_beispiele.tex}
Weitere Parameter verrät wie immer die Man-Page.
\index{sort=\texttt{sort}|)} \index{sort=\texttt{sort}|)}
@ -530,7 +802,12 @@ sobald sie an die Datei angeh
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{tee}\label{tee}\index{tee=\texttt{tee}|(textbf} \subsection{tee}\label{tee}\index{tee=\texttt{tee}|(textbf}
TODO!!! tee Dies ist praktisch ein T-Stück für Pipes. \texttt{tee} liest von seiner
Standard-Eingabe, und gibt alle Eingaben direkt auf der Standard-Ausgabe wieder
aus. Nebenbei werden die Ausgaben in eine oder mehrere Dateien geschrieben.
Wenn die Ausgabedateien schon existieren, werden sie überschrieben. Dieses
Verhalten kann mit dem Parameter \texttt{-a} geändert werden.
\index{tee=\texttt{tee}|)} \index{tee=\texttt{tee}|)}
@ -558,7 +835,15 @@ Referenzdatei angepa
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{wc}\label{wc}\index{wc=\texttt{wc}|(textbf} \subsection{wc}\label{wc}\index{wc=\texttt{wc}|(textbf}
TODO!!! wc Wie der Name schon suggeriert\footnote{Oder etwa nicht?!? ;-)} kann man mit
diesem Kommando Wörter zählen (word count). Gezählt wird entweder in einer
Datei, oder~--~wenn kein Dateiname angegeben wurde~--~in der Standardeingabe.
Weitaus häufiger wird aber der Parameter \texttt{-l} benutzt, mit dem sich die
Zeilen zählen lassen. Weiterhin kann man Bytes (\texttt{-c}) oder Zeichen
(\texttt{-m}) zählen lassen.
Der Parameter \texttt{-L} gibt die Länge der längsten enthaltenen Zeile aus.
\index{wc=\texttt{wc}|)} \index{wc=\texttt{wc}|)}

View File

@ -1,6 +1,12 @@
% $Id$ % $Id$
\chapter{Wie sieht ein Shell-Skript aus?} \chapter{Wie sieht ein Shell-Skript aus?}
Wie schon erwähnt, kann ein Shell-Skript beinahe alles, was eine `richtige' Programmiersprache auch kann. Bei der Entwicklung sollte man nur bedenken, daß gerade die Ausführung von externen Kommandos --- und das ist eine der Standard-Techniken bei der Shell-Programmierung --- nur sehr langsam vonstatten geht. Für Anwendungen bei denen z. B. viele Rechnungen oder Stringbearbeitungen gemacht werden müssen, sollte man also ggf. die Benutzung einer anderen Sprache, beispielsweise Perl\index{Perl}, in Erwägung ziehen. Wie schon erwähnt, kann ein Shell-Skript beinahe alles, was eine `richtige'
Programmiersprache auch kann. Bei der Entwicklung sollte man nur bedenken, daß
gerade die Ausführung von externen Kommandos~--~und das ist eine der
Standard-Techniken bei der Shell-Programmierung~--~nur sehr langsam vonstatten
geht. Für Anwendungen bei denen z. B. viele Rechnungen oder Stringbearbeitungen
gemacht werden müssen, sollte man also ggf. die Benutzung einer anderen
Sprache, beispielsweise Perl\index{Perl}, in Erwägung ziehen.
In der Shell stehen viele Mechanismen zur Verfü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ügung, die auch aus anderen Sprachen bekannt sind. Um den Umfang dieses Dokuments nicht zu sprengen, werden an dieser Stelle nur die wichtigsten vorgestellt.
@ -51,7 +57,12 @@ Auf den meisten Systemen befindet sich im Pfad der Eintrag \texttt{\~{}/bin} bzw
\subsection{Rückgabewerte}\label{exitcode}\index{Rückgabewert|(textbf}\index{Exit-Code|see{Rückgabewert}}\index{Exit-Status|see{Rückgabewert}} \subsection{Rückgabewerte}\label{exitcode}\index{Rückgabewert|(textbf}\index{Exit-Code|see{Rückgabewert}}\index{Exit-Status|see{Rückgabewert}}
Wenn unter Unix ein Prozeß beendet wird, gibt er einen Rückgabewert (auch Exit-Code oder Exit-Status genannt) an seinen aufrufenden Prozeß zurück. So kann der Mutterprozeß kontrollieren, ob die Ausführung des Tochterprozesses ohne Fehler beendet wurde. In einigen Fällen (z. B. \texttt{grep}\index{grep=\texttt{grep}}) werden unterschiedliche Exit-Codes für unterschiedliche Ereignisse benutzt. Wenn unter Unix ein Prozeß beendet wird, gibt er einen Rückgabewert (auch
Exit-Code oder Exit-Status genannt) an seinen aufrufenden Prozeß zurück. So
kann der Mutterprozeß kontrollieren, ob die Ausführung des Tochterprozesses
ohne Fehler beendet wurde. In einigen Fällen (z. B.
\texttt{grep}\index{grep=\texttt{grep}}) werden unterschiedliche Exit-Codes für
unterschiedliche Ereignisse benutzt.
Dieser Rückgabewert wird bei der interaktiven Benutzung der Shell nur selten Dieser Rückgabewert wird bei der interaktiven Benutzung der Shell nur selten
benutzt, da Fehlermeldungen direkt vom Benutzer abgelesen werden können. Aber benutzt, da Fehlermeldungen direkt vom Benutzer abgelesen werden können. Aber
@ -64,25 +75,67 @@ Beschreibung der Kommandos \texttt{if}\index{if=\texttt{if}} (\ref{if}),
\texttt{until}\index{until=\texttt{until}} (\ref{until}), sowie in dem \texttt{until}\index{until=\texttt{until}} (\ref{until}), sowie in dem
Abschnitt über Befehlsformen (\ref{befehlsformen}). Abschnitt über Befehlsformen (\ref{befehlsformen}).
In der Bourne-Shell wird der Exit-Code des letzten aufgerufenen Programms in der Variable \texttt{\$?}\index{\$?=\texttt{\$?}} abgelegt. Üblicherweise geben Programme den Wert 0 zurück, bei irgendwelchen Problemen einen von 0 verschiedenen Wert. Das wird im folgenden Beispiel deutlich: In der Bourne-Shell wird der Exit-Code des letzten aufgerufenen Programms in
\LTXtable{\textwidth}{tab_beisp_exitcode.tex} der Variable \texttt{\$?}\index{\$?=\texttt{\$?}} abgelegt. Üblicherweise geben
Normalerweise wird man den Exit-Code nicht in dieser Form abfragen. Sinnvoller ist folgendes Beispiel, in dem eine Datei erst gedruckt wird, und dann --- falls der Ausdruck erfolgreich war --- gelöscht wird: Programme den Wert 0 zurück, bei irgendwelchen Problemen einen von 0
\LTXtable{\textwidth}{tab_beisp_exitcode_lpr.tex} verschiedenen Wert. Das wird im folgenden Beispiel deutlich:
Näheres zur Verknüpfung von Aufrufen steht im Kapitel über Befehlsformen (\ref{befehlsformen}). Beispiele zur Benutzung von Rückgabewerten in Schleifen finden sich im Anhang unter \ref{beisp_schleifen_exitcode}.
\LTXtable{\textwidth}{tab_beisp_exitcode.tex}
Normalerweise wird man den Exit-Code nicht in dieser Form abfragen. Sinnvoller
ist folgendes Beispiel, in dem eine Datei erst gedruckt wird, und dann~--~falls
der Ausdruck erfolgreich war ~--~elöscht wird:
\LTXtable{\textwidth}{tab_beisp_exitcode_lpr.tex}
Näheres zur Verknüpfung von Aufrufen steht im Kapitel über Befehlsformen
(\ref{befehlsformen}). Beispiele zur Benutzung von Rückgabewerten in Schleifen
finden sich im Anhang unter \ref{beisp_schleifen_exitcode}.
Auch Shell-Skripte können einen Rückgabewert an aufrufende Prozesse
zurückgeben. Wie das geht, steht in dem Abschnitt zu \texttt{exit}
(\ref{exit}).
Auch Shell-Skripte können einen Rückgabewert an aufrufende Prozesse zurückgeben. Wie das geht, steht in dem Abschnitt zu \texttt{exit} (\ref{exit}).
\index{Rückgabewert|)} \index{Rückgabewert|)}
\section{Variablen}\index{Variablen|(textbf} \section{Variablen}\index{Variablen|(textbf}
In einem Shell-Skript hat man --- genau wie bei der interaktiven Nutzung der Shell --- Möglichkeiten, über Variablen zu verfügen. Anders als in den meisten modernen Programmiersprachen gibt es aber keine Datentypen\index{Datentypen} wie Ganzzahlen, Fließkommazahlen oder Strings\footnote{Bei einigen modernen Shells (\texttt{csh}\index{C-Shell}, \texttt{tcsh}\index{TENEX-C-Shell}, \texttt{ksh}\index{Korn-Shell}, \texttt{bash}\index{Bourne-Again-Shell}, \texttt{zsh}\index{Z-Shell}...) hat man die Möglichkeit, Variablentypen zu vereinbaren. In der Bourne-Shell\index{Bourne-Shell} nicht.}. Alle Variablen werden als String gespeichert, wenn die Variable die Funktion einer Zahl übernehmen soll, dann muß das verarbeitende Programm die Variable entsprechend interpretieren\footnote{Für arithmetische Operationen steht das Programm \texttt{expr}\index{expr=\texttt{expr}} zur Verfügung (siehe Zählschleifen-Beispiel unter \ref{while})}. In einem Shell-Skript hat man~--~genau wie bei der interaktiven Nutzung der
Shell~--~Möglichkeiten, über Variablen zu verfügen. Anders als in den meisten
modernen Programmiersprachen gibt es aber keine Datentypen\index{Datentypen}
wie Ganzzahlen, Fließkommazahlen oder Strings\footnote{Bei einigen modernen
Shells (\texttt{csh}\index{C-Shell}, \texttt{tcsh}\index{TENEX-C-Shell},
\texttt{ksh}\index{Korn-Shell}, \texttt{bash}\index{Bourne-Again-Shell},
\texttt{zsh}\index{Z-Shell}...) hat man die Möglichkeit, Variablentypen zu
vereinbaren. In der Bourne-Shell\index{Bourne-Shell} nicht.}. Alle Variablen
werden als String gespeichert, wenn die Variable die Funktion einer Zahl
übernehmen soll, dann muß das verarbeitende Programm die Variable entsprechend
interpretieren\footnote{Für arithmetische Operationen steht das Programm
\texttt{expr}\index{expr=\texttt{expr}} zur Verfügung (siehe
Zählschleifen-Beispiel unter \ref{while})}.
Man muß bei der Benutzung von Variablen sehr aufpassen, wann die Variable expandiert\footnote{Mit \emph{Expansion}\index{Expansion} ist das Ersetzen des Variablennamens durch den Inhalt gemeint} wird und wann nicht. Grundsätzlich werden Variablen während der Ausführung des Skriptes immer an den Stellen ersetzt, an denen sie stehen. Das passiert in jeder Zeile, unmittelbar bevor sie ausgeführt wird. Es ist also auch möglich, in einer Variable einen Shell-Befehl abzulegen. Im Folgenden kann dann der Variablenname an der Stelle des Befehls stehen. Um die Expansion einer Variable zu verhindern, benutzt man das Quoting\index{Quoting} (siehe unter \ref{quoting}). Man muß bei der Benutzung von Variablen sehr aufpassen, wann die Variable
expandiert\footnote{Mit \emph{Expansion}\index{Expansion} ist das Ersetzen des
Variablennamens durch den Inhalt gemeint} wird und wann nicht. Grundsätzlich
werden Variablen während der Ausführung des Skriptes immer an den Stellen
ersetzt, an denen sie stehen. Das passiert in jeder Zeile, unmittelbar bevor
sie ausgeführt wird. Es ist also auch möglich, in einer Variable einen
Shell-Befehl abzulegen. Im Folgenden kann dann der Variablenname an der Stelle
des Befehls stehen. Um die Expansion einer Variable zu verhindern, benutzt man
das Quoting\index{Quoting} (siehe unter \ref{quoting}).
Wie aus diversen Beispielen hervorgeht, belegt man eine Variable, indem man dem Namen mit dem Gleichheitszeichen einen Wert zuweist. Dabei darf zwischen dem Namen und dem Gleichheitszeichen keine Leerstelle stehen, ansonsten erkennt die Shell den Variablennamen nicht als solchen und versucht, ein gleichnamiges Kommando auszuführen --- was meistens durch eine Fehlermeldung quittiert wird. Wie aus diversen Beispielen hervorgeht, belegt man eine Variable, indem man dem
Namen mit dem Gleichheitszeichen einen Wert zuweist. Dabei darf zwischen dem
Namen und dem Gleichheitszeichen keine Leerstelle stehen, ansonsten erkennt die
Shell den Variablennamen nicht als solchen und versucht, ein gleichnamiges
Kommando auszuführen~--~was meistens durch eine Fehlermeldung quittiert wird.
Wenn man auf den Inhalt einer Variablen zugreifen möchte, leitet man den
Variablennamen durch ein \texttt{\$}-Zeichen ein. Alles was mit einem
\texttt{\$} anfängt wird von der Shell als Variable angesehen und entsprechend
behandelt (expandiert).
Wenn man auf den Inhalt einer Variablen zugreifen möchte, leitet man den Variablennamen durch ein \texttt{\$}-Zeichen ein. Alles was mit einem \texttt{\$} anfängt wird von der Shell als Variable angesehen und entsprechend behandelt (expandiert).
\index{Variablen|)} \index{Variablen|)}
@ -271,7 +324,11 @@ Bei der Shell-Programmierung verf
\subsection{Kommentare\label{kommentare}\index{Kommentar|(textbf} (\texttt{\#})}\index{\#=\texttt{\#}|see{Kommentar}} \subsection{Kommentare\label{kommentare}\index{Kommentar|(textbf} (\texttt{\#})}\index{\#=\texttt{\#}|see{Kommentar}}
Kommentare in der Shell beginnen immer mit dem Nummern-Zeichen (\verb\#\). Dabei spielt es keine Rolle, ob das Zeichen am Anfang der Zeile steht, oder hinter irgendwelchen Befehlen. Alles von diesem Zeichen bis zum Zeilenende wird nicht beachtet (bis auf eine Ausnahme --- siehe unter \ref{auswahl_der_shell}). Kommentare in der Shell beginnen immer mit dem Nummern-Zeichen (\verb\#\).
Dabei spielt es keine Rolle, ob das Zeichen am Anfang der Zeile steht, oder
hinter irgendwelchen Befehlen. Alles von diesem Zeichen bis zum Zeilenende wird
nicht beachtet (bis auf eine Ausnahme~--~siehe unter \ref{auswahl_der_shell}).
\index{Kommentar|)} \index{Kommentar|)}
@ -330,9 +387,21 @@ durch die Eingabe von \verb\count\.\nopagebreak
\subsection{Bedingungen (\texttt{[ ]})}\label{bedingungen}\index{Bedingungen|see{test}}\index{[ ]=\texttt{[ ]}|see{test}}\index{test=\texttt{test}|(textbf} \subsection{Bedingungen (\texttt{[ ]})}\label{bedingungen}\index{Bedingungen|see{test}}\index{[ ]=\texttt{[ ]}|see{test}}\index{test=\texttt{test}|(textbf}
Da die Standard-Shell keine arithmetischen oder logischen Ausdrücke auswerten kann\footnote{\texttt{if} und Konsorten prüfen nur den Rückgabewert\index{Rückgabewert} eines aufgerufenen Programmes --- 0 bedeutet `true', alles andere bedeutet `false', siehe auch \ref{exitcode}.}, muß dazu ein externes Programm benutzt werden. Dieses Programm heißt \verb\test\\index{test=\texttt{test}}. Üblicherweise besteht auf allen Systemen auch noch ein Link namens \verb\[\ auf dieses Programm. Dieser Link ist fast absolut gleichwertig zu benutzen (in dieser Form wird allerdings eine abschließende Klammer nach der Bedingung erwartet). Dementsprechend ist es auch zwingend erforderlich, nach der Klammer ein Leerzeichen zu schreiben. Das dient dazu, Bedingungen in \verb\if\-Abfragen u. ä. lesbarer zu machen. Da die Standard-Shell keine arithmetischen oder logischen Ausdrücke auswerten
kann\footnote{\texttt{if} und Konsorten prüfen nur den
Rückgabewert\index{Rückgabewert} eines aufgerufenen Programmes~--~0 bedeutet
`true', alles andere bedeutet `false', siehe auch \ref{exitcode}.}, muß dazu
ein externes Programm benutzt werden. Dieses Programm heißt
\verb\test\\index{test=\texttt{test}}. Üblicherweise besteht auf allen Systemen
auch noch ein Link namens \verb\[\ auf dieses Programm. Dieser Link ist fast
absolut gleichwertig zu benutzen (in dieser Form wird allerdings eine
abschließende Klammer nach der Bedingung erwartet). Dementsprechend ist es auch
zwingend erforderlich, nach der Klammer ein Leerzeichen zu schreiben. Das dient
dazu, Bedingungen in \verb\if\-Abfragen u. ä. lesbarer zu machen.
Das \verb\test\-Programm bietet sehr umfangreiche Optionen an. Dazu gehören Dateitests und Vergleiche von Zeichenfolgen oder ganzen Zahlen. Diese Bedingungen können auch durch Verknüpfungen kombiniert werden. Das \verb\test\-Programm bietet sehr umfangreiche Optionen an. Dazu gehören
Dateitests und Vergleiche von Zeichenfolgen oder ganzen Zahlen. Diese
Bedingungen können auch durch Verknüpfungen kombiniert werden.
\medskip\medskip\emph{Dateitests:}\index{Dateitests}\nopagebreak \medskip\medskip\emph{Dateitests:}\index{Dateitests}\nopagebreak
\LTXtable{\textwidth}{tab_bedingungen_dateitests.tex} \LTXtable{\textwidth}{tab_bedingungen_dateitests.tex}
@ -387,12 +456,28 @@ In den Mustern sind die gleichen Meta-Zeichen\index{Meta-Zeichen} erlaubt wie be
\subsection{for\ldots}\label{for}\index{for=\texttt{for}|(textbf}\index{Schleife>for-=\texttt{for}-|see{for}}\index{in=\texttt{in}|see{for}}\index{in=\texttt{in}|see{case}}\index{do=\texttt{do}|see{for}}\index{do=\texttt{do}|see{while}}\index{do=\texttt{do}|see{until}}\index{do=\texttt{done}|see{for}}\index{do=\texttt{done}|see{while}}\index{do=\texttt{done}|see{until}} \subsection{for\ldots}\label{for}\index{for=\texttt{for}|(textbf}\index{Schleife>for-=\texttt{for}-|see{for}}\index{in=\texttt{in}|see{for}}\index{in=\texttt{in}|see{case}}\index{do=\texttt{do}|see{for}}\index{do=\texttt{do}|see{while}}\index{do=\texttt{do}|see{until}}\index{do=\texttt{done}|see{for}}\index{do=\texttt{done}|see{while}}\index{do=\texttt{done}|see{until}}
Dieses Konstrukt ähnelt nur auf den ersten Blick seinen Pendants aus anderen Programmiersprachen. In anderen Sprachen wird die \texttt{for}-Schleife meistens dazu benutzt, eine Zählvariable über einen bestimmten Wertebereich iterieren zu lassen (\texttt{for i = 1 to 100\ldots next}). In der Shell dagegen wird die Laufvariable nicht mit aufeinanderfolgenden Zahlen belegt, sondern mit einzelnen Werten aus einer anzugebenden Liste\footnote{Wenn man trotzdem eine Laufvariable\index{Laufvariable} braucht, muß man dazu die \texttt{while}-Schleife\index{while=\texttt{while}} `mißbrauchen' (siehe unter \ref{while}).}. Dieses Konstrukt ähnelt nur auf den ersten Blick seinen Pendants aus anderen
Programmiersprachen. In anderen Sprachen wird die \texttt{for}-Schleife
meistens dazu benutzt, eine Zählvariable über einen bestimmten Wertebereich
iterieren zu lassen (\texttt{for i = 1 to 100\ldots next}). In der Shell
dagegen wird die Laufvariable nicht mit aufeinanderfolgenden Zahlen belegt,
sondern mit einzelnen Werten aus einer anzugebenden Liste\footnote{Wenn man
trotzdem eine Laufvariable\index{Laufvariable} braucht, muß man dazu die
\texttt{while}-Schleife\index{while=\texttt{while}} `mißbrauchen' (siehe unter
\ref{while}).}.
Die Syntax der \texttt{for}-Schleife lautet wie folgt:\nopagebreak Die Syntax der \texttt{for}-Schleife lautet wie folgt:\nopagebreak
\LTXtable{\textwidth}{tab_for.tex} \LTXtable{\textwidth}{tab_for.tex}
Die \textsl{Befehle} werden ausgeführt, wobei der Variablen \textsl{x} nacheinander die Werte aus der \textsl{Liste} zugewiesen werden. Wie man sieht ist die Angabe der \textsl{Liste} optional, wenn sie nicht angegeben wird, nimmt \textsl{x} der Reihe nach alle Werte aus \texttt{\$@} (in dieser vordefinierten Variablen liegen die Aufrufparameter --- siehe unter \ref{vordefinierte_variablen}) an. Wenn die Ausführung eines Schleifendurchlaufs bzw der ganzen Schleife abgebrochen werden soll, müssen die Kommandos \texttt{continue}\index{continue=\texttt{continue}} (\ref{continue}) bzw. \texttt{break}\index{break=\texttt{break}} (\ref{break}) benutzt werden. Die \textsl{Befehle} werden ausgeführt, wobei der Variablen \textsl{x}
nacheinander die Werte aus der \textsl{Liste} zugewiesen werden. Wie man sieht
ist die Angabe der \textsl{Liste} optional, wenn sie nicht angegeben wird,
nimmt \textsl{x} der Reihe nach alle Werte aus \texttt{\$@} (in dieser
vordefinierten Variablen liegen die Aufrufparameter~--~siehe unter
\ref{vordefinierte_variablen}) an. Wenn die Ausführung eines
Schleifendurchlaufs bzw der ganzen Schleife abgebrochen werden soll, müssen die
Kommandos \texttt{continue}\index{continue=\texttt{continue}} (\ref{continue})
bzw. \texttt{break}\index{break=\texttt{break}} (\ref{break}) benutzt werden.
\medskip\emph{Beispiele:}\nopagebreak \medskip\emph{Beispiele:}\nopagebreak
\LTXtable{\textwidth}{tab_beisp_for.tex} \LTXtable{\textwidth}{tab_beisp_for.tex}
@ -441,7 +526,7 @@ Die Syntax der \texttt{until}-Schleife lautet wie folgt:\nopagebreak
Die \textsl{Bedingung} wird dabei üblicherweise, genau wie bei der Die \textsl{Bedingung} wird dabei üblicherweise, genau wie bei der
\texttt{if}-Anweisung, mit mit dem Befehl \texttt{if}-Anweisung, mit mit dem Befehl
\texttt{test}\index{test=\texttt{test}} (siehe unter \ref{bedingungen}) \texttt{test}\index{test=\texttt{test}} (siehe unter \ref{bedingungen})
formuliert. Wenn die Ausführung eines Schleifendurchlaufs bzw der ganzen formuliert. Wenn die Aus\-füh\-rung eines Schleifendurchlaufs bzw der ganzen
Schleife abgebrochen werden soll, müssen die Kommandos Schleife abgebrochen werden soll, müssen die Kommandos
\texttt{continue}\index{continue=\texttt{continue}} (\ref{continue}) bzw. \texttt{continue}\index{continue=\texttt{continue}} (\ref{continue}) bzw.
\texttt{break}\index{break=\texttt{break}} (\ref{break}) benutzt werden. \texttt{break}\index{break=\texttt{break}} (\ref{break}) benutzt werden.