From 14dec499673c2c9b10186d3ccb529aec880aefdd Mon Sep 17 00:00:00 2001 From: rschaten Date: Fri, 12 Nov 2004 12:07:32 +0000 Subject: [PATCH] Viele ueberarbeitungen --- quellen.tex | 4 +- schmutzige_tricks.tex | 2 + shell.tex | 5 +- tab_beisp_metazeichen.tex | 2 +- tab_kommandos_chmod_beispiele.tex | 16 ++ tab_kommandos_cut_beispiele.tex | 16 ++ tab_kommandos_expr_parameter.tex | 29 +++ tab_kommandos_pgrep_parameter.tex | 15 ++ tab_kommandos_sort_beispiele.tex | 16 ++ tab_kommandos_sort_parameter.tex | 20 ++ todo.tex | 29 +++ werkzeugkasten.tex | 345 ++++++++++++++++++++++++++--- wie_sieht_ein_shell_skript_aus.tex | 121 ++++++++-- 13 files changed, 568 insertions(+), 52 deletions(-) create mode 100644 tab_kommandos_chmod_beispiele.tex create mode 100644 tab_kommandos_cut_beispiele.tex create mode 100644 tab_kommandos_expr_parameter.tex create mode 100644 tab_kommandos_pgrep_parameter.tex create mode 100644 tab_kommandos_sort_beispiele.tex create mode 100644 tab_kommandos_sort_parameter.tex create mode 100644 todo.tex diff --git a/quellen.tex b/quellen.tex index 8b01abc..4b220f6 100644 --- a/quellen.tex +++ b/quellen.tex @@ -1,5 +1,5 @@ % $Id$ -\chapter{Quellen} +\chapter{Quellen}\label{quellen} \begin{itemize} \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...) +\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 kann ich nur jedem empfehlen - es ist spannender als es sich anhört...). \end{itemize} diff --git a/schmutzige_tricks.tex b/schmutzige_tricks.tex index ba15891..24e635e 100644 --- a/schmutzige_tricks.tex +++ b/schmutzige_tricks.tex @@ -26,6 +26,8 @@ haben. TODO!!! tar-Brücke +%ssh 192.168.2.1 tar clf - / | (cd /mnt; tar xf - ) + \section{Binaries inside} diff --git a/shell.tex b/shell.tex index d67cfbf..d8b9d78 100644 --- a/shell.tex +++ b/shell.tex @@ -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. \textbf{Aber ich übernehme keine Garantie für die Korrektheit der hier dargestellten Dinge.} Mit der Formulierung \textsl{`daraus vielleicht einen -Nutzen ziehen können'} meine ich nicht, daß dieses Dokument~---~oder Teile -daraus~---~verkauft werden darf. \textbf{Dieses Dokument darf nur kostenlos +Nutzen ziehen können'} meine ich nicht, daß dieses Dokument~--~oder Teile +daraus~--~verkauft werden darf. \textbf{Dieses Dokument darf nur kostenlos weitergegeben werden.}\bigskip Ich danke folgenden Personen, die mir bei der Durchsicht behilflich waren und @@ -157,6 +157,7 @@ R \include{beispiele} \include{schmutzige_tricks} \include{quellen} +\include{todo} \printindex % Index einfügen diff --git a/tab_beisp_metazeichen.tex b/tab_beisp_metazeichen.tex index 038ddb2..6eafa4f 100644 --- a/tab_beisp_metazeichen.tex +++ b/tab_beisp_metazeichen.tex @@ -10,5 +10,5 @@ \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 [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} diff --git a/tab_kommandos_chmod_beispiele.tex b/tab_kommandos_chmod_beispiele.tex new file mode 100644 index 0000000..38a6ff7 --- /dev/null +++ b/tab_kommandos_chmod_beispiele.tex @@ -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} diff --git a/tab_kommandos_cut_beispiele.tex b/tab_kommandos_cut_beispiele.tex new file mode 100644 index 0000000..8f7d18b --- /dev/null +++ b/tab_kommandos_cut_beispiele.tex @@ -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} diff --git a/tab_kommandos_expr_parameter.tex b/tab_kommandos_expr_parameter.tex new file mode 100644 index 0000000..e72ec9e --- /dev/null +++ b/tab_kommandos_expr_parameter.tex @@ -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} diff --git a/tab_kommandos_pgrep_parameter.tex b/tab_kommandos_pgrep_parameter.tex new file mode 100644 index 0000000..bf205a7 --- /dev/null +++ b/tab_kommandos_pgrep_parameter.tex @@ -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} diff --git a/tab_kommandos_sort_beispiele.tex b/tab_kommandos_sort_beispiele.tex new file mode 100644 index 0000000..9078ccc --- /dev/null +++ b/tab_kommandos_sort_beispiele.tex @@ -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} diff --git a/tab_kommandos_sort_parameter.tex b/tab_kommandos_sort_parameter.tex new file mode 100644 index 0000000..e6596dc --- /dev/null +++ b/tab_kommandos_sort_parameter.tex @@ -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} diff --git a/todo.tex b/todo.tex new file mode 100644 index 0000000..610a5d2 --- /dev/null +++ b/todo.tex @@ -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} diff --git a/werkzeugkasten.tex b/werkzeugkasten.tex index 09200f2..99954a6 100644 --- a/werkzeugkasten.tex +++ b/werkzeugkasten.tex @@ -24,9 +24,10 @@ Shell-Programmierer nicht sinnvoll um den Einsatz dieser Programme herum. In diesem Abschnitt sollen einige dieser Programme mit typischen Einsatzmöglichkeiten vorgestellt werden. Eine vollständige Beschreibung wäre (wenn überhaupt möglich) viel zu lang, um an dieser Stelle untergebracht zu -werden. Für ausführlichere Beschreibungen empfiehlt sich das Studium der -Man-Pages oder der Kauf eines entsprechenden Buches. Am besten macht man -natürlich beides. ;-) +werden. \textbf{Dies ist also nur ein grober Überblick, nicht mal annähernd +eine vollständige Referenz!} Für ausführlichere Beschreibungen empfiehlt sich +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 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} \item \texttt{basename} (\ref{basename}): Den Namen einer Datei (ohne Pfad) ausgeben \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{find} (\ref{find}): Dateien suchen +\item \texttt{mkdir} (\ref{mkdir}): Verzeichnisse anlegen \item \texttt{mv} (\ref{mv}): Dateien verschieben \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{xargs} (\ref{xargs}): Ausgaben eines Kommandos als Parameter eines anderen Kommandos benutzen \end{itemize} @@ -148,6 +154,13 @@ Verf \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} @@ -170,18 +183,14 @@ der eigentlichen Datei wird zur %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{bc}\label{bc}\index{bc=\texttt{bc}|(textbf} -Mit dem Kommando \texttt{bc} verfügt die Shell praktisch über einen -Taschenrechner. Die Man-Page verrät, daß es sich hierbei um ein erstaunlich -komplexes Programm handelt, in der Praxis findet man allerdings meistens -einfache Anwendungen wie das inkrementieren einer Laufvariable (\texttt{i=`bc -\$i + 1`}). +Bei \texttt{bc} handelt es sich, ähnlich wie bei \texttt{expr} um einen +Taschenrechner. Allerdings verfügt dieses Kommando um eine vergleichsweise +komplexe Syntax, die auch Berechnungen mit hoher Genauigkeit zulassen. -Bei Multiplikationen ist darauf zu achten, daß der Stern in der Shell eine -Sonderbedeutung hat, er muß also gequoted werden: \texttt{i=`bc \$i -\textbackslash{}* 3`}. - -Eine andere Möglichkeit für einfache Rechnungen besteht in der sogenannten -Arithmetik-Expansion (Siehe \ref{arithmetikexpansion}). +Für einfache Grundrechenaufgaben wie das Inkrementieren von Variablen sollte +man entweder die eingebaute Arithmetik-Expansion der Shell (Siehe +\ref{arithmetikexpansion}) oder das wesentlich ressourcenfreundlichere +\texttt{expr} (Siehe \ref{expr}) benutzen. \index{bc=\texttt{bc}|)} @@ -211,6 +220,87 @@ werden. \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} @@ -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 (force) das Kopieren, falls an der Zielstelle schon Dateien existieren werden 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}|)} @@ -295,10 +385,34 @@ der Praxis oft als sehr hilfreich: \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} -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}|)} @@ -317,9 +431,9 @@ Siehe auch: Abschnitt \ref{beispiele_suchen_dateien}. \subsection{grep}\label{grep}\index{grep=\texttt{grep}|(textbf} 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, -oder eben auch in einem Datenstrom nach dem Auftreten bestimmter regulärer -Ausdrücke (siehe \ref{mustererkennung}) gesucht werden. +Sys\-tem\-ad\-mi\-ni\-stra\-tors. Mit seiner Hilfe kann in einer oder mehreren +Dateien, oder eben auch in einem Datenstrom nach dem Auftreten bestimmter +regulärer Ausdrücke (siehe \ref{mustererkennung}) gesucht werden. 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} -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}|)} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\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} -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}|)} @@ -370,7 +531,24 @@ TODO!!! mv %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}. @@ -380,7 +558,24 @@ Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}|)} @@ -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} liest die ersten fünf Zeichen in die Variable \texttt{var} ein. Demzufolge kann ein Skript durch ein \texttt{read -n 1} dazu gebracht werden, auf einen -einzelnen Tastendruck~---~nicht zwingend ein Return~---~zu warten. +einzelnen Tastendruck~--~nicht zwingend ein Return~--~zu warten. Mit dem Parameter \texttt{-p} kann man einen Prompt, also eine Eingabeaufforderung ausgeben lassen. \texttt{read -p \dq{}Gib was ein:\dq~var} @@ -460,11 +655,37 @@ Timeout oder ein EOF auf. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}|)} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\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} @@ -492,7 +713,22 @@ TODO!!! sed %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}|)} @@ -500,7 +736,16 @@ TODO!!! seq %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}|)} @@ -508,7 +753,34 @@ TODO!!! sleep %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}|)} @@ -530,7 +802,12 @@ sobald sie an die Datei angeh %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}|)} @@ -558,7 +835,15 @@ Referenzdatei angepa %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}|)} diff --git a/wie_sieht_ein_shell_skript_aus.tex b/wie_sieht_ein_shell_skript_aus.tex index a2a0bda..df6dad5 100644 --- a/wie_sieht_ein_shell_skript_aus.tex +++ b/wie_sieht_ein_shell_skript_aus.tex @@ -1,6 +1,12 @@ % $Id$ \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. @@ -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}} -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 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 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: -\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 --- gelö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}. +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: + +\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|)} \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|)} @@ -271,7 +324,11 @@ Bei der Shell-Programmierung verf \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|)} @@ -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} -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 \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}} -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 \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 \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 \texttt{if}-Anweisung, mit mit dem Befehl \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 \texttt{continue}\index{continue=\texttt{continue}} (\ref{continue}) bzw. \texttt{break}\index{break=\texttt{break}} (\ref{break}) benutzt werden.