Viele Aenderungen

This commit is contained in:
rschaten
2005-01-21 17:23:30 +00:00
parent 52635f366a
commit 68d30297e6
6 changed files with 209 additions and 84 deletions

View File

@ -16,10 +16,10 @@ Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunde
\index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{Pipe}\index{grep=\texttt{grep}}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}} \index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{Pipe}\index{grep=\texttt{grep}}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}}
\begin{lstlisting} \begin{lstlisting}
#!/bin/sh #!/bin/sh
until who | grep "^root " until who | grep "^root "; do
do sleep 30 sleep 30
done done
echo Big Brother is watching you! echo "Big Brother is watching you!"
\end{lstlisting} \end{lstlisting}
Das Skript f<>hrt also so lange das Kommando aus, bis die Ausf<73>hrung erfolgreich Das Skript f<>hrt also so lange das Kommando aus, bis die Ausf<73>hrung erfolgreich
@ -42,10 +42,10 @@ Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das melde
\index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{grep=\texttt{grep}}\index{Pipe}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}} \index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{grep=\texttt{grep}}\index{Pipe}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}}
\begin{lstlisting} \begin{lstlisting}
#!/bin/sh #!/bin/sh
while who | grep "^root " while who | grep "^root "; do
do sleep 30 sleep 30
done done
echo Die Katze ist aus dem Haus, Zeit, da<64> die M<>use tanzen! echo "Die Katze ist aus dem Haus, Zeit, da<64> die M<>use tanzen!"
\end{lstlisting} \end{lstlisting}
Die Schleife wird n<>mlich dann so lange ausgef<65>hrt, bis \texttt{grep}\index{grep=\texttt{grep}} einen Fehler (bzw. eine erfolglose Suche) zur<75>ckmeldet. Die Schleife wird n<>mlich dann so lange ausgef<65>hrt, bis \texttt{grep}\index{grep=\texttt{grep}} einen Fehler (bzw. eine erfolglose Suche) zur<75>ckmeldet.
@ -245,18 +245,31 @@ echo "aflag=$aflag / Name = $name / Die Dateien sind $*"
\end{lstlisting} \end{lstlisting}
\section{Fallensteller: Auf Traps \section{Fallensteller: Auf Traps reagieren}\label{traps}\index{trap=\texttt{trap}|(}\index{Signal|(}
reagieren}\label{traps}\index{trap=\texttt{trap}|(}\index{Signal|(}
Ein laufendes Shell-Skript kann durch Druck auf die Interrupt-Taste (normalerweise \Ovalbox{CTRL}-\Ovalbox{C}) unterbrochen werden. Durch Druck auf diese Taste wird ein Signal an den entsprechenden Proze<7A> gesandt, das ihn bittet sich zu beenden. Dieses Signal hei<65>t SIGINT (f<>r SIGnal INTerrupt) und tr<74>gt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript sich tempor<6F>re Dateien angelegt hat, da diese nach der Ausf<73>hrung nur noch unn<6E>tig Platz verbrauchen und eigentlich gel<65>scht werden sollten. Man kann sich sicher auch noch wichtigere F<>lle vorstellen, in denen ein Skript bestimmte Aufgaben auf jeden Fall erledigen mu<6D>, bevor es sich beendet. Ein laufendes Shell-Skript kann durch Druck auf die Interrupt-Taste
(normalerweise \Ovalbox{CTRL}-\Ovalbox{C}) unterbrochen werden. Durch Druck auf
diese Taste wird ein Signal an den entsprechenden Proze<7A> gesandt, das ihn
bittet sich zu beenden. Dieses Signal hei<65>t SIGINT (f<>r SIGnal INTerrupt) und
tr<EFBFBD>gt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript
sich tempor<6F>re Dateien angelegt hat, da diese nach der Ausf<73>hrung nur noch
unn<EFBFBD>tig Platz verbrauchen und eigentlich gel<65>scht werden sollten. Man kann
sich sicher auch noch wichtigere F<>lle vorstellen, in denen ein Skript
bestimmte Aufgaben auf jeden Fall erledigen mu<6D>, bevor es sich beendet.
Es gibt eine Reihe weiterer Signale, auf die ein Skript reagieren kann. Alle sind in der Man-Page von \texttt{signal} beschrieben. Hier die wichtigsten:\nopagebreak Es gibt eine Reihe weiterer Signale, auf die ein Skript reagieren kann. Alle
sind in der Man-Page von \texttt{signal} beschrieben. Hier die
wichtigsten:\nopagebreak
\LTXtable{\textwidth}{tab_signale.tex} \LTXtable{\textwidth}{tab_signale.tex}
Wie l<>st man jetzt dieses Problem? Gl<47>cklicherweise verf<72>gt die Shell <20>ber das \texttt{trap}-Kommando, mit dessen Hilfe man auf diese Signale reagieren kann. Die Anwendung soll in folgendem Skript beispielhaft dargestellt werden. Wie l<>st man jetzt dieses Problem? Gl<47>cklicherweise verf<72>gt die Shell <20>ber das
\texttt{trap}-Kommando, mit dessen Hilfe man auf diese Signale reagieren kann.
Die Anwendung soll in folgendem Skript beispielhaft dargestellt werden.
Das Skript soll eine komprimierte Textdatei mittels \texttt{zcat} in ein tempor<6F>res File entpacken, dieses mit \texttt{pg} seitenweise anzeigen und nachher wieder l<>schen. Das Skript soll eine komprimierte Textdatei mittels \texttt{zcat} in ein
tempor<EFBFBD>res File entpacken, dieses mit \texttt{pg} seitenweise anzeigen und
nachher wieder l<>schen.
\index{!==\texttt{!=}} \index{!==\texttt{!=}}
\begin{lstlisting} \begin{lstlisting}
@ -266,7 +279,12 @@ temp=/tmp/zeige$$
\end{lstlisting} \end{lstlisting}
Zun<EFBFBD>chst werden zwei Variablen belegt, die im weiteren Verlauf benutzt werden sollen. In \texttt{stat} wird der Wert abgelegt, den das Skript im Falle eines Abbruchs als Exit-Status zur<75>ckliefern soll. Die Variable \texttt{temp} enth<74>lt den Namen f<>r eine tempor<6F>re Datei. Dieser setzt sich zusammen aus \texttt{/tmp/zeige} und der Proze<7A>nummer des laufenden Skripts. So soll sichergestellt werden, da<64> noch keine Datei mit diesem Namen existiert. Zun<EFBFBD>chst werden zwei Variablen belegt, die im weiteren Verlauf benutzt werden
sollen. In \texttt{stat} wird der Wert abgelegt, den das Skript im Falle eines
Abbruchs als Exit-Status zur<75>ckliefern soll. Die Variable \texttt{temp} enth<74>lt
den Namen f<>r eine tempor<6F>re Datei. Dieser setzt sich zusammen aus
\texttt{/tmp/zeige} und der Proze<7A>nummer des laufenden Skripts. So soll
sichergestellt werden, da<64> noch keine Datei mit diesem Namen existiert.
\index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}} \index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
\begin{lstlisting}[firstnumber=last] \begin{lstlisting}[firstnumber=last]
@ -275,7 +293,17 @@ trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15
\end{lstlisting} \end{lstlisting}
Hier werden die Traps definiert. Bei Signal 0 wird die tempor<6F>re Datei gel<65>scht und der Wert aus der Variable \texttt{stat} als Exit-Code zur<75>ckgegeben. Dabei wird dem \texttt{rm}-Kommando der Parameter\index{Parameter} \texttt{-f} mitgegeben, damit keine Fehlermeldung ausgegeben wird, falls die Datei (noch) nicht existiert. Dieser Fall tritt bei jedem Beenden des Skriptes auf, also sowohl bei einem normalen Ende, als auch beim Exit-Kommando, bei einem Interrupt oder bei einem Kill\index{kill=\texttt{kill}}. Der zweite Trap reagiert auf die Signale 1, 2 und 15. Das hei<65>t, er wird bei jedem unnormalen Ende ausgef<65>hrt. Er gibt eine entsprechende Meldung auf die Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet, und der erste Trap wird ausgef<65>hrt. Hier werden die Traps definiert. Bei Signal 0 wird die tempor<6F>re Datei gel<65>scht
und der Wert aus der Variable \texttt{stat} als Exit-Code zur<75>ckgegeben. Dabei
wird dem \texttt{rm}-Kommando der Parameter\index{Parameter} \texttt{-f}
mitgegeben, damit keine Fehlermeldung ausgegeben wird, falls die Datei (noch)
nicht existiert. Dieser Fall tritt bei jedem Beenden des Skriptes auf, also
sowohl bei einem normalen Ende, als auch beim Exit-Kommando, bei einem
Interrupt oder bei einem Kill\index{kill=\texttt{kill}}. Der zweite Trap
reagiert auf die Signale 1, 2 und 15. Das hei<65>t, er wird bei jedem unnormalen
Ende ausgef<65>hrt. Er gibt eine entsprechende Meldung auf die
Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet,
und der erste Trap wird ausgef<65>hrt.
\index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}} \index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}}
\begin{lstlisting}[firstnumber=last] \begin{lstlisting}[firstnumber=last]
@ -287,7 +315,14 @@ case $# in
\end{lstlisting} \end{lstlisting}
Jetzt kommt die eigentliche Funktionalit<69>t des Skriptes: Das \texttt{case}-Kommando (\ref{case}) testet die Anzahl der <20>bergebenen Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} <20>bergeben wurde, entpackt \texttt{zcat} die Datei, die im ersten Parameter\index{Parameter} angegeben wurde, in die tempor<6F>re Datei. Dann folgt die Seitenweise Ausgabe mittels \texttt{pg}. Nach Beendigung der Ausgabe wird der Status in der Variablen auf 0 gesetzt, damit beim Skriptende der korrekte Exit-Code zur<75>ckgegeben wird. Jetzt kommt die eigentliche Funktionalit<69>t des Skriptes: Das
\texttt{case}-Kommando (\ref{case}) testet die Anzahl der <20>bergebenen
Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} <20>bergeben
wurde, entpackt \texttt{zcat} die Datei, die im ersten
Parameter\index{Parameter} angegeben wurde, in die tempor<6F>re Datei. Dann folgt
die Seitenweise Ausgabe mittels \texttt{pg}. Nach Beendigung der Ausgabe wird
der Status in der Variablen auf 0 gesetzt, damit beim Skriptende der korrekte
Exit-Code zur<75>ckgegeben wird.
\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}} \index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
\begin{lstlisting}[firstnumber=last] \begin{lstlisting}[firstnumber=last]
@ -296,7 +331,9 @@ esac
\end{lstlisting} \end{lstlisting}
Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit der Aufrufsyntax auf die Standard-Fehlerausgabe geschrieben. Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit
der Aufrufsyntax auf die Standard-Fehlerausgabe geschrieben.
\index{trap=\texttt{trap}|)}\index{Signal|)} \index{trap=\texttt{trap}|)}\index{Signal|)}

