Umformatiert

This commit is contained in:
rschaten
2004-12-10 14:38:03 +00:00
parent 15af99f29e
commit 464f0bcf77
6 changed files with 417 additions and 333 deletions

View File

@ -1,5 +1,6 @@
% $Id$
\chapter{Werkzeugkasten}\label{werkzeugkasten}
Durch die gezeigten Steuerungsm<73>glichkeiten stehen dem Shell-Pro\-grammie\-rer
M<EFBFBD>g\-lich\-kei\-ten offen, fast alle g<>ngigen Algorithmen zu implementieren. Es
ist tats<74>chlich in der Shell m<>glich, Sortier- oder Suchfunktionen zu
@ -43,6 +44,14 @@ typische Aufgaben beschrieben. Diese enthalten `Links' zu den in Frage
kommenden Werkzeugen. Danach gibt es eine alphabetische Aufz<66>hlung der
wichtigsten Kommandos.
Das GNU-Projekt\marginpar{GNU!} hat vielen Kommandos n<>tzliche Parameter
zugef<EFBFBD>gt, einige der hier beschriebenen Tools stehen ausschlie<69>lich auf
GNU-Systemen zur Verf<72>gung. Da diese Optionen nicht auf allen Unix-Systemen zur
Verf<EFBFBD>gung stehen, werden die betroffenen Stellen wie dieser Absatz am Rand mit
`GNU!' markiert. Wenn diese Kommandos und Optionen benutzt werden mu<6D> also das
Zielsystem ber<65>cksichtigt werden, im Zweifelsfall sollten die Skripte
ausf<EFBFBD>hrlich getestet werden.
\section{N<EFBFBD>gel...}\label{naegel}
\subsection{Ein- und Ausgabe}\label{ein_und_ausgabe}
@ -66,6 +75,7 @@ Dateien auf der Festplatte.
\item \texttt{echo} (\ref{echo}): Daten ausgeben
\item \texttt{grep} (\ref{grep}): In Dateien suchen
\item \texttt{head} (\ref{head}): Dateianfang ausgeben
\item \texttt{logger} (\ref{logger}): Text ins System-Log schreiben
\item \texttt{printf} (\ref{printf}): Formatierte Datenausgabe
\item \texttt{read} (\ref{read}): Zeilen einlesen
\item \texttt{tail} (\ref{tail}): Dateiende ausgeben
@ -215,8 +225,7 @@ Eine weitere Gemeinsamkeit ist die Art der Ein- und Ausgabe. Wenn eine
Eingabedatei angegeben wird, wird diese verarbeitet. Ansonsten wird die
Standard-Eingabe gelesen. Ausgaben erfolgen immer auf der Standard-Ausgabe.
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
# Aufruf als Filter:
kommando1 | awk '{ print $1; print $2 }' | kommando2
@ -233,15 +242,14 @@ awk '
# Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert und
# <20>ber den Parameter -f eingebunden werden:
awk -f script.awk datei.txt
\end{listing}
\normalsize
\end{lstlisting}
Neben dem Parameter \texttt{-f} zum Einlesen der Programmdatei gibt es noch den
Parameter \texttt{-F} mit dem der Feld-Trenner angegeben werden kann. Die
folgende Zeile gibt beispielsweise alle Benutzernamen und deren User-IDs aus
der Doppelpunktseparierten Datei \texttt{/etc/passwd} aus:
\texttt{awk -F: '\{ print \$1\dq hat ID \dq\$3 \}' /etc/passwd}
\lstinline|awk -F: '{ print $1" hat ID "$3 }' /etc/passwd|
\subsubsection{Muster und Prozeduren}
@ -291,8 +299,7 @@ mit den TeX-Dateien weiter unten.
Hier ein paar Einfache Beispiele f<>r Blocks aus Mustern und Prozeduren:
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
# Das erste Feld jeder Zeile ausgeben:
{ print $1 }
@ -335,8 +342,7 @@ END { summe /= 1024; print "Die Gr
# ausgeben, verarbeitet die Ausgabe von 'df':
BEGIN { OFS="|" }
/^\/dev\// { print $1,$5 }
\end{listing}
\normalsize
\end{lstlisting}
\index{awk=\texttt{awk}|)}
@ -377,17 +383,17 @@ an vielen, teilweise sehr unterschiedlich gelagerten Aufgaben wertvolle
Dienste.
Durch Umlenklung der Ausgabe k<>nnen Dateien erzeugt und erweitert werden. So
k<EFBFBD>nnen mehrere Dateien per \texttt{cat datei1.txt datei2.txt > datei.txt}
k<EFBFBD>nnen mehrere Dateien per \lstinline|cat datei1.txt datei2.txt > datei.txt|
verkettet werden.
Au<EFBFBD>erdem kann man mit einem Aufruf in der Art \texttt{cat datei.txt | kommando}
Daten an ein Programm <20>bergeben, das nur von der Standardeingabe lesen kann
(Filter).
Au<EFBFBD>erdem kann man mit einem Aufruf in der Art
\lstinline|cat datei.txt | kommando| Daten an ein Programm <20>bergeben, das nur
von der Standardeingabe lesen kann (Filter).
\texttt{cat} verf<72>gt <20>ber eine Reihe von Parametern, um die Ausgabe zu
formatieren, so k<>nnen mit \texttt{-n} bzw. \texttt{-b} die Zeilen numeriert
werden, oder mit \texttt{-s} mehrere Zeilen zu einer einzigen zusammengefa<66>t
werden.
GNU-\texttt{cat}\marginpar{GNU!} verf<72>gt <20>ber eine Reihe von Parametern, um die
Ausgabe zu formatieren, so k<>nnen mit \texttt{-n} bzw. \texttt{-b} die Zeilen
numeriert werden, oder mit \texttt{-s} mehrere Zeilen zu einer einzigen
zusammengefa<EFBFBD>t werden.
\index{cat=\texttt{cat}|)}
@ -458,8 +464,9 @@ Zur Verdeutlichung ein paar Beispiele, wo es m
\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<73>hrbar sein soll oder nicht.
Am wichtigsten sind also die Aufrufe \lstinline|chmod 644 datei| und
\lstinline|chmod 755 datei|, je nachdem ob die Datei ausf<73>hrbar sein soll oder
nicht.
\index{chmod=\texttt{chmod}|)}
@ -482,9 +489,9 @@ Will man lediglich die Gruppen-ID
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{chpasswd}\index{chpasswd=\texttt{chpasswd}|(textbf}
\subsection{chpasswd}\index{chpasswd=\texttt{chpasswd}|(textbf}\marginpar{GNU!}
Mit diesem Kommando bietet sich dem Administrator des Systems die
Mit diesem GNU-Kommando bietet sich dem Administrator des Systems die
M<EFBFBD>g\-lich\-keit, scriptgesteuert die Pa<50>w<EFBFBD>rter f<>r neue Benutzer zu vergeben.
Manuell <20>ndert man ein Pa<50>wort mit dem Kommando
\texttt{passwd}\index{passwd=\texttt{passwd}}, allerdings l<>scht (flusht)
@ -511,7 +518,23 @@ diese Datei nicht allgemein lesbar ist.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{cmp}\label{cmp}\index{cmp=\texttt{cmp}|(textbf}
TODO!!! cmp GNU?
Mit \texttt{cmp} werden zwei Dateien verglichen. Wenn die beiden Dateien
identisch sind gibt es keine Ausgabe, ansonsten wird die Position des ersten
Unterschiedes ausgegeben.
Einer der beiden anzugebenden Dateinamen kann auch durch \texttt{-} ersetzt
werden, dann wird die Standard-Eingabe mit der anderen angegebenen Datei
verglichen.
Mit dem Parameter \texttt{-l} werden alle abweichenden Bytes aufgelistet,
jeweils mit der Position (dezimal) und den beiden Bytes (oktal).
Durch \texttt{-s} l<><6C>t sich die Ausgabe von Unterschieden unterdr<64>cken, der
Exit-Status gibt weiterhin das Ergebnis an.
In der GNU-Version\marginpar{GNU!} gibt es auch Parameter, mit denen Bereiche
der Datei vom Vergleich ausgeschlossen werden k<>nnen (\texttt{-i}), oder mit
denen nur die ersten n Bytes der Dateien verglichen werden (\texttt{-n}).
\index{cmp=\texttt{cmp}|)}
@ -552,7 +575,15 @@ Dateien in Spalten zusammengef
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{diff}\label{diff}\index{diff=\texttt{diff}|(textbf}
TODO!!! diff
Mit \texttt{diff} werden zwei Dateien verglichen, und die <20>nderungen auf der
Standardausgabe aufgelistet, die n<>tig sind um die erste an die zweite Datei
anzupassen.
Mit dem Parameter \texttt{-r} k<>nnen auch ganze Verzeichnisse rekursiv
verglichen werden.
Die ausgegebenen Listen k<>nnen mit dem \texttt{patch}-Kommando auf Dateien
angewandt werden um sie auf den ge<67>nderten Stand zu bringen.
\index{diff=\texttt{diff}|)}
@ -602,7 +633,7 @@ Variablen zu bilden.
Eine wichtige Anwendung f<>r dieses Kommando ist der Fall, wenn eigentlich ein
Array\index{Array} gebraucht w<>rde. Der Inhalt eines Array-Elements kann
beispielsweise mittels \texttt{eval echo \textbackslash\$arr\$index} ausgegeben
beispielsweise mittels \lstinline|eval echo \$arr$index| ausgegeben
werden, dabei ist \texttt{arr} der Name des Arrays und \texttt{index} der Name
der Variablen, die den Index des auszugebenden Elementes enth<74>lt.
@ -625,7 +656,7 @@ wichtigsten Operatoren lauten wie folgt:
Bei einigen Sonderzeichen ist deren Bedeutung in der Shell zu ber<65>cksichtigen,
sie sind also durch Anf<6E>hrungszeichen oder Backslashes zu quoten:
\texttt{i=`expr \$i \textbackslash{}* 3`}.
\lstinline|i=`expr $i \* 3`|.
Eine andere M<>glichkeit f<>r einfache Rechnungen besteht in der sogenannten
Arith\-me\-tik-Ex\-pan\-sion (Siehe \ref{arithmetikexpansion}).
@ -666,8 +697,7 @@ Vorkommen gr
Da die reine Beschreibung der Parameter manchmal etwas verwirrend ist, folgen
hier ein paar praktische Beispiele:
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
# Suche alle Eintr<74>ge in bzw. unter dem aktuellen Verzeichnis:
find .
# Suche alle normalen Dateien mit der Endung txt unter /home:
@ -680,8 +710,7 @@ find ~ -size +10000000c -exec ls -l {} \;
# Suche alle Eintr<74>ge im Homeverzeichnis, die innerhalb der letzten zwei Tage
# ge<67>ndert wurden:
find ~ -mtime -2
\end{listing}
\normalsize
\end{lstlisting}
Wenn mittels \texttt{-exec} weitere Kommandos gestartet werden, sollte beachtet
werden da<64> mindestens ein Proze<7A> pro Fundstelle gestartet wird. Das kostet sehr
@ -755,8 +784,7 @@ Daneben stehen noch eine Reihe weiterer Signale zur Verf
Es gibt verschiedene Wege, das Signal abzusetzen. Welchen man w<>hlt ist
Geschmackssache. Hier ein paar Beispiele:
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
# Die folgenden Befehle sind gleichwertig. Alle senden ein HUP an Proze<7A>-ID 42:
kill -1 42
kill -HUP 42
@ -770,8 +798,7 @@ kill -9 -1
# SIGTERM an mehrere Prozesse senden:
kill 123 456 789
\end{listing}
\normalsize
\end{lstlisting}
Siehe auch: Das Beispiel `Fallensteller' in Abschnitt \ref{traps} zeigt, wie
ein Skript auf Signale reagieren kann.
@ -780,12 +807,12 @@ ein Skript auf Signale reagieren kann.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{killall}\label{killall}\index{killall=\texttt{killall}|(textbf}
\subsection{killall}\label{killall}\index{killall=\texttt{killall}|(textbf}\marginpar{GNU!}
Im Abschnitt <20>ber \texttt{kill} (\ref{kill}) wird beschrieben, wie man ein
Signal an einen Proze<7A> schickt, dessen ID bekannt ist. Kennt man die ID nicht,
oder will man das Signal an mehrere Prozesse schicken, kann dieses Kommando
eine gro<72>e Hilfe darstellen.
oder will man das Signal an mehrere Prozesse schicken, kann dieses Kommando auf
GNU-Systemen eine gro<72>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
@ -803,6 +830,22 @@ zur Verf
\index{killall=\texttt{killall}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{logger}\label{logger}\index{logger=\texttt{logger}|(textbf}
Mit \texttt{logger} werden Nachrichten an die Log-Mechanismen des Systems
geschickt. So k<>nnen auch unbeobachtet laufende Skripte <20>ber ihr tun
informieren.
Der zu loggende Text wird einfach als Parameter <20>bergeben.
Die GNU-Version\marginpar{GNU!} verf<72>gt <20>ber einige Parameter, unter anderem
kann die Nachricht mit \texttt{-s} parallel zum System-Log auch auf der
Standard-Fehlerausgabe ausgegeben werden.
\index{logger=\texttt{logger}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{ls}\label{ls}\index{ls=\texttt{ls}|(textbf}
@ -812,7 +855,7 @@ oder angegebenen Verzeichnis auf, das Kommando hat aber auch sehr viele
Parameter mit denen sich die Ausgabe anpassen l<><6C>t. Hier sind die wichtigsten,
eine vollst<73>ndige Auflistung bietet wie immer die Man-Page:
\LTXtable{\textwidth}{tab_kommandos_ls_parameter.tex}
\marginpar{GNU!}\LTXtable{\textwidth}{tab_kommandos_ls_parameter.tex}
Besonders informativ gibt sich der Parameter \texttt{-l}, da damit auch die
Eigent<EFBFBD>mer und die Berechtigungen der Dateien angezeigt werden. Die Ausgabe hat
@ -893,7 +936,7 @@ gedreht.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf}
\subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf}\marginpar{GNU!}
Eine h<>ufig wiederkehrende Aufgabe ist es, zu sehen ob ein bestimmter Proze<7A>
existiert oder nicht. Falls das Kommando \texttt{pgrep} zur Verf<72>gung steht,
@ -901,7 +944,7 @@ kannn man auf das Konstrukt mit \texttt{ps} und \texttt{grep} verzichten. Der
folgende Aufruf liefert alle Proze<7A>-IDs, deren Name httpd enth<74>lt, inclusive
des vollen Kommandos:
\texttt{pgrep -lf httpd}
\lstinline|pgrep -lf httpd|
<EFBFBD>ber weitere Parameter l<><6C>t sich genauer spezifizieren, wonach gesucht werden
soll, hier die wichtigsten:
@ -912,7 +955,7 @@ Die Ausgabe enth
sich als Parameter f<>r andere Programme benutzen. Das folgende Beispiel liefert
detaillierte Informationen <20>ber alle xterm-Prozesse:
\texttt{ps -fp \$(pgrep -d, -x xterm)}
\lstinline|ps -fp $(pgrep -d, -x xterm)|
Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}.
@ -920,7 +963,7 @@ 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}\marginpar{GNU!}
Dieses Kommando ist eng verwandt mit \texttt{pgrep} (Siehe Abschnitt
\ref{pgrep}), es versteht im Wesentlichen die gleichen Parameter. Allerdings
@ -934,7 +977,7 @@ diese Funktion wird im Abschnitt zu \texttt{kill} (\ref{kill}) n
beschrieben. Das folgende Kommando veranla<6C>t beispielsweise den Syslog-Daemon,
seine Konfiguration neu einzulesen:
\texttt{pkill -HUP syslogd}
\lstinline|pkill -HUP syslogd|
Das Kommando \texttt{killall} (Abschnitt \ref{killall}) bietet eine <20>hnliche
Funktionalit<EFBFBD>t, allerdings fehlen ihm einige Parameter. Trotzdem sollte im
@ -954,7 +997,7 @@ Dabei enth
bestimmten Regeln durch die Daten ersetzt werden.
Der Format-String folgt im Wesentlichen den gleichen Regeln wie in der
C-Version. N<>heres dazu erf<72>hrt man mit \texttt{man 3 printf}.
C-Version. N<>heres dazu erf<72>hrt man mit \lstinline|man 3 printf|.
Hier die wichtigsten Parameter f<>r den Format-String:
@ -965,15 +1008,13 @@ Daten. Im folgenden Beispiel werden alle Benutzernamen, deren
Home-Verzeichnisse und Default-Shells aus der Datei \texttt{/etc/passwd}
extrahiert und <20>bersichtlich ausgegeben:
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
#!/bin/sh
IFS=:
while read user pass uid gid name home shell; do
printf "%-15s %-25s %s\n" $user $home $shell
done < /etc/passwd
\end{listing}
\normalsize
\end{lstlisting}
Zur Erinnerung: Die vordefinierte Variable
\texttt{\$IFS}\index{\$IFS=\texttt{\$IFS}} ist der Feld-Separator, die
@ -1001,12 +1042,12 @@ In Skripten m
aktiv ist, ob also zum Beispiel ein bestimmter Serverdienst l<>uft. Dazu macht
man \texttt{ps} <20>ber Optionen gespr<70>chiger.
Das Kommando versteht in der GNU-Version zwei unterschiedliche Arten von
Optionen. Den sogenannten Unix- bzw. Posix-Stil und den BSD-Stil. Zus<75>tzlich
gibt es noch ausf<73>hrliche Parameter, aber die sollen hier nicht beschrieben
werden. Die jeweiligen Formen stehen nicht auf allen Systemen zur Verf<72>gung,
wenn ein Skript beispielsweise auch unter Solaris benutzt werden soll ist man
gezwungen, die Unix-Parametrisierung zu benutzen.
Das Kommando versteht in der GNU-Version\marginpar{GNU!} zwei unterschiedliche
Arten von Optionen. Den sogenannten Unix- bzw. Posix-Stil und den BSD-Stil.
Zus<EFBFBD>tzlich gibt es noch ausf<73>hrliche Parameter, aber die sollen hier nicht
beschrieben werden. Die jeweiligen Formen stehen nicht auf allen Systemen zur
Verf<EFBFBD>gung, wenn ein Skript beispielsweise auch unter Solaris benutzt werden
soll ist man gezwungen, die Unix-Parametrisierung zu benutzen.
Unix-Parameter zeichnen sich durch die <20>bliche Angabe mit Bindestrich aus.
BSD-Pa\-ra\-me\-ter werden ohne Bindestrich angegeben, was neben den meisten
@ -1016,8 +1057,7 @@ Es gibt sehr viele verschiedene Parameter, die beste Informationsquelle ist wie
immer die Man-Page bzw. ein entsprechendes Buch. Hier werden nur ein paar
typische Aufrufbeispiele gezeigt, deren Ausgabe sich jeder selber ansehen kann:
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
# Alle Prozesse auflisten, Unix-Syntax:
ps -e
ps -ef
@ -1041,8 +1081,7 @@ ps -C syslogd -o pid=
# Nur den Namen des Prozesses mit der ID 42 ausgeben:
ps -p 42 -o comm=
\end{listing}
\normalsize
\end{lstlisting}
F<EFBFBD>r die Suche nach Prozessen bestimmten Namens steht auf manchen Systemen auch
das Kommando \texttt{pgrep} (Abschnitt \ref{pgrep}) zur Verf<72>gung.
@ -1070,36 +1109,38 @@ alle Zeichen, die in der vordefinierten Variable
Wenn keine Variablennamen angegeben werden, wird die Eingabe in der Variable
\texttt{REPLY} abgelegt.
Normalerweise wird eine Eingabezeile mit einem Newline abgeschlossen. Mit dem
Parameter \texttt{-d} ist es m<>glich, ein anderes Zeilenendezeichen anzugeben.
Beispielsweise liest \texttt{read -d \dq~\dq~var} alle Zeichen bis zum ersten
Leerzeichen in die Variable \texttt{var} ein.
Wenn nur eine bestimmte Zahl von Zeichen gelesen werden soll, kann diese durch
den Parameter \texttt{-n} angegeben werden. Der Befehl \texttt{read -n 5 var}
liest die ersten f<>nf Zeichen in die Variable \texttt{var} ein. Demzufolge kann
ein Skript durch ein \texttt{read -n 1} dazu gebracht werden, auf einen
einzelnen Tastendruck~--~nicht zwingend ein Return~--~zu warten.
Mit dem Parameter \texttt{-p} kann man einen Prompt, also eine
Eingabeaufforderung ausgeben lassen. \texttt{read -p \dq{}Gib was ein:\dq~var}
schreibt also erst den Text \textit{Gib was ein:} auf das Terminal, bevor die
Eingaben in die Variable \texttt{var} <20>bernommen werden. Dieser Prompt wird nur
an einem interaktiven Terminal ausgegeben, also nicht in einem Skript das seine
Eingaben aus einer Datei oder aus einem Stream erh<72>lt.
Sonderzeichen k<>nnen w<>hrend der Eingabe normalerweise mittels eines Backslash
vor der Interpretation gesch<63>tzt werden. Ein Backslash vor einem Newline
bewirkt also eine mehrzeilige Eingabe. Dieses Verhalten kann mit dem Parameter
\texttt{-r} abgeschaltet werden.
Normalerweise wird eine Eingabezeile mit einem Newline abgeschlossen. Mit dem
Parameter \texttt{-d}\marginpar{GNU!} ist es m<>glich, ein anderes
Zeilenendezeichen anzugeben. Beispielsweise liest
\lstinline|read -d " " var| alle Zeichen bis zum ersten Leerzeichen in die
Variable \texttt{var} ein.
Wenn nur eine bestimmte Zahl von Zeichen gelesen werden soll, kann diese durch
den Parameter \texttt{-n}\marginpar{GNU!} angegeben werden. Der Befehl
\lstinline|read -n 5 var| liest die ersten f<>nf Zeichen in die Variable
\texttt{var} ein. Demzufolge kann ein Skript durch ein \lstinline|read -n 1|
dazu gebracht werden, auf einen einzelnen Tastendruck~--~nicht zwingend ein
Return~--~zu warten.
Mit dem Parameter \texttt{-p}\marginpar{GNU!} kann man einen Prompt, also eine
Eingabeaufforderung ausgeben lassen. \lstinline|read -p "Gib was ein:" var|
schreibt also erst den Text \textit{Gib was ein:} auf das Terminal, bevor die
Eingaben in die Variable \texttt{var} <20>bernommen werden. Dieser Prompt wird nur
an einem interaktiven Terminal ausgegeben, also nicht in einem Skript das seine
Eingaben aus einer Datei oder aus einem Stream erh<72>lt.
Wenn die Eingabe von einem Terminal kommt und nicht auf dem Bildschirm
erscheinen soll, zum Beispiel bei Pa<50>wortabfragen, kann die Ausgabe mit dem
Parameter \texttt{-s} (Silent) unterdr<64>ckt werden.
Parameter \texttt{-s}\marginpar{GNU!} (Silent) unterdr<64>ckt werden.
Mit \texttt{-t} kann ein Time-Out definiert werden, nach dessen Ablauf das
Kommando mit einem Fehler abbricht. Dieser Parameter ist nur bei interaktiver
Eingabe oder beim Lesen aus einer Pipe aktiv.
Mit \texttt{-t}\marginpar{GNU!} kann ein Time-Out definiert werden, nach dessen
Ablauf das Kommando mit einem Fehler abbricht. Dieser Parameter ist nur bei
interaktiver Eingabe oder beim Lesen aus einer Pipe aktiv.
Der R<>ckgabewert des \texttt{read}-Kommandos ist 0, es sei denn es trat ein
Timeout oder ein EOF auf.
@ -1119,8 +1160,8 @@ Verzeichnisse k
Gegensatz zu \texttt{rmdir} werden dann auch s<>mtliche enthaltenen Dateien und
Unterverzeichnisse gel<65>scht.
Die GNU-Version von \texttt{rm} unterst<73>tzt zus<75>tzlich den Parameter
\texttt{-v}, mit dem jeder L<>schvorgang ausgegeben wird.
Die GNU-Version\marginpar{GNU!} von \texttt{rm} unterst<73>tzt zus<75>tzlich den
Parameter \texttt{-v}, mit dem jeder L<>schvorgang ausgegeben wird.
\index{rm=\texttt{rm}|)}
@ -1142,7 +1183,7 @@ nicht-leere Verzeichnisse k
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{script}\label{script}\index{script=\texttt{script}|(textbf}
\subsection{script}\label{script}\index{script=\texttt{script}|(textbf}\marginpar{GNU!}
Dieses Kommando eignet sich vorz<72>glich f<>r das Debuggen fertiger Skripte. Man
ruft es in Verbindung mit einem Dateinamen auf. Dieser Aufruf startet eine neue
@ -1176,8 +1217,7 @@ nur die g
\subsubsection{Aufruf}
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
# Aufruf als Stream-Editor:
kommando1 | sed 's/alt/neu/' | kommando2
@ -1200,13 +1240,12 @@ s/alt/neu/
# Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert und
# <20>ber den Parameter -f eingebunden werden:
sed -f script.sed datei.txt
\end{listing}
\normalsize
\end{lstlisting}
Neben den oben erw<72>hnten Parametern kann \texttt{sed} auch mit \texttt{-n}
ruhig gestellt werden. Damit werden die Zeilen nur dann ausgegeben, wenn das
mittels `p' explizit gefordert wird. Die GNU-Version stellt noch ein paar
Parameter zur Verf<72>gung, die Man-Page verr<72>t n<>heres.
mittels `p' explizit gefordert wird. Die GNU-Version\marginpar{GNU!} stellt
noch ein paar Parameter zur Verf<72>gung, die Man-Page verr<72>t n<>heres.
\subsubsection{Addressierung}
@ -1278,8 +1317,7 @@ gehen soll werden hier keine komplexen Sachen vorgestellt, sondern nur ein paar
Einzeiler. Nichtsdestotrotz k<>nnen es auch diese unscheinbaren Aufrufe in sich
haben.
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
### SUCHEN UND ERSETZEN
# Im kompletten Text 'rot' durch 'blau' ersetzen:
@ -1355,25 +1393,24 @@ sed '/./!d' # Methode 2
# Alle Leerzeilen am Dateianfang l<>schen:
sed '/./,$!d'
\end{listing}
\normalsize
\end{lstlisting}
\index{sed=\texttt{sed}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{seq}\label{seq}\index{seq=\texttt{seq}|(textbf}
\subsection{seq}\label{seq}\index{seq=\texttt{seq}|(textbf}\marginpar{GNU!}
Oft wird eine auf- oder absteigende Sequenz aufeinanderfolgender Zahlen
ben<EFBFBD>tigt, beispielsweise um eine Schleife 100 mal zu durchlaufen. Es ist nicht
sehr performant bei jedem Schleifendurchlauf hochzuz<75>hlen und dann die
entstandene Zahl mit dem Limit zu vergleichen. Daher nimmt man an der Stelle
\texttt{seq} zur Hilfe.
\texttt{seq} zur Hilfe, wenn es zur Verf<72>gung steht.
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<65>hlt, und
\texttt{seq 20 -2 10} z<>hlt in zweierschritten r<>ckw<6B>rts von 20 nach 10.
Parametrisierung definiert: Ein Aufruf in der Form \lstinline|seq 10| gibt die
Zahlen von 1 bis 10 aus. Mit \lstinline|seq 10 20| wird von 10 bis 20 gez<65>hlt,
und \lstinline|seq 20 -2 10| z<>hlt in zweierschritten r<>ckw<6B>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
@ -1390,13 +1427,13 @@ mit f
Das Kommando \texttt{sleep} veranla<6C>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<68>ft zehn
Sekunden, \texttt{sleep 10m} zehn Minuten. Genauso werden Stunden (h) und Tage
(d) definiert.
In der GNU-Variante\marginpar{GNU!} von \texttt{sleep} kann die Einheit der
angegebenen Zeitspanne durch Suffixe definiert werden: \lstinline|sleep 10s|
schl<EFBFBD>ft zehn Sekunden, \lstinline|sleep 10m| zehn Minuten. Genauso werden
Stunden (h) und Tage (d) definiert.
Au<EFBFBD>erdem kann die GNU-Variante auch mit nicht-Integer Zeiten arbeiten:
\texttt{sleep 0.5} schl<68>ft eine halbe Sekunde.
\lstinline|sleep 0.5| schl<68>ft eine halbe Sekunde.
\index{sleep=\texttt{sleep}|)}
@ -1447,6 +1484,9 @@ Parameter \texttt{-n} steuern.
Mit dem Parameter \texttt{-f} (follow) gibt \texttt{tail} neue Zeilen aus,
sobald sie an die Datei angeh<65>ngt werden.
Die GNU-Version\marginpar{GNU!} kann auch das Ende mehrere Dateien ausgeben
bzw. verfolgen, wenn mehrere Namen angegeben werden.
\index{tail=\texttt{tail}|)}
@ -1517,8 +1557,7 @@ in der Man-Page.
Die folgenden Beispiele verdeutlichen die Anwendung:
\footnotesize
\begin{listing}[2]{1}
\begin{lstlisting}
text="Dies ist ein Testtext"
# kleine Umlaute durch grosse ersetzen:
@ -1544,8 +1583,7 @@ echo "$text" | tr -s "a-zA-Z"
# doppelte Buchstaben l<>schen, mit Zeichenklasse:
echo "$text" | tr -s "[:alpha:]"
# -> Dies ist ein Testext
\end{listing}
\normalsize
\end{lstlisting}
\index{tr=\texttt{tr}|)}
@ -1564,7 +1602,7 @@ mehrere Bedingungen die zum Ausf
Kommando gibt zm Beispiel eine Fehlermeldung aus wenn sein Skript ein Signal 1
(HUP), 2 (INT) oder 15 (TERM) erh<72>lt:
\texttt{trap 'echo \dq`basename \$0`: Ooops...\dq 1>\&2' 1 2 15}
\lstinline|trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15|
Die Zeile ist dem Beispiel aus Abschnitt \ref{traps} entnommen, dort findet
sich auch nochmal eine ausf<73>hrliche Erkl<6B>rung.
@ -1601,13 +1639,14 @@ Weitaus h
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.
Der Parameter \texttt{-L} gibt in der GNU-Version \marginpar{GNU!} die L<>nge
der l<>ngsten enthaltenen Zeile aus.
\index{wc=\texttt{wc}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{which}\label{which}\index{which=\texttt{which}|(textbf}
\subsection{which}\label{which}\index{which=\texttt{which}|(textbf}\marginpar{GNU!}
Sucht im Pfad (vordefinierte Variable
\texttt{\$PATH}\index{\$PATH=\texttt{\$PATH}}, siehe Abschnitt
@ -1633,8 +1672,8 @@ mit deren aktueller Konsole und der Anmeldezeit aus.
Bisweilen kommt man in die Verlegenheit, versehentlich zu lange Einzeiler
geschrieben zu haben. Neben den F<>llen, in denen der Tipp-Eifer <20>berhand
genommen hat handelt es sich in aller Regel um Zeilen in der Art `\texttt{grep
'text' \$(find / -name \textbackslash*.txt)}'. Dieses Kommando sucht alle
genommen hat handelt es sich in aller Regel um Zeilen in der Art
\lstinline|grep 'text' $(find / -name \*.txt)|. Dieses Kommando sucht alle
Dateien mit der Endung txt, die im System vorhanden sind. Diese werden `in die
Kommandozeile eingebaut'. Wenn sehr viele Dateien gefunden werden, wird die
Zeile zu lang f<>r die Shell\footnote{Die maximale L<>nge der Kommandozeile
@ -1642,23 +1681,23 @@ unterscheidet sich von System zu System}.
Ein weiterer und in der Praxis mindestens ebenso sinnvoller Einsatzzweck ist
das Vermeiden von Schleifen. Das obige Problem lie<69>e sich auch mit einer Zeile
in der Form `\texttt{find / -name \textbackslash*.txt -exec grep 'text' \{\}
\textbackslash;}'. Allerdings h<>tte das den Nachteil, da<64> f<>r jede gefundene
Datei ein neuer \texttt{grep} gestartet werden mu<6D>. Das kostet Resourcen.
in der Form \lstinline|find / -name \*.txt -exec grep 'text' {} \;| l<>sen.
Allerdings h<>tte das den Nachteil, da<64> f<>r jede gefundene Datei ein neuer
\texttt{grep} gestartet werden mu<6D>. Das kostet Resourcen.
Beide Probleme werden durch eine Zeile in der Form `\texttt{find / -name
\textbackslash*.txt | xargs grep 'text'}' umgangen. Dabei liest \texttt{xargs}
aus der Standardeingabe die Parameter, die dann an den \texttt{grep}-Aufruf
angeh<EFBFBD>ngt werden. Sollten zu viele Dateien gefunden werden, wird \texttt{grep}
mehrfach aufgerufen, allerdings im Gegensatz zum obigen Beispiel nicht einmal
pro Fundstelle.
Beide Probleme werden durch eine Zeile in der Form
\lstinline+find / -name \*.txt | xargs grep 'text'+ umgangen. Dabei liest
\texttt{xargs} aus der Standardeingabe die Parameter, die dann an den
\texttt{grep}-Aufruf angeh<EFBFBD>ngt werden. Sollten zu viele Dateien gefunden
werden, wird \texttt{grep} mehrfach aufgerufen, allerdings im Gegensatz zum
obigen Beispiel nicht einmal pro Fundstelle.
Neben einigen anderen Parametern informiert die Manpage <EFBFBD>ber die Option
\texttt{-r}. Damit kann vermieden werden, da<64> \texttt{xargs} das Kommando
startet wenn keine Eingabe vorhanden ist. Bezogen auf das angegebene Beispiel
w<EFBFBD>rde \texttt{grep} ohne Dateinamen gestartet, wenn \texttt{find} nichts
findet. Es w<>rde auf Input von der Standardeingabe warten, der aber
wahrscheinlich nicht kommt. Das Skript w<>rde h<>ngen, wenn der Parameter
\texttt{-r} nicht angewandt w<>rde.
Neben einigen anderen Parametern informiert die Manpage der
GNU-Version\marginpar{GNU!} <20>ber die Option \texttt{-r}. Damit kann vermieden
werden, da<64> \texttt{xargs} das Kommando startet wenn keine Eingabe vorhanden
ist. Bezogen auf das angegebene Beispiel w<EFBFBD>rde \texttt{grep} ohne Dateinamen
gestartet, wenn \texttt{find} nichts findet. Es w<>rde auf Input von der
Standardeingabe warten, der aber wahrscheinlich nicht kommt. Das Skript w<>rde
h<EFBFBD>ngen, wenn der Parameter \texttt{-r} nicht angewandt w<>rde.
\index{xargs=\texttt{xargs}|)}