Viele Aenderungen
This commit is contained in:
parent
52635f366a
commit
68d30297e6
@ -16,10 +16,10 @@ Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunde
|
|||||||
\index{\^=\texttt{\^}}\index{Anführungszeichen}\index{Pipe}\index{grep=\texttt{grep}}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}}
|
\index{\^=\texttt{\^}}\index{Anfü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ührung erfolgreich
|
Das Skript führt also so lange das Kommando aus, bis die Ausführung erfolgreich
|
||||||
@ -42,10 +42,10 @@ Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das melde
|
|||||||
\index{\^=\texttt{\^}}\index{Anführungszeichen}\index{grep=\texttt{grep}}\index{Pipe}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}}
|
\index{\^=\texttt{\^}}\index{Anfü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ß die Mäuse tanzen!
|
echo "Die Katze ist aus dem Haus, Zeit, daß die Mäuse tanzen!"
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
Die Schleife wird nämlich dann so lange ausgeführt, bis \texttt{grep}\index{grep=\texttt{grep}} einen Fehler (bzw. eine erfolglose Suche) zurückmeldet.
|
Die Schleife wird nämlich dann so lange ausgeführt, bis \texttt{grep}\index{grep=\texttt{grep}} einen Fehler (bzw. eine erfolglose Suche) zurü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ß gesandt, das ihn bittet sich zu beenden. Dieses Signal heißt SIGINT (für SIGnal INTerrupt) und trägt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript sich temporäre Dateien angelegt hat, da diese nach der Ausführung nur noch unnötig Platz verbrauchen und eigentlich gelöscht werden sollten. Man kann sich sicher auch noch wichtigere Fälle vorstellen, in denen ein Skript bestimmte Aufgaben auf jeden Fall erledigen muß, 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ß gesandt, das ihn
|
||||||
|
bittet sich zu beenden. Dieses Signal heißt SIGINT (für SIGnal INTerrupt) und
|
||||||
|
trägt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript
|
||||||
|
sich temporäre Dateien angelegt hat, da diese nach der Ausführung nur noch
|
||||||
|
unnötig Platz verbrauchen und eigentlich gelöscht werden sollten. Man kann
|
||||||
|
sich sicher auch noch wichtigere Fälle vorstellen, in denen ein Skript
|
||||||
|
bestimmte Aufgaben auf jeden Fall erledigen muß, 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ücklicherweise verfügt die Shell ü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ücklicherweise verfügt die Shell ü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ä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ä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ä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ückliefern soll. Die Variable \texttt{temp} enthält den Namen für eine temporäre Datei. Dieser setzt sich zusammen aus \texttt{/tmp/zeige} und der Prozeßnummer des laufenden Skripts. So soll sichergestellt werden, daß noch keine Datei mit diesem Namen existiert.
|
Zunä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ückliefern soll. Die Variable \texttt{temp} enthält
|
||||||
|
den Namen für eine temporäre Datei. Dieser setzt sich zusammen aus
|
||||||
|
\texttt{/tmp/zeige} und der Prozeßnummer des laufenden Skripts. So soll
|
||||||
|
sichergestellt werden, daß noch keine Datei mit diesem Namen existiert.
|
||||||
|
|
||||||
\index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anführungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
|
\index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anfü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äre Datei gelöscht und der Wert aus der Variable \texttt{stat} als Exit-Code zurü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ßt, er wird bei jedem unnormalen Ende ausgeführt. Er gibt eine entsprechende Meldung auf die Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet, und der erste Trap wird ausgeführt.
|
Hier werden die Traps definiert. Bei Signal 0 wird die temporäre Datei gelöscht
|
||||||
|
und der Wert aus der Variable \texttt{stat} als Exit-Code zurü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ßt, er wird bei jedem unnormalen
|
||||||
|
Ende ausgeführt. Er gibt eine entsprechende Meldung auf die
|
||||||
|
Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet,
|
||||||
|
und der erste Trap wird ausgeführt.
|
||||||
|
|
||||||
\index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}\index{case=\texttt{case}}
|
\index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anfü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ät des Skriptes: Das \texttt{case}-Kommando (\ref{case}) testet die Anzahl der übergebenen Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} übergeben wurde, entpackt \texttt{zcat} die Datei, die im ersten Parameter\index{Parameter} angegeben wurde, in die temporä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ückgegeben wird.
|
Jetzt kommt die eigentliche Funktionalität des Skriptes: Das
|
||||||
|
\texttt{case}-Kommando (\ref{case}) testet die Anzahl der übergebenen
|
||||||
|
Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} übergeben
|
||||||
|
wurde, entpackt \texttt{zcat} die Datei, die im ersten
|
||||||
|
Parameter\index{Parameter} angegeben wurde, in die temporä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ückgegeben wird.
|
||||||
|
|
||||||
\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
|
\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anfü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|)}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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ächst der Inhalt des aktuellen Verzeichnisses `verpackt'. Das
|
Hier wird zunächst der Inhalt des aktuellen Verzeichnisses `verpackt'. Das
|
||||||
Resultat wird an die Standard-Ausgabe geschrieben. Auf der Empfängerseite der
|
Resultat wird an die Standard-Ausgabe geschrieben. Auf der Empfängerseite der
|
||||||
@ -57,9 +57,13 @@ Am Ziel-Ort finden sich jetzt die gleichen Dateien wie am Quell-Ort.
|
|||||||
Das ließe sich lokal natürlich auch anders lösen. Man könnte erst ein Archiv
|
Das ließe sich lokal natürlich auch anders lösen. Man könnte erst ein Archiv
|
||||||
erstellen, das dann an anderer Stelle wieder auspacken. Nachteil: Es muß
|
erstellen, das dann an anderer Stelle wieder auspacken. Nachteil: Es muß
|
||||||
genügend Platz für das Archiv vorhanden sein. Denkbar wäre auch ein in den Raum
|
genü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äß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äßt \texttt{tar}
|
||||||
|
beispielsweise nicht das File-System. Nützlich wenn nur eine Partition
|
||||||
gesichert werden soll.}, und die oben erwähnte Brücke wäre mit einem reinen
|
gesichert werden soll.}, und die oben erwähnte Brü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 ähnlich:
|
Der Weg in die andere Richtung ist ganz ä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über dem
|
Hier wird die Datei verpackt und versendet. Eine Besonderheit gegenüber dem
|
||||||
vorigen Beispiel bestehtdarin, daß das Zielverzeichnis bei Bedarf erstellt
|
vorigen Beispiel bestehtdarin, daß das Zielverzeichnis bei Bedarf erstellt
|
||||||
|
40
shell.tex
40
shell.tex
@ -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ände zwischen den Absätzen, statt
|
||||||
|
% Einrü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
|
||||||
|
%Übersicht zu diesem Thema haben wollte. Ich beabsichtige nicht, damit in
|
||||||
|
%irgendeiner Form Kommerz zu machen. Ich stelle es frei zur Verfügung, in der
|
||||||
|
%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
|
||||||
|
%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 über jede
|
aufmerksam zu machen. Auch abgesehen davon freue ich mich über jede
|
||||||
Rückmeldung.
|
Rückmeldung.\bigskip
|
||||||
|
|
||||||
|
Dieses Dokument entstand unter Verwendung von Linux, vim und \LaTeX. Dank an
|
||||||
|
deren Entwickler.
|
||||||
|
|
||||||
\normalsize
|
\normalsize
|
||||||
\newpage
|
\newpage
|
||||||
\pagenumbering{roman}
|
\pagenumbering{roman}
|
||||||
|
@ -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ührungszeichen}} \\
|
|
||||||
\multicolumn{2}{|X|}{\texttt{fi}} \\
|
|
||||||
\end{longtable}
|
|
@ -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
|
||||||
# über den Parameter -f eingebunden werden:
|
# und ü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ätze mit mehr als zwei Feldern auswählen:
|
# Datensätze mit mehr als zwei Feldern auswä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ält:
|
# den String 'WICHTIG' enthä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öße aller TeX-Dateien addieren, die Summe in kB umrechnen und ausgeben,
|
# Die Größ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öße aller TeX-Files beträgt", summe, "kB" }
|
END { summe /= 1024; print "Die Größe aller TeX-Files:", summe, "kB" }
|
||||||
|
|
||||||
# Pipe-Separierte Liste aller gemounteten Partitionen und derer Füllstände
|
# Pipe-Separierte Liste aller gemounteten Partitionen und derer
|
||||||
# ausgeben, verarbeitet die Ausgabe von 'df':
|
# Füllstä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äge in bzw. unter dem aktuellen Verzeichnis:
|
# Suche alle Einträ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äge außer symbolischen Links, in die jeder schreiben darf:
|
|
||||||
|
# Suche alle Einträge auß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öße 10000000 Bytes
|
|
||||||
# übersteigt und gib sie ausführlich aus:
|
# Suche alle Dateien unter dem Homeverzeichnis, deren Größe 10000000
|
||||||
|
# Bytes übersteigt und gib sie ausführlich aus:
|
||||||
find ~ -size +10000000c -exec ls -l {} \;
|
find ~ -size +10000000c -exec ls -l {} \;
|
||||||
# Suche alle Einträge im Homeverzeichnis, die innerhalb der letzten zwei Tage
|
|
||||||
# geändert wurden:
|
# Suche alle Einträge im Homeverzeichnis, die innerhalb der letzten zwei
|
||||||
|
# Tage geä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ß-ID 42:
|
# Die folgenden Befehle sind gleichwertig. Alle senden ein HUP an
|
||||||
|
# Prozeß-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ßbaum ausgeben. Das ist in Skripten weniger Sinnvoll, wird hier aber
|
# Prozeß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ührt werden soll, muß der Parameter -e
|
# Wenn mehr als ein Kommando ausgeführt werden soll, muß 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 über mehrere Zeilen gehen:
|
# In einem Skript kann das Kommando auch ü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
|
||||||
# über den Parameter -f eingebunden werden:
|
# und ü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ängen löschen:
|
# Führende Blanks (Leerzeichen, Tabulatoren) von den Zeilenanfängen
|
||||||
# ACHTUNG: An Stelle des \t muß der Tabulator gedrückt werden, die Darstellung
|
# löschen:
|
||||||
# als \t versteht nicht jedes sed!
|
# ACHTUNG: An Stelle des \t muß der Tabulator gedrü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ührliche Erklärung.
|
sich auch nochmal eine ausführliche Erklärung.
|
||||||
|
|
||||||
|
Ein weiterer nützlicher Einsatz für \texttt{trap} ist es, Signale zu
|
||||||
|
ignorieren. Das kann gewünscht sein, wenn eine Folge von Kommandos in einem
|
||||||
|
Skript auf keinen Fall unterbrochen werden darf. Um zu verhindern daß 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über freundlicher, auf das
|
||||||
|
entkrä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ührten Kommando der Trap ausgelöst. Dieses
|
||||||
|
Feature wird wie der Name schon erahnen läßt zum Debuggen benutzt, ein Beispiel
|
||||||
|
findet sich in Abschnitt \ref{fehlersuche}.
|
||||||
|
|
||||||
\index{trap=\texttt{trap}|)}
|
\index{trap=\texttt{trap}|)}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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ügt man
|
Es gibt für Shell-Skripte keine wirklichen Debugger, aber trotzdem verfügt man
|
||||||
über einige bewährte Methoden zum Aufspüren von Fehlern:
|
über einige bewährte Methoden zum Aufspüren von Fehlern:
|
||||||
@ -86,6 +86,18 @@ Aufruf
|
|||||||
Zeile vor der Ausführung aus, allerdings im Gegensatz zu \texttt{-x} nicht in
|
Zeile vor der Ausfü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ückgabewert, der Auskunft über Erfolg oder Miß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ü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ände
|
aber gerade in unbeobachtet laufenden Skripten sollte man unerwartete Zustä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ßfreien Blick auf unter Umstä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ß mit dem folgenden Kommando dafür gesorgt werden kann, daß 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ückgabewerte}\label{exitcode}\index{Rückgabewert|(textbf}\index{Exit-Code|see{Rückgabewert}}\index{Exit-Status|see{Rückgabewert}}
|
\section{Rückgabewerte}\label{exitcode}\index{Rückgabewert|(textbf}\index{Exit-Code|see{Rückgabewert}}\index{Exit-Status|see{Rü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ü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äre
|
||||||
zu definieren. Diese Muster werden auch reguläre Ausdrücke (regular
|
Ausdrücke (regular expression)\index{Regular Expression|see{Regulärer
|
||||||
expression)\index{Regular Expression|see{Regulärer
|
|
||||||
Ausdruck}}\index{Expression|see{Regulärer
|
Ausdruck}}\index{Expression|see{Regulärer
|
||||||
Ausdruck}}\index{Ausdruck|see{Regulärer Ausdruck}} genannt. Sie bieten
|
Ausdruck}}\index{Ausdruck|see{Regulä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ßer den Status 0 zurückzugeben. Er wird benutzt, um Endlosschleifen\index{Endlosschleife} zu schreiben (siehe unter \ref{while}), oder um leere Blö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ßer den Status 0 zurückzugeben. Er wird benutzt, um Endlosschleifen\index{Endlosschleife} zu schreiben (siehe unter \ref{while}), oder um leere Blöcke in \texttt{if}- oder \texttt{case}-Konstrukten\index{if=\texttt{if}}\index{case=\texttt{case}} möglich zu machen.
|
||||||
|
|
||||||
\medskip\emph{Beispiel:} Prü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}}
|
||||||
|
Loading…
Reference in New Issue
Block a user