View File

@ -42,7 +42,7 @@ werden um wieder entpackt zu werden.
Ein Beispiel verdeutlicht diese Kopier-F<>higkeit: Ein Beispiel verdeutlicht diese Kopier-F<>higkeit:
\texttt{tar cf - . | ( cd /tmp/backup; tar xf - )} \lstinline_tar cf - . | ( cd /tmp/backup; tar xf - )_
Hier wird zun<75>chst der Inhalt des aktuellen Verzeichnisses `verpackt'. Das Hier wird zun<75>chst der Inhalt des aktuellen Verzeichnisses `verpackt'. Das
Resultat wird an die Standard-Ausgabe geschrieben. Auf der Empf<70>ngerseite der Resultat wird an die Standard-Ausgabe geschrieben. Auf der Empf<70>ngerseite der
@ -57,9 +57,13 @@ Am Ziel-Ort finden sich jetzt die gleichen Dateien wie am Quell-Ort.
Das lie<69>e sich lokal nat<61>rlich auch anders l<>sen. Man k<>nnte erst ein Archiv Das lie<69>e sich lokal nat<61>rlich auch anders l<>sen. Man k<>nnte erst ein Archiv
erstellen, das dann an anderer Stelle wieder auspacken. Nachteil: Es mu<6D> erstellen, das dann an anderer Stelle wieder auspacken. Nachteil: Es mu<6D>
gen<EFBFBD>gend Platz f<>r das Archiv vorhanden sein. Denkbar w<>re auch ein in den Raum gen<EFBFBD>gend Platz f<>r das Archiv vorhanden sein. Denkbar w<>re auch ein in den Raum
gestelltes \texttt{cp -Rp * /tmp/backup}. Allerdings fehlen einem dabei gestelltes
mitunter n<>tzliche \texttt{tar}-Optionen\footnote{Mit \texttt{-l} verl<72><6C>t
\texttt{tar} beispielsweise nicht das File-System. N<>tzlich wenn eine Partition \lstinline_cp -Rp * /tmp/backup_
Allerdings fehlen einem dabei mitunter n<>tzliche
\texttt{tar}-Optionen\footnote{Mit \texttt{-l} verl<72><6C>t \texttt{tar}
beispielsweise nicht das File-System. N<>tzlich wenn nur eine Partition
gesichert werden soll.}, und die oben erw<72>hnte Br<42>cke w<>re mit einem reinen gesichert werden soll.}, und die oben erw<72>hnte Br<42>cke w<>re mit einem reinen
\texttt{cp} nicht m<>glich. \texttt{cp} nicht m<>glich.
@ -69,14 +73,14 @@ nur unter Vorsicht einsetzen!) schlagen die Br
dort wird entweder gepackt und versendet oder quasi die Subshell gestartet und dort wird entweder gepackt und versendet oder quasi die Subshell gestartet und
gelesen. Das sieht wie folgt aus: gelesen. Das sieht wie folgt aus:
\texttt{ssh 192.168.2.1 tar clf - / | (cd /mnt/backup; tar xf - )} \lstinline_ssh 192.168.2.1 tar clf - / | (cd /mnt/backup; tar xf - )_
Hier wird auf einem entfernten Rechner die Root-Partition verpackt, per SSH in Hier wird auf einem entfernten Rechner die Root-Partition verpackt, per SSH in
das lokale System geholt und lokal im Backup-Verzeichnis entpackt. das lokale System geholt und lokal im Backup-Verzeichnis entpackt.
Der Weg in die andere Richtung ist ganz <20>hnlich: Der Weg in die andere Richtung ist ganz <20>hnlich:
\texttt{tar cf - datei.txt | ssh 192.168.2.1 \dq(mkdir -p \$PWD ;cd \$PWD; tar xf -)\dq} \lstinline_tar cf - datei.txt | ssh 192.168.2.1 "(mkdir -p $PWD ;cd $PWD; tar xf -)"_
Hier wird die Datei verpackt und versendet. Eine Besonderheit gegen<65>ber dem Hier wird die Datei verpackt und versendet. Eine Besonderheit gegen<65>ber dem
vorigen Beispiel bestehtdarin, da<64> das Zielverzeichnis bei Bedarf erstellt vorigen Beispiel bestehtdarin, da<64> das Zielverzeichnis bei Bedarf erstellt

View File

@ -15,6 +15,8 @@
headsepline, % Trennlinie unter die Kopfzeile headsepline, % Trennlinie unter die Kopfzeile
pointlessnumbers, % Keine Punkte hinter den pointlessnumbers, % Keine Punkte hinter den
% Gliederungsnummern % Gliederungsnummern
% halfparskip, % Abst<73>nde zwischen den Abs<62>tzen, statt
% Einr<6E>ckung der ersten Zeile
% draft, % Entwurfsmodus % draft, % Entwurfsmodus
final, % Release-Modus final, % Release-Modus
twoside % Doppelseitig, f<>r Buch twoside % Doppelseitig, f<>r Buch
@ -49,9 +51,11 @@
\lstset{ \lstset{
extendedchars=true, extendedchars=true,
backgroundcolor=\color[gray]{0.95}, backgroundcolor=\color[gray]{0.95},
basicstyle=\ttfamily\scriptsize, %basicstyle=\ttfamily\scriptsize,
basicstyle=\ttfamily\footnotesize,
numbers=left, numbers=left,
numberstyle=\tiny, %numberstyle=\tiny,
numberstyle=\scriptsize,
stepnumber=2, stepnumber=2,
numbersep=5pt numbersep=5pt
} }
@ -104,6 +108,32 @@
\newpage \newpage
\thispagestyle{empty} % eine Leerseite \thispagestyle{empty} % eine Leerseite
~\vfill ~\vfill
%\fboxsep 1.36mm
%\definecolor{g1}{gray}{0.92}
%\newsavebox{\syntaxbox}
%\newenvironment{sybox}
%{\begin{lrbox}{\syntaxbox}
%\begin{minipage}{12.5cm}}
%{\end{minipage}
%\end{lrbox}
%{\fcolorbox{g1}{g1}
%{\parbox{12.5cm}{\usebox{\syntaxbox}\hfill\hbox{}}}}}
%
%\begin{sybox}
%Syntaxbox, in der Sonderzeichen wie \verb?%~^? dargestellt werden k<>nnen.
%
%Dieses Dokument ist entstanden, weil ich f<>r mich selbst eine kompakte
%<25>bersicht zu diesem Thema haben wollte. Ich beabsichtige nicht, damit in
%irgendeiner Form Kommerz zu machen. Ich stelle es frei zur Verf<72>gung, in der
%Hoffnung, da<64> andere Leute daraus vielleicht einen Nutzen ziehen k<>nnen.
%\textbf{Aber ich <20>bernehme keine Garantie f<>r die Korrektheit der hier
%dargestellten Dinge.} Mit der Formulierung \textsl{`daraus vielleicht einen
%Nutzen ziehen k<>nnen'} meine ich nicht, da<64> dieses Dokument~--~oder Teile
%daraus~--~verkauft werden darf. \textbf{Dieses Dokument darf nur kostenlos
%weitergegeben werden.}
%\end{sybox}
\footnotesize \footnotesize
Copyright \copyright{} 2000-2005 Ronald Schaten (ronald@schatenseite.de)\bigskip Copyright \copyright{} 2000-2005 Ronald Schaten (ronald@schatenseite.de)\bigskip
@ -139,7 +169,11 @@ chronologischer Reihenfolge ihres Eingreifens):
Und ich bitte alle Leser, auf eventuelle Fehler zu achten und mich darauf Und ich bitte alle Leser, auf eventuelle Fehler zu achten und mich darauf
aufmerksam zu machen. Auch abgesehen davon freue ich mich <20>ber jede aufmerksam zu machen. Auch abgesehen davon freue ich mich <20>ber jede
R<EFBFBD>ckmeldung. R<EFBFBD>ckmeldung.\bigskip
Dieses Dokument entstand unter Verwendung von Linux, vim und \LaTeX. Dank an
deren Entwickler.
\normalsize \normalsize
\newpage \newpage
\pagenumbering{roman} \pagenumbering{roman}

View File

@ -1,16 +0,0 @@
% $Id$
\begin{longtable}{|X l|}
% KILLED & LINE!!!! \kill
\hline
\endfirsthead
\endhead
\endfoot
\hline
\endlastfoot
\multicolumn{2}{|X|}{\texttt{if who | grep \$1 > /dev/null~~\# who: Liste der Benutzer}\index{Pipe}\index{\$n=\texttt{\$}$n$}\index{!>=\texttt{!>}}\index{who=\texttt{who}}} \\
\multicolumn{2}{|X|}{\texttt{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\# grep: Suche nach Muster}} \\
\multicolumn{2}{|X|}{\texttt{then :~~~~~~~~~~~~~~~~~~~~~~~~\# tut nichts}} \\
\multicolumn{2}{|X|}{\texttt{~else echo \dq Benutzer \$1 ist nicht angemeldet\dq}\index{Anf<EFBFBD>hrungszeichen}} \\
\multicolumn{2}{|X|}{\texttt{fi}} \\
\end{longtable}

View File

@ -240,8 +240,8 @@ awk '
print $2; print $2;
}' datei.txt }' datei.txt
# Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert und # Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert
# <20>ber den Parameter -f eingebunden werden: # und <20>ber den Parameter -f eingebunden werden:
awk -f script.awk datei.txt awk -f script.awk datei.txt
\end{lstlisting} \end{lstlisting}
@ -313,8 +313,8 @@ Hier ein paar Einfache Beispiele f
# Datens<6E>tze mit mehr als zwei Feldern ausw<73>hlen: # Datens<6E>tze mit mehr als zwei Feldern ausw<73>hlen:
NF > 2 NF > 2
# Das dritte und das zweite Feld jeder Zeile ausgeben, deren erstes Feld den # Das dritte und das zweite Feld jeder Zeile ausgeben, deren erstes Feld
# String 'WICHTIG' enth<74>lt: # den String 'WICHTIG' enth<74>lt:
$1 ~ /WICHTIG/ { print $3, $2 } $1 ~ /WICHTIG/ { print $3, $2 }
# Die Vorkommen von 'muster' z<>hlen, und deren Anzahl ausgeben: # Die Vorkommen von 'muster' z<>hlen, und deren Anzahl ausgeben:
@ -328,19 +328,20 @@ length($0) < 23
# enthalten: # enthalten:
NF == 7 && /^Name:/ NF == 7 && /^Name:/
# Alle Felder der Eingabedaten zeilenweise in umgekehrter Reihenfolge ausgeben: # Alle Felder der Eingabedaten zeilenweise in umgekehrter Reihenfolge
# ausgeben:
{ {
for (i = NF; i >= 1; i--) for (i = NF; i >= 1; i--)
print $i print $i
} }
# Die Gr<47><72>e aller TeX-Dateien addieren, die Summe in kB umrechnen und ausgeben, # Die Gr<47><72>e aller TeX-Dateien addieren, die Summe in kB umrechnen und
# verarbeitet die Ausgabe von 'ls -l': # ausgeben, verarbeitet die Ausgabe von 'ls -l':
/.*tex/ { summe += $5 } /.*tex/ { summe += $5 }
END { summe /= 1024; print "Die Gr<47><72>e aller TeX-Files betr<74>gt", summe, "kB" } END { summe /= 1024; print "Die Gr<47><72>e aller TeX-Files:", summe, "kB" }
# Pipe-Separierte Liste aller gemounteten Partitionen und derer F<>llst<73>nde # Pipe-Separierte Liste aller gemounteten Partitionen und derer
# ausgeben, verarbeitet die Ausgabe von 'df': # F<>llst<73>nde ausgeben, verarbeitet die Ausgabe von 'df':
BEGIN { OFS="|" } BEGIN { OFS="|" }
/^\/dev\// { print $1,$5 } /^\/dev\// { print $1,$5 }
@ -705,15 +706,20 @@ hier ein paar praktische Beispiele:
\begin{lstlisting} \begin{lstlisting}
# Suche alle Eintr<74>ge in bzw. unter dem aktuellen Verzeichnis: # Suche alle Eintr<74>ge in bzw. unter dem aktuellen Verzeichnis:
find . find .
# Suche alle normalen Dateien mit der Endung txt unter /home: # Suche alle normalen Dateien mit der Endung txt unter /home:
find /home -type f -name \*.txt find /home -type f -name \*.txt
# Suche alle Eintr<74>ge au<61>er symbolischen Links, in die jeder schreiben darf:
# Suche alle Eintr<74>ge au<61>er symbolischen Links, in die jeder schreiben
# darf:
find / \! -type l -perm 777 find / \! -type l -perm 777
# Suche alle Dateien unter dem Homeverzeichnis, deren Gr<47><72>e 10000000 Bytes
# <EFBFBD>bersteigt und gib sie ausf<73>hrlich aus: # Suche alle Dateien unter dem Homeverzeichnis, deren Gr<47><72>e 10000000
# Bytes <20>bersteigt und gib sie ausf<73>hrlich aus:
find ~ -size +10000000c -exec ls -l {} \; find ~ -size +10000000c -exec ls -l {} \;
# Suche alle Eintr<74>ge im Homeverzeichnis, die innerhalb der letzten zwei Tage
# ge<EFBFBD>ndert wurden: # Suche alle Eintr<74>ge im Homeverzeichnis, die innerhalb der letzten zwei
# Tage ge<67>ndert wurden:
find ~ -mtime -2 find ~ -mtime -2
\end{lstlisting} \end{lstlisting}
@ -790,7 +796,8 @@ Es gibt verschiedene Wege, das Signal abzusetzen. Welchen man w
Geschmackssache. Hier ein paar Beispiele: Geschmackssache. Hier ein paar Beispiele:
\begin{lstlisting} \begin{lstlisting}
# Die folgenden Befehle sind gleichwertig. Alle senden ein HUP an Proze<7A>-ID 42: # Die folgenden Befehle sind gleichwertig. Alle senden ein HUP an
# Proze<7A>-ID 42:
kill -1 42 kill -1 42
kill -HUP 42 kill -HUP 42
kill -SIGHUP 42 kill -SIGHUP 42
@ -798,7 +805,8 @@ kill -s 1 42
kill -s HUP 42 kill -s HUP 42
kill -s SIGHUP 42 kill -s SIGHUP 42
# virtueller Selbstmord: Alle Prozesse umbringen, die man umbringen kann: # virtueller Selbstmord:
# Alle Prozesse umbringen, die man umbringen kann:
kill -9 -1 kill -9 -1
# SIGTERM an mehrere Prozesse senden: # SIGTERM an mehrere Prozesse senden:
@ -1073,8 +1081,8 @@ ps -ely
ps ax ps ax
ps axu ps axu
# Proze<7A>baum ausgeben. Das ist in Skripten weniger Sinnvoll, wird hier aber # Proze<7A>baum ausgeben. Das ist in Skripten weniger Sinnvoll, wird hier
# angegeben weil es so eine praktische Funktion ist... :-) # aber angegeben weil es so eine praktische Funktion ist... :-)
ps -ejH ps -ejH
ps axjf ps axjf
@ -1229,12 +1237,12 @@ kommando1 | sed 's/alt/neu/' | kommando2
# Aufruf mit einer zu bearbeitenden Datei: # Aufruf mit einer zu bearbeitenden Datei:
sed 's/alt/neu/' datei.txt sed 's/alt/neu/' datei.txt
# Wenn mehr als ein Kommando ausgef<65>hrt werden soll, mu<6D> der Parameter -e # Wenn mehr als ein Kommando ausgef<65>hrt werden soll, mu<6D> der Parameter
# verwendet werden: # -e verwendet werden:
sed -e 's/alt/neu/' -e '/loeschen/d' datei.txt sed -e 's/alt/neu/' -e '/loeschen/d' datei.txt
# Man kann auch mehrere Kommandos mit einem -e aufrufen, wenn sie durch ein # Man kann auch mehrere Kommandos mit einem -e aufrufen, wenn sie durch
# Semikolon getrennt werden: # ein Semikolon getrennt werden:
sed 's/alt/neu/; /loeschen/d' datei.txt sed 's/alt/neu/; /loeschen/d' datei.txt
# In einem Skript kann das Kommando auch <20>ber mehrere Zeilen gehen: # In einem Skript kann das Kommando auch <20>ber mehrere Zeilen gehen:
@ -1242,8 +1250,8 @@ sed '
s/alt/neu/ s/alt/neu/
/loeschen/d' datei.txt /loeschen/d' datei.txt
# Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert und # Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert
# <20>ber den Parameter -f eingebunden werden: # und <20>ber den Parameter -f eingebunden werden:
sed -f script.sed datei.txt sed -f script.sed datei.txt
\end{lstlisting} \end{lstlisting}
@ -1330,10 +1338,12 @@ sed 's/rot/blau/' # Ersetzt nur das erste Vorkommen in jeder Zeile
sed 's/rot/blau/4' # Ersetzt nur das vierte Vorkommen in jeder Zeile sed 's/rot/blau/4' # Ersetzt nur das vierte Vorkommen in jeder Zeile
sed 's/rot/blau/g' # Ersetzt nur jedes Vorkommen in jeder Zeile sed 's/rot/blau/g' # Ersetzt nur jedes Vorkommen in jeder Zeile
# 'rot' durch 'blau' ersetzen, aber NUR in Zeilen die auch 'gelb' enthalten: # 'rot' durch 'blau' ersetzen, aber NUR in Zeilen die auch 'gelb'
# enthalten:
sed '/gelb/s/rot/blau/g' sed '/gelb/s/rot/blau/g'
# 'rot' durch 'blau' ersetzen, AUSSER in Zeilen die auch 'gelb' enthalten: # 'rot' durch 'blau' ersetzen, AUSSER in Zeilen die auch 'gelb'
# enthalten:
sed '/gelb/!s/rot/blau/g' sed '/gelb/!s/rot/blau/g'
# 'rosa', 'hellrot' und 'magenta' durch 'pink' ersetzen: # 'rosa', 'hellrot' und 'magenta' durch 'pink' ersetzen:
@ -1344,9 +1354,10 @@ gsed 's/rosa\|hellrot\|magenta/pink/g' # nur in GNU sed
# lies: 'ersetze jeden Zeilenanfang durch f<>nf Leerzeichen' # lies: 'ersetze jeden Zeilenanfang durch f<>nf Leerzeichen'
sed 's/^/ /' sed 's/^/ /'
# F<>hrende Blanks (Leerzeichen, Tabulatoren) von den Zeilenanf<6E>ngen l<>schen: # F<>hrende Blanks (Leerzeichen, Tabulatoren) von den Zeilenanf<6E>ngen
# ACHTUNG: An Stelle des \t mu<6D> der Tabulator gedr<64>ckt werden, die Darstellung # l<EFBFBD>schen:
# als \t versteht nicht jedes sed! # ACHTUNG: An Stelle des \t mu<6D> der Tabulator gedr<64>ckt werden, die
# Darstellung als \t versteht nicht jedes sed!
sed 's/^[ \t]*//' sed 's/^[ \t]*//'
# Schliessende Blanks vom Zeilenende l<>schen, siehe oben: # Schliessende Blanks vom Zeilenende l<>schen, siehe oben:
@ -1612,6 +1623,30 @@ Kommando gibt zm Beispiel eine Fehlermeldung aus wenn sein Skript ein Signal 1
Die Zeile ist dem Beispiel aus Abschnitt \ref{traps} entnommen, dort findet Die Zeile ist dem Beispiel aus Abschnitt \ref{traps} entnommen, dort findet
sich auch nochmal eine ausf<73>hrliche Erkl<6B>rung. sich auch nochmal eine ausf<73>hrliche Erkl<6B>rung.
Ein weiterer n<>tzlicher Einsatz f<>r \texttt{trap} ist es, Signale zu
ignorieren. Das kann gew<65>nscht sein, wenn eine Folge von Kommandos in einem
Skript auf keinen Fall unterbrochen werden darf. Um zu verhindern da<64> ein
\Ovalbox{CTRL}-\Ovalbox{C} des Benutzers das Skript beendet wird folgendes
Konstrukt eingesetzt:
\begin{lstlisting}
trap '' 2 # Signal 2 ist Ctrl-C, jetzt deaktiviert.
kommando1
kommando2
kommando3
trap 2 # Reaktiviert Ctrl-C
\end{lstlisting}
Vielleicht w<>re es aber auch dem Benutzer gegen<65>ber freundlicher, auf das
entkr<EFBFBD>ftete Signal hinzuweisen:
\lstinline|trap 'echo "Ctrl-C ist ausser Kraft."' 2|
Eine Sonderbehandlung macht die Shell, wenn als Signal \texttt{DEBUG} angegeben
wird. Dann wird nach jedem ausgef<65>hrten Kommando der Trap ausgel<65>st. Dieses
Feature wird wie der Name schon erahnen l<><6C>t zum Debuggen benutzt, ein Beispiel
findet sich in Abschnitt \ref{fehlersuche}.
\index{trap=\texttt{trap}|)} \index{trap=\texttt{trap}|)}

View File

@ -54,7 +54,7 @@ da
kann man an der Shell durch Eingabe von \lstinline/echo $PATH/\index{\$PATH=\texttt{\$PATH}} herausfinden. kann man an der Shell durch Eingabe von \lstinline/echo $PATH/\index{\$PATH=\texttt{\$PATH}} herausfinden.
\section{Fehlersuche} \section{Fehlersuche}\label{fehlersuche}\index{Fehlersuche|(}\index{debuggen|(}
Es gibt f<>r Shell-Skripte keine wirklichen Debugger, aber trotzdem verf<72>gt man Es gibt f<>r Shell-Skripte keine wirklichen Debugger, aber trotzdem verf<72>gt man
<EFBFBD>ber einige bew<65>hrte Methoden zum Aufsp<73>ren von Fehlern: <EFBFBD>ber einige bew<65>hrte Methoden zum Aufsp<73>ren von Fehlern:
@ -86,6 +86,18 @@ Aufruf
Zeile vor der Ausf<73>hrung aus, allerdings im Gegensatz zu \texttt{-x} nicht in Zeile vor der Ausf<73>hrung aus, allerdings im Gegensatz zu \texttt{-x} nicht in
der expandierten sondern in der vollen Form. der expandierten sondern in der vollen Form.
\item \texttt{set -e}: Alle g<>ngigen Shell-Kommandos liefern einen
R<EFBFBD>ckgabewert, der Auskunft <20>ber Erfolg oder Mi<4D>erfolg gibt (siehe Abschnitt
\ref{exitcode}). Normalerweise liegt es beim Programmierer, diese Werte zu
interpretieren. Setzt man aber mit dem Schalter \texttt{-e} den sogenannten
errexit-Modus, beendet die Shell das Skript sobald ein Kommando sich mit einem
R<EFBFBD>ckgabewert ungleich 0 beendet.
Ausnahmen gibt es lediglich, wenn das betroffene Kommando in ein Konstrukt
wie \texttt{while}, \texttt{until} oder \texttt{if} eingebunden ist. Auch wenn
der R<>ckgabewert mittels \texttt{\&\&} oder \texttt{||} verarbeitet wird,
beendet sich die Shell nicht.
\item System-Log: F<>r das direkte Debuggen ist dieser Weg weniger geeignet, \item System-Log: F<>r das direkte Debuggen ist dieser Weg weniger geeignet,
aber gerade in unbeobachtet laufenden Skripten sollte man unerwartete Zust<73>nde aber gerade in unbeobachtet laufenden Skripten sollte man unerwartete Zust<73>nde
oder besondere Ereignisse im System-Log festhalten. Dies geschieht mit dem oder besondere Ereignisse im System-Log festhalten. Dies geschieht mit dem
@ -98,12 +110,22 @@ eine l
Ruhe analysiert werden. Das Kommando wird in Abschnitt \ref{script} Ruhe analysiert werden. Das Kommando wird in Abschnitt \ref{script}
beschrieben. beschrieben.
TODO: Debuggen \item \texttt{tee}: Wenn Ausgaben eines Kommandos durch den Filter \texttt{tee}
%http://localhost/~rschaten/doku/abs-guide/debugging.html#FTN.AEN14050 geschoben werden, k<>nnen sie in einer Datei mitgeschrieben werden. Auch diese
%-> trapping signals Variante bietet einen stre<72>freien Blick auf unter Umst<73>nden sehr lange und
komplexe Ausgaben. Abschnitt \ref{tee} gibt weitere Hinweise zu dem Kommando.
\item Variablen `tracen': Das Kommando \texttt{trap} (Abschnitt \ref{trap})
reagiert auf Signale. Die Shell erzeugt nach jedem Kommando das Signal DEBUG,
so da<64> mit dem folgenden Kommando daf<61>r gesorgt werden kann, da<64> der Inhalt
einer Variablen nach jedem Kommando ausgegeben wird:
\lstinline|trap 'echo "Trace> \$var = \"$var\""' DEBUG|
\end{itemize} \end{itemize}
\index{Fehlersuche|)}\index{debuggen|)}
\section{R<EFBFBD>ckgabewerte}\label{exitcode}\index{R<EFBFBD>ckgabewert|(textbf}\index{Exit-Code|see{R<EFBFBD>ckgabewert}}\index{Exit-Status|see{R<EFBFBD>ckgabewert}} \section{R<EFBFBD>ckgabewerte}\label{exitcode}\index{R<EFBFBD>ckgabewert|(textbf}\index{Exit-Code|see{R<EFBFBD>ckgabewert}}\index{Exit-Status|see{R<EFBFBD>ckgabewert}}
@ -286,11 +308,16 @@ Die folgenden Zeichen k
\index{Quoting|)} \index{Quoting|)}
\section{Meta-Zeichen}\index{Meta-Zeichen|(textbf}\index{Wildcards|see{Metazeichen}}\index{Joker-Zeichen|see{Metazeichen}}\index{Platzhalter|see{Metazeichen}}\label{metazeichen} \section{Meta-Zeichen}\index{Meta-Zeichen|(textbf}\index{Wildcards|see{Metazeichen}}\index{Joker-Zeichen|see{Metazeichen}}\index{Platzhalter|see{Metazeichen}}\index{Globbing|see{Metazeichen}}\label{metazeichen}
\index{*=\texttt{*}|(textbf}\index{?=\texttt{?}|(textbf}\index{[abc]=\texttt{[}\textsl{abc}\texttt{]}|(textbf}\index{[a-q]=\texttt{[}\textsl{a}\texttt{-}\textsl{q}\texttt{]}|(textbf}\index{[!!abc]=\texttt{[!!}\textsl{abc}\texttt{]}|(textbf}\index{Dateinamen|(textbf} \index{*=\texttt{*}|(textbf}\index{?=\texttt{?}|(textbf}\index{[abc]=\texttt{[}\textsl{abc}\texttt{]}|(textbf}\index{[a-q]=\texttt{[}\textsl{a}\texttt{-}\textsl{q}\texttt{]}|(textbf}\index{[!!abc]=\texttt{[!!}\textsl{abc}\texttt{]}|(textbf}\index{Dateinamen|(textbf}
\index{\~{}=\texttt{\~{}}|(textbf}\index{\~{}name=\texttt{\~{}}\textsl{name}|(textbf}\index{\~{}+=\texttt{\~{}+}|(textbf}\index{\~{}-=\texttt{\~{}-}|(textbf} \index{\~{}=\texttt{\~{}}|(textbf}\index{\~{}name=\texttt{\~{}}\textsl{name}|(textbf}\index{\~{}+=\texttt{\~{}+}|(textbf}\index{\~{}-=\texttt{\~{}-}|(textbf}
Bei der Angabe von Dateinamen k<>nnen eine Reihe von Meta-Zeichen\footnote{Meta-Zeichen werden auch Wildcards, Joker-Zeichen oder Platzhalter genannt.} verwendet werden, um mehrere Dateien gleichzeitig anzusprechen oder um nicht den vollen Dateinamen ausschreiben zu m<>ssen. Bei der Angabe von Dateinamen k<>nnen eine Reihe von
Meta-Zeichen\footnote{Meta-Zeichen werden auch Wildcards, Joker-Zeichen oder
Platzhalter genannt. Meint man die Expansion der Meta-Zeichen zu Dateinamen ist
auch von `Globbing' die Rede.} verwendet werden, um mehrere Dateien
gleichzeitig anzusprechen oder um nicht den vollen Dateinamen ausschreiben zu
m<EFBFBD>ssen.
Die wichtigsten Meta-Zeichen sind:\nopagebreak Die wichtigsten Meta-Zeichen sind:\nopagebreak
\LTXtable{\textwidth}{tab_metazeichen.tex} \LTXtable{\textwidth}{tab_metazeichen.tex}
@ -317,10 +344,9 @@ das Suchmuster \texttt{.*}.
Man unterscheidet in der Shell-Programmierung zwischen den Man unterscheidet in der Shell-Programmierung zwischen den
Meta-Zeichen\index{Meta-Zeichen}, die bei der Bezeichnung von Dateinamen Meta-Zeichen\index{Meta-Zeichen}, die bei der Bezeichnung von Dateinamen
eingesetzt werden (sogenanntes `Globbing'\index{Globbing}) und den eingesetzt werden und den Meta-Zeichen, die in mehreren Programmen Verwendung
Meta-Zeichen, die in mehreren Programmen Verwendung finden, um z. B. Suchmuster finden, um z. B. Suchmuster zu definieren. Diese Muster werden auch regul<75>re
zu definieren. Diese Muster werden auch regul<75>re Ausdr<64>cke (regular Ausdr<EFBFBD>cke (regular expression)\index{Regular Expression|see{Regul<EFBFBD>rer
expression)\index{Regular Expression|see{Regul<EFBFBD>rer
Ausdruck}}\index{Expression|see{Regul<EFBFBD>rer Ausdruck}}\index{Expression|see{Regul<EFBFBD>rer
Ausdruck}}\index{Ausdruck|see{Regul<EFBFBD>rer Ausdruck}} genannt. Sie bieten Ausdruck}}\index{Ausdruck|see{Regul<EFBFBD>rer Ausdruck}} genannt. Sie bieten
wesentlich mehr M<>glichkeiten als die relativ einfachen Wildcards f<>r wesentlich mehr M<>glichkeiten als die relativ einfachen Wildcards f<>r
@ -491,9 +517,14 @@ der Bourne-Shell wirkt das f
Dieser Befehl tut nichts, au<61>er den Status 0 zur<75>ckzugeben. Er wird benutzt, um Endlosschleifen\index{Endlosschleife} zu schreiben (siehe unter \ref{while}), oder um leere Bl<42>cke in \texttt{if}- oder \texttt{case}-Konstrukten\index{if=\texttt{if}}\index{case=\texttt{case}} m<>glich zu machen. Dieser Befehl tut nichts, au<61>er den Status 0 zur<75>ckzugeben. Er wird benutzt, um Endlosschleifen\index{Endlosschleife} zu schreiben (siehe unter \ref{while}), oder um leere Bl<42>cke in \texttt{if}- oder \texttt{case}-Konstrukten\index{if=\texttt{if}}\index{case=\texttt{case}} m<>glich zu machen.
\medskip\emph{Beispiel:} Pr<50>fen, ob jemand angemeldet ist:\nopagebreak \begin{lstlisting}
\LTXtable{\textwidth}{tab_beisp_nullbefehl.tex} if who | grep $1 > /dev/null; then # who: Liste der Benutzer
\index{Null-Befehl|)} # grep: Suche nach Muster
: # tut nichts
else
echo "Benutzer $1 ist nicht angemeldet"
fi
\end{lstlisting}
\subsection{Source (\texttt{.})}\label{source}\index{source=\texttt{source}|(textbf}\index{.=\texttt{.}|see{source}} \subsection{Source (\texttt{.})}\label{source}\index{source=\texttt{source}|(textbf}\index{.=\texttt{.}|see{source}}