Umformatiert
This commit is contained in:
parent
15af99f29e
commit
464f0bcf77
310
beispiele.tex
310
beispiele.tex
@ -13,34 +13,40 @@ Angenommen, bei der Benutzung eines Rechners tritt ein Problem auf, bei dem nur
|
|||||||
|
|
||||||
Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunden automatisch überprüft, ob der Admin angemeldet ist. Wir erreichen das mit dem folgenden Code:
|
Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunden automatisch überprüft, ob der Admin angemeldet ist. Wir erreichen das mit dem folgenden Code:
|
||||||
|
|
||||||
\footnotesize
|
|
||||||
\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{listing}[2]{1}
|
\begin{lstlisting}
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
until who | grep "^root "
|
until who | grep "^root "
|
||||||
do sleep 30
|
do sleep 30
|
||||||
done
|
done
|
||||||
echo Big Brother is watching you!
|
echo Big Brother is watching you!
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Das Skript führt also so lange das Kommando aus, bis die Ausführung erfolgreich war. Dabei wird die Ausgabe von \texttt{who}\index{who=\texttt{who}} mit einer Pipe (\ref{datenstrom}) in das \texttt{grep}\index{grep=\texttt{grep}}-Kommando umgeleitet. Dieses sucht darin nach einem Auftreten von `\texttt{root~}' am Zeilenanfang. Der Rückgabewert von \texttt{grep}\index{grep=\texttt{grep}} ist 0 wenn das Muster\index{Mustererkennung} gefunden wird, 1 wenn es nicht gefunden wird und 2 wenn ein Fehler auftrat. Damit der Rechner nicht die ganze Zeit mit dieser Schleife beschäftigt ist, wird im Schleifenkörper ein \texttt{sleep 30}\index{sleep=\texttt{sleep}} ausgeführt, um den Prozeß für 30 Sekunden schlafen zu schicken. Sobald der Admin sich eingeloggt hat, wird eine entsprechende Meldung ausgegeben.
|
Das Skript führt also so lange das Kommando aus, bis die Ausführung erfolgreich
|
||||||
|
war. Dabei wird die Ausgabe von \texttt{who}\index{who=\texttt{who}} mit einer
|
||||||
|
Pipe (\ref{datenstrom}) in das \texttt{grep}\index{grep=\texttt{grep}}-Kommando
|
||||||
|
umgeleitet. Dieses sucht darin nach einem Auftreten von `\texttt{root~}' am
|
||||||
|
Zeilenanfang. Der Rückgabewert von \texttt{grep}\index{grep=\texttt{grep}} ist
|
||||||
|
0 wenn das Muster\index{Mustererkennung} gefunden wird, 1 wenn es nicht
|
||||||
|
gefunden wird und 2 wenn ein Fehler auftrat. Damit der Rechner nicht die ganze
|
||||||
|
Zeit mit dieser Schleife beschäftigt ist, wird im Schleifenkörper ein
|
||||||
|
\lstinline|sleep 30|\index{sleep=\texttt{sleep}} ausgeführt, um den Prozeß für
|
||||||
|
30 Sekunden schlafen zu schicken. Sobald der Admin sich eingeloggt hat, wird
|
||||||
|
eine entsprechende Meldung ausgegeben.
|
||||||
|
|
||||||
|
|
||||||
\subsection{Schleife, bis ein Kommando erfolglos war}
|
\subsection{Schleife, bis ein Kommando erfolglos war}
|
||||||
|
|
||||||
Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das meldet, sobald sich ein Benutzer abgemeldet hat. Dazu ersetzen wir nur die \texttt{until}- Schleife durch eine entsprechende \texttt{while}-Schleife:
|
Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das meldet, sobald sich ein Benutzer abgemeldet hat. Dazu ersetzen wir nur die \texttt{until}- Schleife durch eine entsprechende \texttt{while}-Schleife:
|
||||||
|
|
||||||
\footnotesize
|
|
||||||
\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{listing}[2]{1}
|
\begin{lstlisting}
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
while who | grep "^root "
|
while who | grep "^root "
|
||||||
do sleep 30
|
do 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{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@ -49,8 +55,7 @@ Die Schleife wird n
|
|||||||
|
|
||||||
\texttt{cat datei.txt | while read i}
|
\texttt{cat datei.txt | while read i}
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
count=0
|
count=0
|
||||||
cat /etc/passwd | while read i; do
|
cat /etc/passwd | while read i; do
|
||||||
@ -61,8 +66,7 @@ cat /etc/passwd | while read i; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
TODO!!! Daten aus Subshell hochreichen
|
TODO!!! Daten aus Subshell hochreichen
|
||||||
|
|
||||||
@ -76,19 +80,16 @@ Das Skript mu
|
|||||||
|
|
||||||
Das Ergebnis der Ausführung wird mit Funktionen\index{Funktion} dargestellt, die aus der Datei \texttt{/etc/rc.d/init.d/functions} stammen. Ebenfalls in dieser Datei sind Funktionen, die einen Dienst starten oder stoppen.
|
Das Ergebnis der Ausführung wird mit Funktionen\index{Funktion} dargestellt, die aus der Datei \texttt{/etc/rc.d/init.d/functions} stammen. Ebenfalls in dieser Datei sind Funktionen, die einen Dienst starten oder stoppen.
|
||||||
|
|
||||||
\begin{flushright}
|
|
||||||
Zunächst wird festgelegt, daß dieses Skript in der Bourne-Shell ausgeführt werden soll (\ref{auswahl_der_shell}).
|
Zunächst wird festgelegt, daß dieses Skript in der Bourne-Shell ausgeführt werden soll (\ref{auswahl_der_shell}).
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
\end{listing}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Dann folgen Kommentare\index{Kommentar}, die den Sinn des Skriptes erläutern (\ref{kommentare}).
|
Dann folgen Kommentare\index{Kommentar}, die den Sinn des Skriptes erläutern (\ref{kommentare}).
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
\begin{lstlisting}[firstnumber=last]
|
||||||
\begin{listingcont}
|
|
||||||
#
|
#
|
||||||
# Startup script for the Apache Web Server
|
# Startup script for the Apache Web Server
|
||||||
#
|
#
|
||||||
@ -100,119 +101,109 @@ Dann folgen Kommentare\index{Kommentar}, die den Sinn des Skriptes erl
|
|||||||
# config: /etc/httpd/conf/access.conf
|
# config: /etc/httpd/conf/access.conf
|
||||||
# config: /etc/httpd/conf/httpd.conf
|
# config: /etc/httpd/conf/httpd.conf
|
||||||
# config: /etc/httpd/conf/srm.conf
|
# config: /etc/httpd/conf/srm.conf
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Jetzt wird die Datei mit den Funktionen\index{Funktion} eingebunden (\ref{source}).
|
Jetzt wird die Datei mit den Funktionen\index{Funktion} eingebunden (\ref{source}).
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{source=\texttt{source}}
|
\index{source=\texttt{source}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
# Source function library.
|
# Source function library.
|
||||||
. /etc/rc.d/init.d/functions
|
. /etc/rc.d/init.d/functions
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Hier werden die Aufrufparameter ausgewertet (\ref{case}).
|
Hier werden die Aufrufparameter ausgewertet (\ref{case}).
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}\index{case=\texttt{case}}
|
\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}\index{case=\texttt{case}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
# See how we were called.
|
# See how we were called.
|
||||||
case "$1" in
|
case "$1" in
|
||||||
start)
|
start)
|
||||||
echo -n "Starting httpd: "
|
echo -n "Starting httpd: "
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Nachdem eine Meldung über den auszuführenden Vorgang ausgegeben wurde, wird die Funktion \texttt{daemon} aus der Funktionsbibliothek ausgeführt. Diese Funktion startet das Programm, dessen Name hier als Parameter\index{Parameter} übergeben wird. Dann gibt sie eine Meldung über den Erfolg aus.
|
Nachdem eine Meldung über den auszuführenden Vorgang ausgegeben wurde, wird die Funktion \texttt{daemon} aus der Funktionsbibliothek ausgeführt. Diese Funktion startet das Programm, dessen Name hier als Parameter\index{Parameter} übergeben wird. Dann gibt sie eine Meldung über den Erfolg aus.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
\begin{lstlisting}[firstnumber=last]
|
||||||
\begin{listingcont}
|
|
||||||
daemon httpd
|
daemon httpd
|
||||||
echo
|
echo
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Jetzt wird ein Lock-File\footnote{Ein Lock-File signalisiert anderen Prozessen, daß ein bestimmter Prozeß bereits gestartet ist. So kann ein zweiter Aufruf verhindert werden.} angelegt.
|
Jetzt wird ein Lock-File\footnote{Ein Lock-File signalisiert anderen Prozessen, daß ein bestimmter Prozeß bereits gestartet ist. So kann ein zweiter Aufruf verhindert werden.} angelegt.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{Anführungszeichen}\index{touch=\texttt{touch}}
|
\index{Anführungszeichen}\index{touch=\texttt{touch}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
touch /var/lock/subsys/httpd
|
touch /var/lock/subsys/httpd
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
echo -n "Shutting down http: "
|
echo -n "Shutting down http: "
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Hier passiert im Prinzip das gleiche wie oben, nur daß mit der Funktion \texttt{killproc} der Daemon angehalten wird.
|
Hier passiert im Prinzip das gleiche wie oben, nur daß mit der Funktion \texttt{killproc} der Daemon angehalten wird.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
\begin{lstlisting}[firstnumber=last]
|
||||||
\begin{listingcont}
|
|
||||||
killproc httpd
|
killproc httpd
|
||||||
echo
|
echo
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Danach werden Lock-File und PID-File\footnote{In einem sogenannten PID-File hinterlegen einige Prozesse ihre Prozeß-ID, um anderen Programmen den Zugriff zu erleichtern (z. B. um den Prozeß anzuhalten etc).} gelöscht.
|
Danach werden Lock-File und PID-File\footnote{In einem sogenannten PID-File hinterlegen einige Prozesse ihre Prozeß-ID, um anderen Programmen den Zugriff zu erleichtern (z. B. um den Prozeß anzuhalten etc).} gelöscht.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
\begin{lstlisting}[firstnumber=last]
|
||||||
\begin{listingcont}
|
|
||||||
rm -f /var/lock/subsys/httpd
|
rm -f /var/lock/subsys/httpd
|
||||||
rm -f /var/run/httpd.pid
|
rm -f /var/run/httpd.pid
|
||||||
;;
|
;;
|
||||||
status)
|
status)
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Die Funktion \texttt{status} stellt fest, ob der entsprechende Daemon bereits läuft, und gibt das Ergebnis aus.
|
Die Funktion \texttt{status} stellt fest, ob der entsprechende Daemon bereits läuft, und gibt das Ergebnis aus.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
\begin{lstlisting}[firstnumber=last]
|
||||||
\begin{listingcont}
|
|
||||||
status httpd
|
status httpd
|
||||||
;;
|
;;
|
||||||
restart)
|
restart)
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Bei Aufruf mit dem Parameter\index{Parameter} \textsl{restart} ruft sich das Skript zwei mal selbst auf (in \texttt{\$0} steht der Aufrufname des laufenden Programms). Einmal, um den Daemon zu stoppen, dann, um ihn wieder zu starten.
|
Bei Aufruf mit dem Parameter\index{Parameter} \textsl{restart} ruft sich das Skript zwei mal selbst auf (in \texttt{\$0} steht der Aufrufname des laufenden Programms). Einmal, um den Daemon zu stoppen, dann, um ihn wieder zu starten.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}
|
\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
$0 stop
|
$0 stop
|
||||||
$0 start
|
$0 start
|
||||||
;;
|
;;
|
||||||
reload)
|
reload)
|
||||||
echo -n "Reloading httpd: "
|
echo -n "Reloading httpd: "
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Hier sendet die \texttt{killproc}-Funktion dem Daemon ein Signal\index{Signal} das ihm sagt, daß er seine Konfiguration neu einlesen soll.
|
Hier sendet die \texttt{killproc}-Funktion dem Daemon ein Signal\index{Signal} das ihm sagt, daß er seine Konfiguration neu einlesen soll.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}
|
\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
killproc httpd -HUP
|
killproc httpd -HUP
|
||||||
echo
|
echo
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Usage: $0 {start|stop|restart|reload|status}"
|
echo "Usage: $0 {start|stop|restart|reload|status}"
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Bei aufruf mit einem beliebigen anderen Parameter\index{Parameter} wird eine Kurzhilfe ausgegeben. Dann wird dafür gesorgt, daß das Skript mit dem Exit-Code 1 beendet wird. So kann festgestellt werden, ob das Skript ordnungsgemäß beendet wurde (\ref{exit}).
|
Bei aufruf mit einem beliebigen anderen Parameter\index{Parameter} wird eine Kurzhilfe ausgegeben. Dann wird dafür gesorgt, daß das Skript mit dem Exit-Code 1 beendet wird. So kann festgestellt werden, ob das Skript ordnungsgemäß beendet wurde (\ref{exit}).
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{exit=\texttt{exit}}
|
\index{exit=\texttt{exit}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
exit 1
|
exit 1
|
||||||
esac
|
esac
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
\section{Parameterübergabe in der Praxis}\label{beisp_parameter}\index{Parameter}
|
\section{Parameterübergabe in der Praxis}\label{beisp_parameter}\index{Parameter}
|
||||||
@ -221,21 +212,19 @@ Es kommt in der Praxis sehr oft vor, da
|
|||||||
|
|
||||||
Das soll an folgendem Skript verdeutlicht werden. Das Skript kennt die Optionen \texttt{-a} und \texttt{-b}. Letzterer Option muß ein zusätzlicher Wert mitgegeben werden. Alle anderen Parameter\index{Parameter} werden als Dateinamen interpretiert.
|
Das soll an folgendem Skript verdeutlicht werden. Das Skript kennt die Optionen \texttt{-a} und \texttt{-b}. Letzterer Option muß ein zusätzlicher Wert mitgegeben werden. Alle anderen Parameter\index{Parameter} werden als Dateinamen interpretiert.
|
||||||
|
|
||||||
\footnotesize
|
|
||||||
\index{\$@=\texttt{\$@}}\index{Anführungszeichen}\index{Backticks}\index{!|!|=\texttt{!|!|}}\index{getopt=\texttt{getopt}}\index{OR}\index{set=\texttt{set}}
|
\index{\$@=\texttt{\$@}}\index{Anführungszeichen}\index{Backticks}\index{!|!|=\texttt{!|!|}}\index{getopt=\texttt{getopt}}\index{OR}\index{set=\texttt{set}}
|
||||||
\begin{listing}[2]{1}
|
\begin{lstlisting}
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -- `getopt "ab:" "$@"` || {
|
set -- `getopt "ab:" "$@"` || {
|
||||||
\end{listing}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Das \texttt{set}\index{set=\texttt{set}}-Kommando belegt den Inhalt der vordefinierten Variablen (\ref{vordefinierte_variablen}) neu, so daß es aussieht, als ob dem Skript die Rückgabewerte von \texttt{getopt}\index{getopt=\texttt{getopt}} übergeben wurden. Man muß die beiden Minuszeichen angeben, da sie dafür sorgen, daß die Aufrufparameter an \texttt{getopt}\index{getopt=\texttt{getopt}} und nicht an die Shell selbst übergeben werden. Die originalen Parameter\index{Parameter} werden von \texttt{getopt}\index{getopt=\texttt{getopt}} untersucht und modifiziert zurückgegeben: \texttt{a} und \texttt{b} werden als Parameter\index{Parameter} Markiert, \texttt{b} sogar mit der Möglichkeit einer zusätzlichen Angabe.
|
Das \texttt{set}\index{set=\texttt{set}}-Kommando belegt den Inhalt der vordefinierten Variablen (\ref{vordefinierte_variablen}) neu, so daß es aussieht, als ob dem Skript die Rückgabewerte von \texttt{getopt}\index{getopt=\texttt{getopt}} übergeben wurden. Man muß die beiden Minuszeichen angeben, da sie dafür sorgen, daß die Aufrufparameter an \texttt{getopt}\index{getopt=\texttt{getopt}} und nicht an die Shell selbst übergeben werden. Die originalen Parameter\index{Parameter} werden von \texttt{getopt}\index{getopt=\texttt{getopt}} untersucht und modifiziert zurückgegeben: \texttt{a} und \texttt{b} werden als Parameter\index{Parameter} Markiert, \texttt{b} sogar mit der Möglichkeit einer zusätzlichen Angabe.
|
||||||
|
|
||||||
Wenn dieses Kommando fehlschlägt ist das ein Zeichen dafür, daß falsche Parameter\index{Parameter} übergeben wurden. Also wird nach einer entsprechenden Meldung das Programm mit Exit-Code 1 verlassen.
|
Wenn dieses Kommando fehlschlägt ist das ein Zeichen dafür, daß falsche Parameter\index{Parameter} übergeben wurden. Also wird nach einer entsprechenden Meldung das Programm mit Exit-Code 1 verlassen.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{\$n=\texttt{\$}$n$}\index{Null-Befehl}\index{!>\&=\texttt{!>\&}}\index{!==\texttt{!=}}\index{Anführungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
|
\index{\$n=\texttt{\$}$n$}\index{Null-Befehl}\index{!>\&=\texttt{!>\&}}\index{!==\texttt{!=}}\index{Anführungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
echo "Anwendung: `basename $0` [-a] [-b Name] Dateien" 1>&2
|
echo "Anwendung: `basename $0` [-a] [-b Name] Dateien" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
@ -243,41 +232,38 @@ echo "Momentan steht in der Kommandozeile folgendes: $*"
|
|||||||
aflag=0 name=NONE
|
aflag=0 name=NONE
|
||||||
while :
|
while :
|
||||||
do
|
do
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
In einer Endlosschleife\index{Endlosschleife}, die man mit Hilfe des Null-Befehls (\texttt{:}, \ref{null-befehl}) baut, werden die `neuen' Parameter\index{Parameter} der Reihe nach untersucht. Wenn ein \texttt{-a} vorkommt, wird die Variable \texttt{aflag} gesetzt. Bei einem \texttt{-b} werden per \texttt{shift}\index{shift=\texttt{shift}} alle Parameter\index{Parameter} nach Links verschoben, dann wird der Inhalt des nächsten Parameters\index{Parameter} in der Variablen \texttt{name} gesichert.
|
In einer Endlosschleife\index{Endlosschleife}, die man mit Hilfe des Null-Befehls (\texttt{:}, \ref{null-befehl}) baut, werden die `neuen' Parameter\index{Parameter} der Reihe nach untersucht. Wenn ein \texttt{-a} vorkommt, wird die Variable \texttt{aflag} gesetzt. Bei einem \texttt{-b} werden per \texttt{shift}\index{shift=\texttt{shift}} alle Parameter\index{Parameter} nach Links verschoben, dann wird der Inhalt des nächsten Parameters\index{Parameter} in der Variablen \texttt{name} gesichert.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{!==\texttt{!=}}\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}\index{case=\texttt{case}}\index{shift=\texttt{shift}}
|
\index{!==\texttt{!=}}\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}\index{case=\texttt{case}}\index{shift=\texttt{shift}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-a) aflag=1 ;;
|
-a) aflag=1 ;;
|
||||||
-b) shift; name="$1" ;;
|
-b) shift; name="$1" ;;
|
||||||
--) break ;;
|
--) break ;;
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Wenn ein \texttt{-{}-} erscheint, ist das ein Hinweis darauf, daß die Liste der Parameter\index{Parameter} abgearbeitet ist. Dann wird per \texttt{break}\index{break=\texttt{break}} (\ref{break}) die Endlosschleife unterbrochen. Die Aufrufparameter enthalten jetzt nur noch die eventuell angegebenen Dateinamen, die jetzt von dem Restlichen Skript wie gewohnt weiterverarbeitet werden können.
|
Wenn ein \texttt{-{}-} erscheint, ist das ein Hinweis darauf, daß die Liste der Parameter\index{Parameter} abgearbeitet ist. Dann wird per \texttt{break}\index{break=\texttt{break}} (\ref{break}) die Endlosschleife unterbrochen. Die Aufrufparameter enthalten jetzt nur noch die eventuell angegebenen Dateinamen, die jetzt von dem Restlichen Skript wie gewohnt weiterverarbeitet werden können.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{shift=\texttt{shift}}
|
\index{shift=\texttt{shift}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
shift
|
shift
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Am Ende werden die Feststellungen ausgegeben.
|
Am Ende werden die Feststellungen ausgegeben.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{\$*=\texttt{\$*}}\index{Anführungszeichen}
|
\index{\$*=\texttt{\$*}}\index{Anführungszeichen}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
echo "aflag=$aflag / Name = $name / Die Dateien sind $*"
|
echo "aflag=$aflag / Name = $name / Die Dateien sind $*"
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
\section{Fallensteller: Auf Traps
|
\section{Fallensteller: Auf Traps
|
||||||
@ -293,50 +279,45 @@ Wie l
|
|||||||
|
|
||||||
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.
|
||||||
|
|
||||||
\footnotesize
|
|
||||||
\index{!==\texttt{!=}}
|
\index{!==\texttt{!=}}
|
||||||
\begin{listing}[2]{1}
|
\begin{lstlisting}
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
stat=1
|
stat=1
|
||||||
temp=/tmp/zeige$$
|
temp=/tmp/zeige$$
|
||||||
\end{listing}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
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.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\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{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
trap 'rm -f $temp; exit $stat' 0
|
trap 'rm -f $temp; exit $stat' 0
|
||||||
trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15
|
trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
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.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\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{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
case $# in
|
case $# in
|
||||||
1) zcat "$1" > $temp
|
1) zcat "$1" > $temp
|
||||||
pg $temp
|
pg $temp
|
||||||
stat=0
|
stat=0
|
||||||
;;
|
;;
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
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.
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\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{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
*) echo "Anwendung: `basename $0` Dateiname" 1>&2
|
*) echo "Anwendung: `basename $0` Dateiname" 1>&2
|
||||||
esac
|
esac
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
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.
|
||||||
\end{flushright}
|
|
||||||
\index{trap=\texttt{trap}|)}\index{Signal|)}
|
\index{trap=\texttt{trap}|)}\index{Signal|)}
|
||||||
|
|
||||||
|
|
||||||
@ -358,27 +339,25 @@ Zwecke noch etwas `bereinigt' werden.
|
|||||||
|
|
||||||
Wie das aussieht, wenn es fertig ist, sieht man im folgenden Skript:
|
Wie das aussieht, wenn es fertig ist, sieht man im folgenden Skript:
|
||||||
|
|
||||||
\footnotesize
|
|
||||||
\index{!==\texttt{!=}}
|
\index{!==\texttt{!=}}
|
||||||
\begin{listing}[2]{1}
|
\begin{lstlisting}
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
for i in `find $1 -type f -name "*.[mM][pP]3"`; do
|
for i in `find $1 -type f -name "*.[mM][pP]3"`; do
|
||||||
\end{listing}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Hier beginnt eine Schleife, die über alle Ausgaben des \texttt{find}-Kommandos
|
Hier beginnt eine Schleife, die über alle Ausgaben des \texttt{find}-Kommandos
|
||||||
iteriert. Dabei sucht \texttt{find} nach allen normalen Dateien (\texttt{-type
|
iteriert. Dabei sucht \texttt{find} nach allen normalen Dateien (\texttt{-type
|
||||||
f}), die die Extension .mp3 tragen (\texttt{-name \dq*.[mM][pP]3\dq} -- wir
|
f}), die die Extension .mp3 tragen (\texttt{-name \dq*.[mM][pP]3\dq} -- wir
|
||||||
ignorieren Groß- / Kleinschreibung).
|
ignorieren Groß- / Kleinschreibung).
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{find=\texttt{find}}
|
\index{find=\texttt{find}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
echo `tr -dc "[:alpha:]" < /dev/urandom | \
|
echo `tr -dc "[:alpha:]" < /dev/urandom | \
|
||||||
dd count=8 bs=1 2> /dev/null`$i
|
dd count=8 bs=1 2> /dev/null`$i
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Hier ist der `magische Teil'. Mit dem \texttt{echo} wird die Ausgabe einer Pipe
|
Hier ist der `magische Teil'. Mit dem \texttt{echo} wird die Ausgabe einer Pipe
|
||||||
ausgegeben, gefolgt von dem aktuellen Dateinamen. Diese Pipe enthält ein
|
ausgegeben, gefolgt von dem aktuellen Dateinamen. Diese Pipe enthält ein
|
||||||
\texttt{tr}, der alle ungewollten Zeichen (alles, was kein Textzeichen ist) aus
|
\texttt{tr}, der alle ungewollten Zeichen (alles, was kein Textzeichen ist) aus
|
||||||
@ -391,14 +370,13 @@ Kommando \texttt{dd} mit den angegebenen Parametern. Damit die Erfolgsmeldung
|
|||||||
von \texttt{dd} nicht die Ausgabe verunstaltet, lenken wir sie nach
|
von \texttt{dd} nicht die Ausgabe verunstaltet, lenken wir sie nach
|
||||||
\texttt{/dev/null} um.
|
\texttt{/dev/null} um.
|
||||||
\index{tr=\texttt{tr}}\index{dd=\texttt{dd}}
|
\index{tr=\texttt{tr}}\index{dd=\texttt{dd}}
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{find=\texttt{find}}
|
\index{find=\texttt{find}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
done | sort | cut -b 9- | while read i; do
|
done | sort | cut -b 9- | while read i; do
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
\begin{flushright}
|
|
||||||
Das Ergebnis der obigen Schleife ist also die Liste der Dateinamen, denen
|
Das Ergebnis der obigen Schleife ist also die Liste der Dateinamen, denen
|
||||||
jeweils acht zufällige Zeichen vorangestellt wurden. Die Reihenfolge entspricht
|
jeweils acht zufällige Zeichen vorangestellt wurden. Die Reihenfolge entspricht
|
||||||
allerdings immer noch der Ausgabe von \texttt{find}, wird also nach jedem
|
allerdings immer noch der Ausgabe von \texttt{find}, wird also nach jedem
|
||||||
@ -414,15 +392,15 @@ Diese lesen wir jetzt zeilenweise mittels \texttt{read} ein. In der
|
|||||||
\texttt{while}-Schleife können wir alle erforderlichen Sachen mit dem
|
\texttt{while}-Schleife können wir alle erforderlichen Sachen mit dem
|
||||||
Dateinamen anstellen. Hier wird er nur mittels \texttt{echo} ausgegeben.
|
Dateinamen anstellen. Hier wird er nur mittels \texttt{echo} ausgegeben.
|
||||||
\index{sort=\texttt{sort}}\index{cut=\texttt{cut}} \index{read=\texttt{read}}\index{while=\texttt{while}}
|
\index{sort=\texttt{sort}}\index{cut=\texttt{cut}} \index{read=\texttt{read}}\index{while=\texttt{while}}
|
||||||
\end{flushright}
|
|
||||||
\footnotesize
|
|
||||||
\index{find=\texttt{find}}
|
\index{find=\texttt{find}}
|
||||||
\begin{listingcont}
|
\begin{lstlisting}[firstnumber=last]
|
||||||
echo "Jetzt wird $i gespielt"
|
echo "Jetzt wird $i gespielt"
|
||||||
mpg123 "$i"
|
mpg123 "$i"
|
||||||
done
|
done
|
||||||
\end{listingcont}
|
|
||||||
\normalsize
|
\end{lstlisting}
|
||||||
|
|
||||||
\index{Zufallszahlen|)}
|
\index{Zufallszahlen|)}
|
||||||
|
|
||||||
|
|
||||||
@ -437,8 +415,7 @@ das Problem, da
|
|||||||
Prozeß läuft oder nicht. Im Normalfall wird er zuerst folgendes ausprobieren,
|
Prozeß läuft oder nicht. Im Normalfall wird er zuerst folgendes ausprobieren,
|
||||||
was aber oft (nicht immer) in die Hose gehen wird:
|
was aber oft (nicht immer) in die Hose gehen wird:
|
||||||
|
|
||||||
\texttt{ps aux | grep }\textit{prozessname}\texttt{ \&\& echo \dq}\textit{läuft
|
\lstinline/ps aux | grep prozessname && echo "läuft schon"/
|
||||||
schon}\texttt{\dq}
|
|
||||||
|
|
||||||
Der Grund dafür ist, daß unter Umständen in der Ausgabe von \texttt{ps} auch
|
Der Grund dafür ist, daß unter Umständen in der Ausgabe von \texttt{ps} auch
|
||||||
das \texttt{grep}-Kommando samt Parameter (\textit{prozessname}) aufgelistet
|
das \texttt{grep}-Kommando samt Parameter (\textit{prozessname}) aufgelistet
|
||||||
@ -447,8 +424,7 @@ wird. So findet das \texttt{grep}-Kom\-man\-do sich quasi selbst.
|
|||||||
Abhilfe schafft entweder \texttt{pgrep} (\ref{pgrep}) oder das folgende
|
Abhilfe schafft entweder \texttt{pgrep} (\ref{pgrep}) oder das folgende
|
||||||
Konstrukt:
|
Konstrukt:
|
||||||
|
|
||||||
\texttt{ps aux | grep \dq}\textit{[p]rozessname}\texttt{\dq~\&\& echo
|
\lstinline/ps aux | grep "[p]rozessname" && echo "läuft schon"/
|
||||||
\dq}\textit{läuft schon}\texttt{\dq}
|
|
||||||
|
|
||||||
Das p ist jetzt als eine Zeichenmenge (regulärer Ausdruck) angegeben worden.
|
Das p ist jetzt als eine Zeichenmenge (regulärer Ausdruck) angegeben worden.
|
||||||
Jetzt sucht \texttt{grep} also nach dem String \textit{prozessname}, in der
|
Jetzt sucht \texttt{grep} also nach dem String \textit{prozessname}, in der
|
||||||
@ -466,7 +442,7 @@ folgendes Szenario: Es gibt ein Verzeichnis mit vielen Unterverzeichnissen,
|
|||||||
denen eine Zeile mit dem Inhalt `strict' vorkommt. Man könnte jetzt
|
denen eine Zeile mit dem Inhalt `strict' vorkommt. Man könnte jetzt
|
||||||
folgendes versuchen:
|
folgendes versuchen:
|
||||||
|
|
||||||
\texttt{grep -r strict *}
|
\lstinline|grep -r strict *|
|
||||||
|
|
||||||
Das führt allerdings dazu, daß alle Dateien durchsucht werden, nicht nur die
|
Das führt allerdings dazu, daß alle Dateien durchsucht werden, nicht nur die
|
||||||
Perl-Skripte. Diese tragen nach unserer Konvention\footnote{Perl-Skripte müssen
|
Perl-Skripte. Diese tragen nach unserer Konvention\footnote{Perl-Skripte müssen
|
||||||
@ -474,14 +450,14 @@ keine spezielle Extension haben, es sei aber um des Beispiels Willen mal
|
|||||||
angenommen.} die Extension `.pl'. Wir starten also eine rekursive Suche über
|
angenommen.} die Extension `.pl'. Wir starten also eine rekursive Suche über
|
||||||
alle Dateien, die dem Muster entsprechen:
|
alle Dateien, die dem Muster entsprechen:
|
||||||
|
|
||||||
\texttt{grep -r strict *.pl}
|
\lstinline|grep -r strict *.pl|
|
||||||
|
|
||||||
Das führt wieder nicht zu dem gewünschten Ergebnis. Da die Unterverzeichnisse
|
Das führt wieder nicht zu dem gewünschten Ergebnis. Da die Unterverzeichnisse
|
||||||
nicht die Extension `*.pl' tragen, werden sie nicht berücksichtigt. Für die
|
nicht die Extension `*.pl' tragen, werden sie nicht berücksichtigt. Für die
|
||||||
Suche in Unterverzeichnissen ziehen wir \texttt{find} (Siehe Abschnitt
|
Suche in Unterverzeichnissen ziehen wir \texttt{find} (Siehe Abschnitt
|
||||||
\ref{find}) heran:
|
\ref{find}) heran:
|
||||||
|
|
||||||
\texttt{find . -name \textbackslash*.pl -exec grep \{\} \textbackslash;}
|
\lstinline|find . -name \*.pl -exec grep strict {} \;|
|
||||||
|
|
||||||
Dieser Befehl gibt uns zwar die gefundenen Zeilen aus, nicht aber die Namen der
|
Dieser Befehl gibt uns zwar die gefundenen Zeilen aus, nicht aber die Namen der
|
||||||
Dateien. Es sieht für \texttt{grep} so aus als ob nur eine Datei durchsucht
|
Dateien. Es sieht für \texttt{grep} so aus als ob nur eine Datei durchsucht
|
||||||
@ -490,7 +466,7 @@ Parameter \texttt{-l}, allerdings w
|
|||||||
angezeigt. Eine Ausgabe mit beiden Informationen erhalten wir mit dem folgenden
|
angezeigt. Eine Ausgabe mit beiden Informationen erhalten wir mit dem folgenden
|
||||||
Konstrukt:
|
Konstrukt:
|
||||||
|
|
||||||
\texttt{find . -name \textbackslash*.pl -exec grep strict /dev/null \{\} \textbackslash;}
|
\lstinline|find . -name \*.pl -exec grep strict /dev/null {} \;|
|
||||||
|
|
||||||
Hier durchsucht \texttt{grep} nicht nur die gefundenen Dateien, sondern bei
|
Hier durchsucht \texttt{grep} nicht nur die gefundenen Dateien, sondern bei
|
||||||
jedem Aufruf auch \texttt{/dev/null}, also den digitalen Mülleimer der per
|
jedem Aufruf auch \texttt{/dev/null}, also den digitalen Mülleimer der per
|
||||||
|
@ -57,8 +57,7 @@ z
|
|||||||
|
|
||||||
Folgendes Skript funktioniert nicht:
|
Folgendes Skript funktioniert nicht:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
count=0
|
count=0
|
||||||
cat /etc/passwd | while read i; do
|
cat /etc/passwd | while read i; do
|
||||||
@ -69,8 +68,7 @@ cat /etc/passwd | while read i; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Was ist passiert?
|
Was ist passiert?
|
||||||
|
|
||||||
@ -91,8 +89,7 @@ praktisch nur lokal zur Verf
|
|||||||
Neben der Methode in \ref{daten_hochreichen} bietet sich hier eine viel
|
Neben der Methode in \ref{daten_hochreichen} bietet sich hier eine viel
|
||||||
einfachere Lösung an:
|
einfachere Lösung an:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
count=0
|
count=0
|
||||||
while read i; do
|
while read i; do
|
||||||
@ -103,8 +100,7 @@ while read i; do
|
|||||||
fi
|
fi
|
||||||
done < /etc/passwd
|
done < /etc/passwd
|
||||||
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Hier befindet sich die Schleife nicht in einer Pipe, daher wird sie auch nicht
|
Hier befindet sich die Schleife nicht in einer Pipe, daher wird sie auch nicht
|
||||||
in einer Subshell ausgeführt. Man kann auf das \texttt{cat}-Kommando verzichten
|
in einer Subshell ausgeführt. Man kann auf das \texttt{cat}-Kommando verzichten
|
||||||
@ -124,7 +120,7 @@ enthalten.
|
|||||||
|
|
||||||
Der erste Versuch an der Stelle wird etwas in der Form
|
Der erste Versuch an der Stelle wird etwas in der Form
|
||||||
|
|
||||||
\texttt{grep }\textit{wichtig datei.txt}\texttt{ > }\textit{datei.txt}
|
\lstinline|grep wichtig datei.txt > datei.txt|
|
||||||
|
|
||||||
sein. Das kann funktionieren, es kann aber auch in die sprichwörtliche Hose
|
sein. Das kann funktionieren, es kann aber auch in die sprichwörtliche Hose
|
||||||
gehen. Das Problem an der Stelle ist, daß die Datei an der Stelle gleichzeitig
|
gehen. Das Problem an der Stelle ist, daß die Datei an der Stelle gleichzeitig
|
||||||
@ -136,15 +132,13 @@ Dateisystem entfernt, wenn kein Deskriptor mehr auf sie zeigt. Dann kann aus
|
|||||||
dem gerade angelegten Deskriptor gelesen werden, während eine neue Datei unter
|
dem gerade angelegten Deskriptor gelesen werden, während eine neue Datei unter
|
||||||
dem alten Namen angelegt wird:
|
dem alten Namen angelegt wird:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
FILE=datei.txt
|
FILE=datei.txt
|
||||||
exec 3< "$FILE"
|
exec 3< "$FILE"
|
||||||
rm "$FILE"
|
rm "$FILE"
|
||||||
grep "wichtig" <&3 > "$FILE"
|
grep "wichtig" <&3 > "$FILE"
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Allerdings sollte man bei dieser Methode beachten, daß man im Falle eines
|
Allerdings sollte man bei dieser Methode beachten, daß man im Falle eines
|
||||||
Fehlers die Quelldaten verliert, da die Datei ja bereits gelöscht wurde.
|
Fehlers die Quelldaten verliert, da die Datei ja bereits gelöscht wurde.
|
||||||
|
11
shell.tex
11
shell.tex
@ -45,6 +45,17 @@
|
|||||||
\usepackage{fancybox} % Kästchen für Tastendarstellung
|
\usepackage{fancybox} % Kästchen für Tastendarstellung
|
||||||
|
|
||||||
\usepackage{moreverb} % Für Listings
|
\usepackage{moreverb} % Für Listings
|
||||||
|
\usepackage{listings} % Für Listings
|
||||||
|
\lstset{
|
||||||
|
extendedchars=true,
|
||||||
|
backgroundcolor=\color[gray]{0.95},
|
||||||
|
basicstyle=\ttfamily\scriptsize,
|
||||||
|
numbers=left,
|
||||||
|
numberstyle=\tiny,
|
||||||
|
stepnumber=2,
|
||||||
|
numbersep=5pt
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
% Für PDF
|
% Für PDF
|
||||||
\usepackage[
|
\usepackage[
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
|
|
||||||
\texttt{-c} & Anzahl der Vorkommnisse vor die Zeilen schreiben \tabularnewline\STRUT
|
\texttt{-c} & Anzahl der Vorkommnisse vor die Zeilen schreiben \tabularnewline\STRUT
|
||||||
\texttt{-d} & Nur doppelte Zeilen ausgeben, jede nur einmal \tabularnewline\STRUT
|
\texttt{-d} & Nur doppelte Zeilen ausgeben, jede nur einmal \tabularnewline\STRUT
|
||||||
\texttt{-D} & Alle doppelten Zeilen ausgeben \tabularnewline\STRUT
|
\texttt{-D} & GNU-Erweiterung: Alle doppelten Zeilen ausgeben \tabularnewline\STRUT
|
||||||
\texttt{-f }\textsl{n} & Die ersten \textsl{n} Felder ignorieren \tabularnewline\STRUT
|
\texttt{-f }\textsl{n} & Die ersten \textsl{n} Felder ignorieren \tabularnewline\STRUT
|
||||||
\texttt{-i} & Groß- / Kleinschreibung ignorieren \tabularnewline\STRUT
|
\texttt{-i} & GNU-Erweiterung: Groß- / Kleinschreibung ignorieren \tabularnewline\STRUT
|
||||||
\texttt{-s }\textsl{n} & Die ersten \textsl{n} Zeichen ignorieren \tabularnewline\STRUT
|
\texttt{-s }\textsl{n} & Die ersten \textsl{n} Zeichen ignorieren \tabularnewline\STRUT
|
||||||
\texttt{-u} & Nur einfach vorkommende Zeilen ausgeben \tabularnewline\STRUT
|
\texttt{-u} & Nur einfach vorkommende Zeilen ausgeben \tabularnewline\STRUT
|
||||||
\texttt{-w }\textsl{n} & Nur die ersten \textsl{n} Zeichen betrachten
|
\texttt{-w }\textsl{n} & GNU-Erweiterung: Nur die ersten \textsl{n} Zeichen betrachten
|
||||||
\end{longtable}
|
\end{longtable}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
% $Id$
|
% $Id$
|
||||||
\chapter{Werkzeugkasten}\label{werkzeugkasten}
|
\chapter{Werkzeugkasten}\label{werkzeugkasten}
|
||||||
|
|
||||||
Durch die gezeigten Steuerungsmöglichkeiten stehen dem Shell-Pro\-grammie\-rer
|
Durch die gezeigten Steuerungsmöglichkeiten stehen dem Shell-Pro\-grammie\-rer
|
||||||
Mög\-lich\-kei\-ten offen, fast alle gängigen Algorithmen zu implementieren. Es
|
Mög\-lich\-kei\-ten offen, fast alle gängigen Algorithmen zu implementieren. Es
|
||||||
ist tatsächlich in der Shell möglich, Sortier- oder Suchfunktionen zu
|
ist tatsä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ählung der
|
kommenden Werkzeugen. Danach gibt es eine alphabetische Aufzählung der
|
||||||
wichtigsten Kommandos.
|
wichtigsten Kommandos.
|
||||||
|
|
||||||
|
Das GNU-Projekt\marginpar{GNU!} hat vielen Kommandos nützliche Parameter
|
||||||
|
zugefügt, einige der hier beschriebenen Tools stehen ausschließlich auf
|
||||||
|
GNU-Systemen zur Verfügung. Da diese Optionen nicht auf allen Unix-Systemen zur
|
||||||
|
Verfügung stehen, werden die betroffenen Stellen wie dieser Absatz am Rand mit
|
||||||
|
`GNU!' markiert. Wenn diese Kommandos und Optionen benutzt werden muß also das
|
||||||
|
Zielsystem berücksichtigt werden, im Zweifelsfall sollten die Skripte
|
||||||
|
ausführlich getestet werden.
|
||||||
|
|
||||||
\section{Nägel...}\label{naegel}
|
\section{Nägel...}\label{naegel}
|
||||||
|
|
||||||
\subsection{Ein- und Ausgabe}\label{ein_und_ausgabe}
|
\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{echo} (\ref{echo}): Daten ausgeben
|
||||||
\item \texttt{grep} (\ref{grep}): In Dateien suchen
|
\item \texttt{grep} (\ref{grep}): In Dateien suchen
|
||||||
\item \texttt{head} (\ref{head}): Dateianfang ausgeben
|
\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{printf} (\ref{printf}): Formatierte Datenausgabe
|
||||||
\item \texttt{read} (\ref{read}): Zeilen einlesen
|
\item \texttt{read} (\ref{read}): Zeilen einlesen
|
||||||
\item \texttt{tail} (\ref{tail}): Dateiende ausgeben
|
\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
|
Eingabedatei angegeben wird, wird diese verarbeitet. Ansonsten wird die
|
||||||
Standard-Eingabe gelesen. Ausgaben erfolgen immer auf der Standard-Ausgabe.
|
Standard-Eingabe gelesen. Ausgaben erfolgen immer auf der Standard-Ausgabe.
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
# Aufruf als Filter:
|
# Aufruf als Filter:
|
||||||
kommando1 | awk '{ print $1; print $2 }' | kommando2
|
kommando1 | awk '{ print $1; print $2 }' | kommando2
|
||||||
|
|
||||||
@ -233,15 +242,14 @@ awk '
|
|||||||
# Alternativ können die Kommandos auch in eine eigene Datei gespeichert und
|
# Alternativ können die Kommandos auch in eine eigene Datei gespeichert und
|
||||||
# über den Parameter -f eingebunden werden:
|
# über den Parameter -f eingebunden werden:
|
||||||
awk -f script.awk datei.txt
|
awk -f script.awk datei.txt
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Neben dem Parameter \texttt{-f} zum Einlesen der Programmdatei gibt es noch den
|
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
|
Parameter \texttt{-F} mit dem der Feld-Trenner angegeben werden kann. Die
|
||||||
folgende Zeile gibt beispielsweise alle Benutzernamen und deren User-IDs aus
|
folgende Zeile gibt beispielsweise alle Benutzernamen und deren User-IDs aus
|
||||||
der Doppelpunktseparierten Datei \texttt{/etc/passwd} 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}
|
\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:
|
Hier ein paar Einfache Beispiele für Blocks aus Mustern und Prozeduren:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
# Das erste Feld jeder Zeile ausgeben:
|
# Das erste Feld jeder Zeile ausgeben:
|
||||||
{ print $1 }
|
{ print $1 }
|
||||||
|
|
||||||
@ -335,8 +342,7 @@ END { summe /= 1024; print "Die Gr
|
|||||||
# ausgeben, verarbeitet die Ausgabe von 'df':
|
# ausgeben, verarbeitet die Ausgabe von 'df':
|
||||||
BEGIN { OFS="|" }
|
BEGIN { OFS="|" }
|
||||||
/^\/dev\// { print $1,$5 }
|
/^\/dev\// { print $1,$5 }
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
\index{awk=\texttt{awk}|)}
|
\index{awk=\texttt{awk}|)}
|
||||||
|
|
||||||
@ -377,17 +383,17 @@ an vielen, teilweise sehr unterschiedlich gelagerten Aufgaben wertvolle
|
|||||||
Dienste.
|
Dienste.
|
||||||
|
|
||||||
Durch Umlenklung der Ausgabe können Dateien erzeugt und erweitert werden. So
|
Durch Umlenklung der Ausgabe können Dateien erzeugt und erweitert werden. So
|
||||||
können mehrere Dateien per \texttt{cat datei1.txt datei2.txt > datei.txt}
|
können mehrere Dateien per \lstinline|cat datei1.txt datei2.txt > datei.txt|
|
||||||
verkettet werden.
|
verkettet werden.
|
||||||
|
|
||||||
Außerdem kann man mit einem Aufruf in der Art \texttt{cat datei.txt | kommando}
|
Außerdem kann man mit einem Aufruf in der Art
|
||||||
Daten an ein Programm übergeben, das nur von der Standardeingabe lesen kann
|
\lstinline|cat datei.txt | kommando| Daten an ein Programm übergeben, das nur
|
||||||
(Filter).
|
von der Standardeingabe lesen kann (Filter).
|
||||||
|
|
||||||
\texttt{cat} verfügt über eine Reihe von Parametern, um die Ausgabe zu
|
GNU-\texttt{cat}\marginpar{GNU!} verfügt über eine Reihe von Parametern, um die
|
||||||
formatieren, so können mit \texttt{-n} bzw. \texttt{-b} die Zeilen numeriert
|
Ausgabe zu formatieren, so können mit \texttt{-n} bzw. \texttt{-b} die Zeilen
|
||||||
werden, oder mit \texttt{-s} mehrere Zeilen zu einer einzigen zusammengefaßt
|
numeriert werden, oder mit \texttt{-s} mehrere Zeilen zu einer einzigen
|
||||||
werden.
|
zusammengefaßt werden.
|
||||||
|
|
||||||
\index{cat=\texttt{cat}|)}
|
\index{cat=\texttt{cat}|)}
|
||||||
|
|
||||||
@ -458,8 +464,9 @@ Zur Verdeutlichung ein paar Beispiele, wo es m
|
|||||||
|
|
||||||
\LTXtable{\textwidth}{tab_kommandos_chmod_beispiele.tex}
|
\LTXtable{\textwidth}{tab_kommandos_chmod_beispiele.tex}
|
||||||
|
|
||||||
Am wichtigsten sind also die Aufrufe \texttt{chmod 644 datei} und \texttt{chmod
|
Am wichtigsten sind also die Aufrufe \lstinline|chmod 644 datei| und
|
||||||
755 datei}, je nachdem ob die Datei ausführbar sein soll oder nicht.
|
\lstinline|chmod 755 datei|, je nachdem ob die Datei ausführbar sein soll oder
|
||||||
|
nicht.
|
||||||
|
|
||||||
\index{chmod=\texttt{chmod}|)}
|
\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ög\-lich\-keit, scriptgesteuert die Paßwörter für neue Benutzer zu vergeben.
|
Mög\-lich\-keit, scriptgesteuert die Paßwörter für neue Benutzer zu vergeben.
|
||||||
Manuell ändert man ein Paßwort mit dem Kommando
|
Manuell ändert man ein Paßwort mit dem Kommando
|
||||||
\texttt{passwd}\index{passwd=\texttt{passwd}}, allerdings löscht (flusht)
|
\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}
|
\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äßt sich die Ausgabe von Unterschieden unterdrü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}|)}
|
\index{cmp=\texttt{cmp}|)}
|
||||||
|
|
||||||
@ -552,7 +575,15 @@ Dateien in Spalten zusammengef
|
|||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{diff}\label{diff}\index{diff=\texttt{diff}|(textbf}
|
\subsection{diff}\label{diff}\index{diff=\texttt{diff}|(textbf}
|
||||||
|
|
||||||
TODO!!! diff
|
Mit \texttt{diff} werden zwei Dateien verglichen, und die Ä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änderten Stand zu bringen.
|
||||||
|
|
||||||
\index{diff=\texttt{diff}|)}
|
\index{diff=\texttt{diff}|)}
|
||||||
|
|
||||||
@ -602,7 +633,7 @@ Variablen zu bilden.
|
|||||||
|
|
||||||
Eine wichtige Anwendung für dieses Kommando ist der Fall, wenn eigentlich ein
|
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
|
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
|
werden, dabei ist \texttt{arr} der Name des Arrays und \texttt{index} der Name
|
||||||
der Variablen, die den Index des auszugebenden Elementes enthält.
|
der Variablen, die den Index des auszugebenden Elementes enthält.
|
||||||
|
|
||||||
@ -625,7 +656,7 @@ wichtigsten Operatoren lauten wie folgt:
|
|||||||
|
|
||||||
Bei einigen Sonderzeichen ist deren Bedeutung in der Shell zu berücksichtigen,
|
Bei einigen Sonderzeichen ist deren Bedeutung in der Shell zu berücksichtigen,
|
||||||
sie sind also durch Anführungszeichen oder Backslashes zu quoten:
|
sie sind also durch Anfü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
|
Eine andere Möglichkeit für einfache Rechnungen besteht in der sogenannten
|
||||||
Arith\-me\-tik-Ex\-pan\-sion (Siehe \ref{arithmetikexpansion}).
|
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
|
Da die reine Beschreibung der Parameter manchmal etwas verwirrend ist, folgen
|
||||||
hier ein paar praktische Beispiele:
|
hier ein paar praktische Beispiele:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
# 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:
|
||||||
@ -680,8 +710,7 @@ find ~ -size +10000000c -exec ls -l {} \;
|
|||||||
# Suche alle Einträge im Homeverzeichnis, die innerhalb der letzten zwei Tage
|
# Suche alle Einträge im Homeverzeichnis, die innerhalb der letzten zwei Tage
|
||||||
# geändert wurden:
|
# geändert wurden:
|
||||||
find ~ -mtime -2
|
find ~ -mtime -2
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Wenn mittels \texttt{-exec} weitere Kommandos gestartet werden, sollte beachtet
|
Wenn mittels \texttt{-exec} weitere Kommandos gestartet werden, sollte beachtet
|
||||||
werden daß mindestens ein Prozeß pro Fundstelle gestartet wird. Das kostet sehr
|
werden daß mindestens ein Prozeß 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
|
Es gibt verschiedene Wege, das Signal abzusetzen. Welchen man wählt ist
|
||||||
Geschmackssache. Hier ein paar Beispiele:
|
Geschmackssache. Hier ein paar Beispiele:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
# 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
|
||||||
@ -770,8 +798,7 @@ kill -9 -1
|
|||||||
|
|
||||||
# SIGTERM an mehrere Prozesse senden:
|
# SIGTERM an mehrere Prozesse senden:
|
||||||
kill 123 456 789
|
kill 123 456 789
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Siehe auch: Das Beispiel `Fallensteller' in Abschnitt \ref{traps} zeigt, wie
|
Siehe auch: Das Beispiel `Fallensteller' in Abschnitt \ref{traps} zeigt, wie
|
||||||
ein Skript auf Signale reagieren kann.
|
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 über \texttt{kill} (\ref{kill}) wird beschrieben, wie man ein
|
Im Abschnitt über \texttt{kill} (\ref{kill}) wird beschrieben, wie man ein
|
||||||
Signal an einen Prozeß schickt, dessen ID bekannt ist. Kennt man die ID nicht,
|
Signal an einen Prozeß schickt, dessen ID bekannt ist. Kennt man die ID nicht,
|
||||||
oder will man das Signal an mehrere Prozesse schicken, kann dieses Kommando
|
oder will man das Signal an mehrere Prozesse schicken, kann dieses Kommando auf
|
||||||
eine große Hilfe darstellen.
|
GNU-Systemen eine große Hilfe darstellen.
|
||||||
|
|
||||||
Mit dem Parameter \texttt{-i} wird vor jedem Signal interaktiv gefragt, ob es
|
Mit dem Parameter \texttt{-i} wird vor jedem Signal interaktiv gefragt, ob es
|
||||||
geschickt werden soll. Mit \texttt{-v} wird angegeben, ob die Signale
|
geschickt werden soll. Mit \texttt{-v} wird angegeben, ob die Signale
|
||||||
@ -803,6 +830,22 @@ zur Verf
|
|||||||
\index{killall=\texttt{killall}|)}
|
\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 über ihr tun
|
||||||
|
informieren.
|
||||||
|
|
||||||
|
Der zu loggende Text wird einfach als Parameter übergeben.
|
||||||
|
|
||||||
|
Die GNU-Version\marginpar{GNU!} verfügt ü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}
|
\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äßt. Hier sind die wichtigsten,
|
Parameter mit denen sich die Ausgabe anpassen läßt. Hier sind die wichtigsten,
|
||||||
eine vollständige Auflistung bietet wie immer die Man-Page:
|
eine vollstä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
|
Besonders informativ gibt sich der Parameter \texttt{-l}, da damit auch die
|
||||||
Eigentümer und die Berechtigungen der Dateien angezeigt werden. Die Ausgabe hat
|
Eigentü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ß
|
Eine häufig wiederkehrende Aufgabe ist es, zu sehen ob ein bestimmter Prozeß
|
||||||
existiert oder nicht. Falls das Kommando \texttt{pgrep} zur Verfügung steht,
|
existiert oder nicht. Falls das Kommando \texttt{pgrep} zur Verfügung steht,
|
||||||
@ -901,7 +944,7 @@ kannn man auf das Konstrukt mit \texttt{ps} und \texttt{grep} verzichten. Der
|
|||||||
folgende Aufruf liefert alle Prozeß-IDs, deren Name httpd enthält, inclusive
|
folgende Aufruf liefert alle Prozeß-IDs, deren Name httpd enthält, inclusive
|
||||||
des vollen Kommandos:
|
des vollen Kommandos:
|
||||||
|
|
||||||
\texttt{pgrep -lf httpd}
|
\lstinline|pgrep -lf httpd|
|
||||||
|
|
||||||
Über weitere Parameter läßt sich genauer spezifizieren, wonach gesucht werden
|
Über weitere Parameter läßt sich genauer spezifizieren, wonach gesucht werden
|
||||||
soll, hier die wichtigsten:
|
soll, hier die wichtigsten:
|
||||||
@ -912,7 +955,7 @@ Die Ausgabe enth
|
|||||||
sich als Parameter für andere Programme benutzen. Das folgende Beispiel liefert
|
sich als Parameter für andere Programme benutzen. Das folgende Beispiel liefert
|
||||||
detaillierte Informationen über alle xterm-Prozesse:
|
detaillierte Informationen ü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}.
|
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
|
Dieses Kommando ist eng verwandt mit \texttt{pgrep} (Siehe Abschnitt
|
||||||
\ref{pgrep}), es versteht im Wesentlichen die gleichen Parameter. Allerdings
|
\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ßt beispielsweise den Syslog-Daemon,
|
beschrieben. Das folgende Kommando veranlaßt beispielsweise den Syslog-Daemon,
|
||||||
seine Konfiguration neu einzulesen:
|
seine Konfiguration neu einzulesen:
|
||||||
|
|
||||||
\texttt{pkill -HUP syslogd}
|
\lstinline|pkill -HUP syslogd|
|
||||||
|
|
||||||
Das Kommando \texttt{killall} (Abschnitt \ref{killall}) bietet eine ähnliche
|
Das Kommando \texttt{killall} (Abschnitt \ref{killall}) bietet eine ähnliche
|
||||||
Funktionalität, allerdings fehlen ihm einige Parameter. Trotzdem sollte im
|
Funktionalität, allerdings fehlen ihm einige Parameter. Trotzdem sollte im
|
||||||
@ -954,7 +997,7 @@ Dabei enth
|
|||||||
bestimmten Regeln durch die Daten ersetzt werden.
|
bestimmten Regeln durch die Daten ersetzt werden.
|
||||||
|
|
||||||
Der Format-String folgt im Wesentlichen den gleichen Regeln wie in der
|
Der Format-String folgt im Wesentlichen den gleichen Regeln wie in der
|
||||||
C-Version. Näheres dazu erfährt man mit \texttt{man 3 printf}.
|
C-Version. Näheres dazu erfährt man mit \lstinline|man 3 printf|.
|
||||||
|
|
||||||
Hier die wichtigsten Parameter für den Format-String:
|
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}
|
Home-Verzeichnisse und Default-Shells aus der Datei \texttt{/etc/passwd}
|
||||||
extrahiert und übersichtlich ausgegeben:
|
extrahiert und übersichtlich ausgegeben:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
IFS=:
|
IFS=:
|
||||||
while read user pass uid gid name home shell; do
|
while read user pass uid gid name home shell; do
|
||||||
printf "%-15s %-25s %s\n" $user $home $shell
|
printf "%-15s %-25s %s\n" $user $home $shell
|
||||||
done < /etc/passwd
|
done < /etc/passwd
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Zur Erinnerung: Die vordefinierte Variable
|
Zur Erinnerung: Die vordefinierte Variable
|
||||||
\texttt{\$IFS}\index{\$IFS=\texttt{\$IFS}} ist der Feld-Separator, die
|
\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
|
aktiv ist, ob also zum Beispiel ein bestimmter Serverdienst läuft. Dazu macht
|
||||||
man \texttt{ps} über Optionen gesprächiger.
|
man \texttt{ps} über Optionen gesprächiger.
|
||||||
|
|
||||||
Das Kommando versteht in der GNU-Version zwei unterschiedliche Arten von
|
Das Kommando versteht in der GNU-Version\marginpar{GNU!} zwei unterschiedliche
|
||||||
Optionen. Den sogenannten Unix- bzw. Posix-Stil und den BSD-Stil. Zusätzlich
|
Arten von Optionen. Den sogenannten Unix- bzw. Posix-Stil und den BSD-Stil.
|
||||||
gibt es noch ausführliche Parameter, aber die sollen hier nicht beschrieben
|
Zusätzlich gibt es noch ausführliche Parameter, aber die sollen hier nicht
|
||||||
werden. Die jeweiligen Formen stehen nicht auf allen Systemen zur Verfügung,
|
beschrieben werden. Die jeweiligen Formen stehen nicht auf allen Systemen zur
|
||||||
wenn ein Skript beispielsweise auch unter Solaris benutzt werden soll ist man
|
Verfügung, wenn ein Skript beispielsweise auch unter Solaris benutzt werden
|
||||||
gezwungen, die Unix-Parametrisierung zu benutzen.
|
soll ist man gezwungen, die Unix-Parametrisierung zu benutzen.
|
||||||
|
|
||||||
Unix-Parameter zeichnen sich durch die übliche Angabe mit Bindestrich aus.
|
Unix-Parameter zeichnen sich durch die übliche Angabe mit Bindestrich aus.
|
||||||
BSD-Pa\-ra\-me\-ter werden ohne Bindestrich angegeben, was neben den meisten
|
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
|
immer die Man-Page bzw. ein entsprechendes Buch. Hier werden nur ein paar
|
||||||
typische Aufrufbeispiele gezeigt, deren Ausgabe sich jeder selber ansehen kann:
|
typische Aufrufbeispiele gezeigt, deren Ausgabe sich jeder selber ansehen kann:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
# Alle Prozesse auflisten, Unix-Syntax:
|
# Alle Prozesse auflisten, Unix-Syntax:
|
||||||
ps -e
|
ps -e
|
||||||
ps -ef
|
ps -ef
|
||||||
@ -1041,8 +1081,7 @@ ps -C syslogd -o pid=
|
|||||||
|
|
||||||
# Nur den Namen des Prozesses mit der ID 42 ausgeben:
|
# Nur den Namen des Prozesses mit der ID 42 ausgeben:
|
||||||
ps -p 42 -o comm=
|
ps -p 42 -o comm=
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Für die Suche nach Prozessen bestimmten Namens steht auf manchen Systemen auch
|
Für die Suche nach Prozessen bestimmten Namens steht auf manchen Systemen auch
|
||||||
das Kommando \texttt{pgrep} (Abschnitt \ref{pgrep}) zur Verfügung.
|
das Kommando \texttt{pgrep} (Abschnitt \ref{pgrep}) zur Verfügung.
|
||||||
@ -1070,36 +1109,38 @@ alle Zeichen, die in der vordefinierten Variable
|
|||||||
Wenn keine Variablennamen angegeben werden, wird die Eingabe in der Variable
|
Wenn keine Variablennamen angegeben werden, wird die Eingabe in der Variable
|
||||||
\texttt{REPLY} abgelegt.
|
\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} ü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ält.
|
|
||||||
|
|
||||||
Sonderzeichen können während der Eingabe normalerweise mittels eines Backslash
|
Sonderzeichen können während der Eingabe normalerweise mittels eines Backslash
|
||||||
vor der Interpretation geschützt werden. Ein Backslash vor einem Newline
|
vor der Interpretation geschützt werden. Ein Backslash vor einem Newline
|
||||||
bewirkt also eine mehrzeilige Eingabe. Dieses Verhalten kann mit dem Parameter
|
bewirkt also eine mehrzeilige Eingabe. Dieses Verhalten kann mit dem Parameter
|
||||||
\texttt{-r} abgeschaltet werden.
|
\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} ü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ält.
|
||||||
|
|
||||||
Wenn die Eingabe von einem Terminal kommt und nicht auf dem Bildschirm
|
Wenn die Eingabe von einem Terminal kommt und nicht auf dem Bildschirm
|
||||||
erscheinen soll, zum Beispiel bei Paßwortabfragen, kann die Ausgabe mit dem
|
erscheinen soll, zum Beispiel bei Paßwortabfragen, kann die Ausgabe mit dem
|
||||||
Parameter \texttt{-s} (Silent) unterdrückt werden.
|
Parameter \texttt{-s}\marginpar{GNU!} (Silent) unterdrückt werden.
|
||||||
|
|
||||||
Mit \texttt{-t} kann ein Time-Out definiert werden, nach dessen Ablauf das
|
Mit \texttt{-t}\marginpar{GNU!} kann ein Time-Out definiert werden, nach dessen
|
||||||
Kommando mit einem Fehler abbricht. Dieser Parameter ist nur bei interaktiver
|
Ablauf das Kommando mit einem Fehler abbricht. Dieser Parameter ist nur bei
|
||||||
Eingabe oder beim Lesen aus einer Pipe aktiv.
|
interaktiver Eingabe oder beim Lesen aus einer Pipe aktiv.
|
||||||
|
|
||||||
Der Rückgabewert des \texttt{read}-Kommandos ist 0, es sei denn es trat ein
|
Der Rückgabewert des \texttt{read}-Kommandos ist 0, es sei denn es trat ein
|
||||||
Timeout oder ein EOF auf.
|
Timeout oder ein EOF auf.
|
||||||
@ -1119,8 +1160,8 @@ Verzeichnisse k
|
|||||||
Gegensatz zu \texttt{rmdir} werden dann auch sämtliche enthaltenen Dateien und
|
Gegensatz zu \texttt{rmdir} werden dann auch sämtliche enthaltenen Dateien und
|
||||||
Unterverzeichnisse gelöscht.
|
Unterverzeichnisse gelöscht.
|
||||||
|
|
||||||
Die GNU-Version von \texttt{rm} unterstützt zusätzlich den Parameter
|
Die GNU-Version\marginpar{GNU!} von \texttt{rm} unterstützt zusätzlich den
|
||||||
\texttt{-v}, mit dem jeder Löschvorgang ausgegeben wird.
|
Parameter \texttt{-v}, mit dem jeder Löschvorgang ausgegeben wird.
|
||||||
|
|
||||||
\index{rm=\texttt{rm}|)}
|
\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üglich für das Debuggen fertiger Skripte. Man
|
Dieses Kommando eignet sich vorzüglich für das Debuggen fertiger Skripte. Man
|
||||||
ruft es in Verbindung mit einem Dateinamen auf. Dieser Aufruf startet eine neue
|
ruft es in Verbindung mit einem Dateinamen auf. Dieser Aufruf startet eine neue
|
||||||
@ -1176,8 +1217,7 @@ nur die g
|
|||||||
|
|
||||||
\subsubsection{Aufruf}
|
\subsubsection{Aufruf}
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
# Aufruf als Stream-Editor:
|
# Aufruf als Stream-Editor:
|
||||||
kommando1 | sed 's/alt/neu/' | kommando2
|
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
|
# Alternativ können die Kommandos auch in eine eigene Datei gespeichert und
|
||||||
# über den Parameter -f eingebunden werden:
|
# über den Parameter -f eingebunden werden:
|
||||||
sed -f script.sed datei.txt
|
sed -f script.sed datei.txt
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
Neben den oben erwähnten Parametern kann \texttt{sed} auch mit \texttt{-n}
|
Neben den oben erwähnten Parametern kann \texttt{sed} auch mit \texttt{-n}
|
||||||
ruhig gestellt werden. Damit werden die Zeilen nur dann ausgegeben, wenn das
|
ruhig gestellt werden. Damit werden die Zeilen nur dann ausgegeben, wenn das
|
||||||
mittels `p' explizit gefordert wird. Die GNU-Version stellt noch ein paar
|
mittels `p' explizit gefordert wird. Die GNU-Version\marginpar{GNU!} stellt
|
||||||
Parameter zur Verfügung, die Man-Page verrät näheres.
|
noch ein paar Parameter zur Verfügung, die Man-Page verrät näheres.
|
||||||
|
|
||||||
\subsubsection{Addressierung}
|
\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
|
Einzeiler. Nichtsdestotrotz können es auch diese unscheinbaren Aufrufe in sich
|
||||||
haben.
|
haben.
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
### SUCHEN UND ERSETZEN
|
### SUCHEN UND ERSETZEN
|
||||||
|
|
||||||
# Im kompletten Text 'rot' durch 'blau' ersetzen:
|
# Im kompletten Text 'rot' durch 'blau' ersetzen:
|
||||||
@ -1355,25 +1393,24 @@ sed '/./!d' # Methode 2
|
|||||||
|
|
||||||
# Alle Leerzeilen am Dateianfang löschen:
|
# Alle Leerzeilen am Dateianfang löschen:
|
||||||
sed '/./,$!d'
|
sed '/./,$!d'
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
\index{sed=\texttt{sed}|)}
|
\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
|
Oft wird eine auf- oder absteigende Sequenz aufeinanderfolgender Zahlen
|
||||||
benötigt, beispielsweise um eine Schleife 100 mal zu durchlaufen. Es ist nicht
|
benötigt, beispielsweise um eine Schleife 100 mal zu durchlaufen. Es ist nicht
|
||||||
sehr performant bei jedem Schleifendurchlauf hochzuzählen und dann die
|
sehr performant bei jedem Schleifendurchlauf hochzuzählen und dann die
|
||||||
entstandene Zahl mit dem Limit zu vergleichen. Daher nimmt man an der Stelle
|
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ügung steht.
|
||||||
|
|
||||||
Die zu zählenden Werte werden durch drei unterschiedliche Arten der
|
Die zu zählenden Werte werden durch drei unterschiedliche Arten der
|
||||||
Parametrisierung definiert: Ein Aufruf in der Form \texttt{seq 10} gibt die
|
Parametrisierung definiert: Ein Aufruf in der Form \lstinline|seq 10| gibt die
|
||||||
Zahlen von 1 bis 10 aus. Mit \texttt{seq 10 20} wird von 10 bis 20 gezählt, und
|
Zahlen von 1 bis 10 aus. Mit \lstinline|seq 10 20| wird von 10 bis 20 gezählt,
|
||||||
\texttt{seq 20 -2 10} zählt in zweierschritten rückwärts von 20 nach 10.
|
und \lstinline|seq 20 -2 10| zählt in zweierschritten rückwärts von 20 nach 10.
|
||||||
|
|
||||||
Per default kommen die Werte zeilenweise, mit dem Parameter \texttt{-s} kann
|
Per default kommen die Werte zeilenweise, mit dem Parameter \texttt{-s} kann
|
||||||
aber auch ein anderes Trennzeichen definiert werden. Will man etwas numerieren
|
aber auch ein anderes Trennzeichen definiert werden. Will man etwas numerieren
|
||||||
@ -1390,13 +1427,13 @@ mit f
|
|||||||
Das Kommando \texttt{sleep} veranlaßt die Shell, für eine angegebene Zeit zu
|
Das Kommando \texttt{sleep} veranlaßt die Shell, für eine angegebene Zeit zu
|
||||||
warten. Die Zeit wird dabei in Sekunden angegeben.
|
warten. Die Zeit wird dabei in Sekunden angegeben.
|
||||||
|
|
||||||
In der GNU-Variante von \texttt{sleep} kann die Einheit der angegebenen
|
In der GNU-Variante\marginpar{GNU!} von \texttt{sleep} kann die Einheit der
|
||||||
Zeitspanne durch Suffixe definiert werden: \texttt{sleep 10s} schläft zehn
|
angegebenen Zeitspanne durch Suffixe definiert werden: \lstinline|sleep 10s|
|
||||||
Sekunden, \texttt{sleep 10m} zehn Minuten. Genauso werden Stunden (h) und Tage
|
schläft zehn Sekunden, \lstinline|sleep 10m| zehn Minuten. Genauso werden
|
||||||
(d) definiert.
|
Stunden (h) und Tage (d) definiert.
|
||||||
|
|
||||||
Außerdem kann die GNU-Variante auch mit nicht-Integer Zeiten arbeiten:
|
Außerdem kann die GNU-Variante auch mit nicht-Integer Zeiten arbeiten:
|
||||||
\texttt{sleep 0.5} schläft eine halbe Sekunde.
|
\lstinline|sleep 0.5| schläft eine halbe Sekunde.
|
||||||
|
|
||||||
\index{sleep=\texttt{sleep}|)}
|
\index{sleep=\texttt{sleep}|)}
|
||||||
|
|
||||||
@ -1447,6 +1484,9 @@ Parameter \texttt{-n} steuern.
|
|||||||
Mit dem Parameter \texttt{-f} (follow) gibt \texttt{tail} neue Zeilen aus,
|
Mit dem Parameter \texttt{-f} (follow) gibt \texttt{tail} neue Zeilen aus,
|
||||||
sobald sie an die Datei angehängt werden.
|
sobald sie an die Datei angehä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}|)}
|
\index{tail=\texttt{tail}|)}
|
||||||
|
|
||||||
|
|
||||||
@ -1517,8 +1557,7 @@ in der Man-Page.
|
|||||||
|
|
||||||
Die folgenden Beispiele verdeutlichen die Anwendung:
|
Die folgenden Beispiele verdeutlichen die Anwendung:
|
||||||
|
|
||||||
\footnotesize
|
\begin{lstlisting}
|
||||||
\begin{listing}[2]{1}
|
|
||||||
text="Dies ist ein Testtext"
|
text="Dies ist ein Testtext"
|
||||||
|
|
||||||
# kleine Umlaute durch grosse ersetzen:
|
# kleine Umlaute durch grosse ersetzen:
|
||||||
@ -1544,8 +1583,7 @@ echo "$text" | tr -s "a-zA-Z"
|
|||||||
# doppelte Buchstaben löschen, mit Zeichenklasse:
|
# doppelte Buchstaben löschen, mit Zeichenklasse:
|
||||||
echo "$text" | tr -s "[:alpha:]"
|
echo "$text" | tr -s "[:alpha:]"
|
||||||
# -> Dies ist ein Testext
|
# -> Dies ist ein Testext
|
||||||
\end{listing}
|
\end{lstlisting}
|
||||||
\normalsize
|
|
||||||
|
|
||||||
\index{tr=\texttt{tr}|)}
|
\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
|
Kommando gibt zm Beispiel eine Fehlermeldung aus wenn sein Skript ein Signal 1
|
||||||
(HUP), 2 (INT) oder 15 (TERM) erhält:
|
(HUP), 2 (INT) oder 15 (TERM) erhä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
|
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.
|
||||||
@ -1601,13 +1639,14 @@ Weitaus h
|
|||||||
Zeilen zählen lassen. Weiterhin kann man Bytes (\texttt{-c}) oder Zeichen
|
Zeilen zählen lassen. Weiterhin kann man Bytes (\texttt{-c}) oder Zeichen
|
||||||
(\texttt{-m}) zählen lassen.
|
(\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}|)}
|
\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
|
Sucht im Pfad (vordefinierte Variable
|
||||||
\texttt{\$PATH}\index{\$PATH=\texttt{\$PATH}}, siehe Abschnitt
|
\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
|
Bisweilen kommt man in die Verlegenheit, versehentlich zu lange Einzeiler
|
||||||
geschrieben zu haben. Neben den Fällen, in denen der Tipp-Eifer überhand
|
geschrieben zu haben. Neben den Fällen, in denen der Tipp-Eifer überhand
|
||||||
genommen hat handelt es sich in aller Regel um Zeilen in der Art `\texttt{grep
|
genommen hat handelt es sich in aller Regel um Zeilen in der Art
|
||||||
'text' \$(find / -name \textbackslash*.txt)}'. Dieses Kommando sucht alle
|
\lstinline|grep 'text' $(find / -name \*.txt)|. Dieses Kommando sucht alle
|
||||||
Dateien mit der Endung txt, die im System vorhanden sind. Diese werden `in die
|
Dateien mit der Endung txt, die im System vorhanden sind. Diese werden `in die
|
||||||
Kommandozeile eingebaut'. Wenn sehr viele Dateien gefunden werden, wird 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
|
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
|
Ein weiterer und in der Praxis mindestens ebenso sinnvoller Einsatzzweck ist
|
||||||
das Vermeiden von Schleifen. Das obige Problem ließe sich auch mit einer Zeile
|
das Vermeiden von Schleifen. Das obige Problem ließe sich auch mit einer Zeile
|
||||||
in der Form `\texttt{find / -name \textbackslash*.txt -exec grep 'text' \{\}
|
in der Form \lstinline|find / -name \*.txt -exec grep 'text' {} \;| lösen.
|
||||||
\textbackslash;}'. Allerdings hätte das den Nachteil, daß für jede gefundene
|
Allerdings hätte das den Nachteil, daß für jede gefundene Datei ein neuer
|
||||||
Datei ein neuer \texttt{grep} gestartet werden muß. Das kostet Resourcen.
|
\texttt{grep} gestartet werden muß. Das kostet Resourcen.
|
||||||
|
|
||||||
Beide Probleme werden durch eine Zeile in der Form `\texttt{find / -name
|
Beide Probleme werden durch eine Zeile in der Form
|
||||||
\textbackslash*.txt | xargs grep 'text'}' umgangen. Dabei liest \texttt{xargs}
|
\lstinline+find / -name \*.txt | xargs grep 'text'+ umgangen. Dabei liest
|
||||||
aus der Standardeingabe die Parameter, die dann an den \texttt{grep}-Aufruf
|
\texttt{xargs} aus der Standardeingabe die Parameter, die dann an den
|
||||||
angehängt werden. Sollten zu viele Dateien gefunden werden, wird \texttt{grep}
|
\texttt{grep}-Aufruf angehängt werden. Sollten zu viele Dateien gefunden
|
||||||
mehrfach aufgerufen, allerdings im Gegensatz zum obigen Beispiel nicht einmal
|
werden, wird \texttt{grep} mehrfach aufgerufen, allerdings im Gegensatz zum
|
||||||
pro Fundstelle.
|
obigen Beispiel nicht einmal pro Fundstelle.
|
||||||
|
|
||||||
Neben einigen anderen Parametern informiert die Manpage über die Option
|
Neben einigen anderen Parametern informiert die Manpage der
|
||||||
\texttt{-r}. Damit kann vermieden werden, daß \texttt{xargs} das Kommando
|
GNU-Version\marginpar{GNU!} über die Option \texttt{-r}. Damit kann vermieden
|
||||||
startet wenn keine Eingabe vorhanden ist. Bezogen auf das angegebene Beispiel
|
werden, daß \texttt{xargs} das Kommando startet wenn keine Eingabe vorhanden
|
||||||
würde \texttt{grep} ohne Dateinamen gestartet, wenn \texttt{find} nichts
|
ist. Bezogen auf das angegebene Beispiel würde \texttt{grep} ohne Dateinamen
|
||||||
findet. Es würde auf Input von der Standardeingabe warten, der aber
|
gestartet, wenn \texttt{find} nichts findet. Es würde auf Input von der
|
||||||
wahrscheinlich nicht kommt. Das Skript würde hängen, wenn der Parameter
|
Standardeingabe warten, der aber wahrscheinlich nicht kommt. Das Skript würde
|
||||||
\texttt{-r} nicht angewandt würde.
|
hängen, wenn der Parameter \texttt{-r} nicht angewandt würde.
|
||||||
|
|
||||||
\index{xargs=\texttt{xargs}|)}
|
\index{xargs=\texttt{xargs}|)}
|
||||||
|
@ -38,21 +38,71 @@ zugleich einer der verwirrendsten Anf
|
|||||||
werden. Das geht mit dem Unix-Kommando
|
werden. Das geht mit dem Unix-Kommando
|
||||||
\texttt{chmod}\index{chmod=\texttt{chmod}} und wird in Abschnitt \ref{chmod}
|
\texttt{chmod}\index{chmod=\texttt{chmod}} und wird in Abschnitt \ref{chmod}
|
||||||
ausführlich beschrieben. An dieser Stelle reicht uns ein Aufruf in der Form
|
ausführlich beschrieben. An dieser Stelle reicht uns ein Aufruf in der Form
|
||||||
\texttt{chmod 755 dateiname}, um das Skript für alle Benutzer ausführbar zu
|
\lstinline/chmod 755 name/, um das Skript für alle Benutzer ausführbar zu
|
||||||
machen.
|
machen.
|
||||||
|
|
||||||
Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgründen auf den
|
Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgründen auf den
|
||||||
meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet,
|
meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet,
|
||||||
muß man der Shell noch mitteilen, wo sie zu suchen hat: Mit \texttt{./name}
|
muß man der Shell noch mitteilen, wo sie zu suchen hat: Mit \lstinline|./name|
|
||||||
wird versucht, im aktuellen Verzeichnis (\texttt{./}) ein Programm namens
|
wird versucht, im aktuellen Verzeichnis (\lstinline|./|) ein Programm namens
|
||||||
\texttt{name} auszuführen.
|
\lstinline|name| auszuführen.
|
||||||
|
|
||||||
Auf den meisten Systemen befindet sich im Pfad ein Verweis auf das Verzeichnis
|
Auf den meisten Systemen befindet sich im Pfad ein Verweis auf das Verzeichnis
|
||||||
\texttt{bin} unterhalb des Home-Verzeichnisses eines Benutzers. Das bedeutet
|
\texttt{bin} unterhalb des Home-Verzeichnisses eines Benutzers. Das bedeutet
|
||||||
daß man Skripte die immer wieder benutzt werden sollen dort ablegen kann, so
|
daß man Skripte die immer wieder benutzt werden sollen dort ablegen kann, so
|
||||||
daß sie auch ohne eine Pfadangabe gefunden werden. Wie der Pfad genau aussieht
|
daß sie auch ohne eine Pfadangabe gefunden werden. Wie der Pfad genau aussieht
|
||||||
kann man an der Shell durch Eingabe von \texttt{echo
|
kann man an der Shell durch Eingabe von \lstinline/echo $PATH/\index{\$PATH=\texttt{\$PATH}} herausfinden.
|
||||||
\$PATH}\index{\$PATH=\texttt{\$PATH}} herausfinden.
|
|
||||||
|
|
||||||
|
\section{Fehlersuche}
|
||||||
|
|
||||||
|
Es gibt für Shell-Skripte keine wirklichen Debugger, aber trotzdem verfügt man
|
||||||
|
über einige bewährte Methoden zum Aufspüren von Fehlern:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
|
||||||
|
\item Debug-Ausgaben: Das wohl einfachste Mittel um herauszufinden was im
|
||||||
|
Skript vor sich geht sind wohl regelmäßige Debug-Ausgaben. Dazu fügt man
|
||||||
|
einfach an `strategisch wichtigen' Punkten im Skript \texttt{echo}-Zeilen ein,
|
||||||
|
die Auskunft über den Status geben.
|
||||||
|
|
||||||
|
\item Syntax-Check: Wenn man das Skript in der Form
|
||||||
|
\lstinline|sh -n ./skriptname| aufruft, wird es nicht wirklich ausgeführt.
|
||||||
|
Lediglich die Syntax der Kommandos wird geprüft. Diese Methode findet natürlich
|
||||||
|
keine logischen Fehler, und selbst wenn dieser Aufruf ohne Probleme durchläuft
|
||||||
|
kann sich zur Laufzeit noch ein anderer Fehler einschleichen.
|
||||||
|
|
||||||
|
\item \texttt{set -x}: Wenn in einem Skript der Aufruf \lstinline|set -x|
|
||||||
|
abgesetzt wird, gibt die Shell jede Zeile nach der Expandierung aber vor der
|
||||||
|
Ausführung aus. Dadurch ist klar ersichtlich wann welche Kommandos mit welchen
|
||||||
|
Parametern ausgeführt werden. Um den Effekt wieder aufzuheben benutzt man
|
||||||
|
\lstinline|set +x|. Man kann die Option auch auf das komplette Skript anwenden
|
||||||
|
ohne sie in das Skript einbauen zu müssen. Dazu startet man das Skript nicht
|
||||||
|
einfach durch \lstinline|./skriptname| sondern durch
|
||||||
|
\lstinline|sh -x ./skriptname|.
|
||||||
|
|
||||||
|
\item \texttt{set -v}: Dies funktioniert genau wie \lstinline|set -x|, auch der
|
||||||
|
Aufruf über \lstinline|sh -v ./skriptname| funktioniert. Diese Option gibt jede
|
||||||
|
Zeile vor der Ausführung aus, allerdings im Gegensatz zu \texttt{-x} nicht in
|
||||||
|
der expandierten sondern in der vollen Form.
|
||||||
|
|
||||||
|
\item System-Log: Für das direkte Debuggen ist dieser Weg weniger geeignet,
|
||||||
|
aber gerade in unbeobachtet laufenden Skripten sollte man unerwartete Zustände
|
||||||
|
oder besondere Ereignisse im System-Log festhalten. Dies geschieht mit dem
|
||||||
|
Kommando \texttt{logger}, das in Abschnitt \ref{logger} beschrieben wird.
|
||||||
|
|
||||||
|
\item \texttt{script}: Mit dem Kommando \texttt{script} kann eine Sitzung an
|
||||||
|
der Shell vollständig protokolliert werden, inclusive aller Ein- und Ausgaben.
|
||||||
|
Das umfaßt sogar Drücke auf die Pfeiltasten oder auf Backspace. So kann auch
|
||||||
|
eine längere Sitzung mit vielen Ein- und Ausgaben nach dem Testlauf in aller
|
||||||
|
Ruhe analysiert werden. Das Kommando wird in Abschnitt \ref{script}
|
||||||
|
beschrieben.
|
||||||
|
|
||||||
|
TODO: Debuggen
|
||||||
|
%http://localhost/~rschaten/doku/abs-guide/debugging.html#FTN.AEN14050
|
||||||
|
%-> trapping signals
|
||||||
|
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
\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}}
|
||||||
@ -84,7 +134,7 @@ verschiedenen Wert. Das wird im folgenden Beispiel deutlich:
|
|||||||
|
|
||||||
Normalerweise wird man den Exit-Code nicht in dieser Form abfragen. Sinnvoller
|
Normalerweise wird man den Exit-Code nicht in dieser Form abfragen. Sinnvoller
|
||||||
ist folgendes Beispiel, in dem eine Datei erst gedruckt wird, und dann~--~falls
|
ist folgendes Beispiel, in dem eine Datei erst gedruckt wird, und dann~--~falls
|
||||||
der Ausdruck erfolgreich war ~--~elöscht wird:
|
der Ausdruck erfolgreich war~--~gelöscht wird:
|
||||||
|
|
||||||
\LTXtable{\textwidth}{tab_beisp_exitcode_lpr.tex}
|
\LTXtable{\textwidth}{tab_beisp_exitcode_lpr.tex}
|
||||||
|
|
||||||
@ -341,7 +391,7 @@ erzeugen.
|
|||||||
\section{Arithmetik-Expansion\label{arithmetikexpansion}\index{Arithmetik-Expansion|(textbf}}
|
\section{Arithmetik-Expansion\label{arithmetikexpansion}\index{Arithmetik-Expansion|(textbf}}
|
||||||
|
|
||||||
Auch hier werden Klammern expandiert. Allerdings gleich doppelte Klammern. Mit
|
Auch hier werden Klammern expandiert. Allerdings gleich doppelte Klammern. Mit
|
||||||
einem Konstrukt in der Form \texttt{i=\$((\$i + 1))} können einfache
|
einem Konstrukt in der Form \lstinline|i=$(($i + 1))| können einfache
|
||||||
Berechnungen angestellt werden.
|
Berechnungen angestellt werden.
|
||||||
|
|
||||||
Dabei wird der Ausdruck in den Klammern bewertet als ob er in doppelten
|
Dabei wird der Ausdruck in den Klammern bewertet als ob er in doppelten
|
||||||
@ -366,9 +416,9 @@ genau eine Parent-Proze
|
|||||||
jeweiligen Prozeß erzeugt hat. Man spricht in diesem Zusammenhang tatsächlich
|
jeweiligen Prozeß erzeugt hat. Man spricht in diesem Zusammenhang tatsächlich
|
||||||
von Eltern- bzw. Kind-Prozessen.
|
von Eltern- bzw. Kind-Prozessen.
|
||||||
|
|
||||||
Diese Zusammenhänge lassen sich sehr schön durch die Ausgabe des Kommandos
|
Diese Zusammenhänge lassen sich sehr schön durch die Ausgabe eines Kommandos
|
||||||
\texttt{pstree} oder \texttt{ps -efH} darstellen, letzteres zeigt auch gleich
|
wie \texttt{pstree} oder \lstinline|ps -efH| darstellen, letzteres zeigt auch
|
||||||
die PIDs und die PPIDs an.
|
gleich die PIDs und die PPIDs an.
|
||||||
|
|
||||||
Wenn in einer Shell ein Kommando gestartet wird, ist es ein Kind dieser Shell.
|
Wenn in einer Shell ein Kommando gestartet wird, ist es ein Kind dieser Shell.
|
||||||
Wird ein Skript gestartet, öffnet es sich seine eigene Shell (siehe
|
Wird ein Skript gestartet, öffnet es sich seine eigene Shell (siehe
|
||||||
@ -424,15 +474,15 @@ In der ersten Zeile eines Shell-Skriptes sollte definiert werden, mit welchem
|
|||||||
Programm das Skript ausgeführt werden soll. Das System öffnet dann eine
|
Programm das Skript ausgeführt werden soll. Das System öffnet dann eine
|
||||||
Subshell\index{Subshell} und führt das restliche Skript in dieser aus.
|
Subshell\index{Subshell} und führt das restliche Skript in dieser aus.
|
||||||
|
|
||||||
Die Angabe erfolgt über eine Zeile in der Form \verb\#!/bin/sh\, wobei unter
|
Die Angabe erfolgt über eine Zeile in der Form \lstinline|#!/bin/sh|, wobei
|
||||||
\verb\/bin/sh\ die entsprechende Shell (in diesem Fall die Bourne-Shell) liegt.
|
unter \lstinline|/bin/sh| die entsprechende Shell (in diesem Fall die
|
||||||
Dieser Eintrag wirkt nur dann, wenn er in der ersten Zeile und der ersten
|
Bourne-Shell) liegt. Dieser Eintrag wirkt nur dann, wenn er in der ersten Zeile
|
||||||
Spalte des Skripts steht.
|
und der ersten Spalte des Skripts steht.
|
||||||
|
|
||||||
Dieser Mechanismus ist bei der Bourne-Shell nicht vorhanden, er wurde mit den
|
Dieser Mechanismus ist bei der Bourne-Shell nicht vorhanden, er wurde mit den
|
||||||
moderneren Shells eingeführt um eben durch die Angabe von \verb\#!/bin/sh\ die
|
moderneren Shells eingeführt um eben durch die Angabe von \lstinline|#!/bin/sh|
|
||||||
Bourne-Shell für die Ausführung von Shell-Skripten benutzen zu können. In der
|
die Bourne-Shell für die Ausführung von Shell-Skripten benutzen zu können. In
|
||||||
Bourne-Shell wirkt das führende \verb\#\ als Kommentarzeichen.
|
der Bourne-Shell wirkt das führende \verb\#\ als Kommentarzeichen.
|
||||||
|
|
||||||
\index{Shell>Auswahl der\ldots|)}
|
\index{Shell>Auswahl der\ldots|)}
|
||||||
|
|
||||||
@ -450,24 +500,38 @@ Dieser Befehl tut nichts, au
|
|||||||
|
|
||||||
Ein Shell-Skript kann in keiner Weise Einfluß auf die umgebende Shell nehmen. Das heißt, daß es beispielsweise nicht möglich ist, in einem Skript Variablen zu setzen, die dann in der aufrufenden Shell zur Verfügung stehen. Genauso wenig ist es möglich, daß ein Skript den Pfad ändert, in dem man sich befindet. Der Grund für dieses Verhalten ist die Systemsicherheit. Man will verhindern, daß ein Skript unbemerkt Änderungen an der Benutzerumgebung vornimmt.
|
Ein Shell-Skript kann in keiner Weise Einfluß auf die umgebende Shell nehmen. Das heißt, daß es beispielsweise nicht möglich ist, in einem Skript Variablen zu setzen, die dann in der aufrufenden Shell zur Verfügung stehen. Genauso wenig ist es möglich, daß ein Skript den Pfad ändert, in dem man sich befindet. Der Grund für dieses Verhalten ist die Systemsicherheit. Man will verhindern, daß ein Skript unbemerkt Änderungen an der Benutzerumgebung vornimmt.
|
||||||
|
|
||||||
Wenn es aber doch gewünscht wird, daß ein Skript die Umgebung des Benutzers ändern kann, dann muß es mit dem Source-Kommando aufgerufen werden. Das wird in der Form \verb\source skriptname\ bzw. \verb\. skriptname\ angegeben. Er bewirkt ähnliches wie ein \verb\#include\ in der Programmiersprache C.
|
Wenn es aber doch gewünscht wird, daß ein Skript die Umgebung des Benutzers
|
||||||
|
ändern kann, dann muß es mit dem Source-Kommando aufgerufen werden. Das wird in
|
||||||
|
der Form \lstinline|source skriptname| bzw. \lstinline|. skriptname| angegeben.
|
||||||
|
Er bewirkt ähnliches wie ein \verb\#include\ in der Programmiersprache C.
|
||||||
|
|
||||||
Die `gesourcte' Datei wird eingelesen und ausgeführt, als ob ihr Inhalt an der Stelle des Befehls stehen würde. Diese Methode wird zum Beispiel beim Login in den Konfigurationsdateien des Benutzers (z. B. \verb\.profile\, \verb\.bashrc\) oder während des Bootvorgangs in den Init-Skripten benutzt, um immer wieder benötigte Funktionen (Starten eines Dienstes, Statusmeldungen auf dem Bildschirm etc.) in einer zentralen Datei pflegen zu können (siehe Beispiel unter~\ref{init-skript}).
|
Die `gesourcte' Datei wird eingelesen und ausgeführt, als ob ihr Inhalt an der
|
||||||
|
Stelle des Befehls stehen würde. Diese Methode wird zum Beispiel beim Login in
|
||||||
|
den Konfigurationsdateien des Benutzers (z. B. \verb\.profile\, \verb\.bashrc\)
|
||||||
|
oder während des Bootvorgangs in den Init-Skripten benutzt, um immer wieder
|
||||||
|
benötigte Funktionen (Starten eines Dienstes, Statusmeldungen auf dem
|
||||||
|
Bildschirm etc.) in einer zentralen Datei pflegen zu können (siehe Beispiel
|
||||||
|
unter~\ref{init-skript}).
|
||||||
\index{source=\texttt{source}|)}
|
\index{source=\texttt{source}|)}
|
||||||
|
|
||||||
|
|
||||||
\subsection{Funktionen}\label{funktionen}\index{Funktion|(textbf}
|
\subsection{Funktionen}\label{funktionen}\index{Funktion|(textbf}
|
||||||
|
|
||||||
Es ist in der Shell auch möglich, ähnlich wie in einer `richtigen' Programmiersprache Funktionen zu deklarieren und zu benutzen. Da die Bourne-Shell (\verb\sh\) nicht über Aliase\index{Aliase} verfügt, können einfache Funktionen als Ersatz dienen.
|
Es ist in der Shell auch möglich, ähnlich wie in einer `richtigen'
|
||||||
|
Programmiersprache Funktionen zu deklarieren und zu benutzen. Da die
|
||||||
|
Bourne-Shell (\texttt{sh}) nicht über Aliase\index{Aliase} verfügt, können
|
||||||
|
einfache Funktionen als Ersatz dienen.
|
||||||
|
|
||||||
Der Rückgabewert einer Funktion ist gleich dem Rückgabewert des letzten in der
|
Der Rückgabewert einer Funktion ist gleich dem Rückgabewert des letzten in der
|
||||||
Funktion aufgerufenen Kommandos, es sei denn man gibt mittels
|
Funktion aufgerufenen Kommandos, es sei denn man gibt mittels
|
||||||
\verb\return\ (Siehe \ref{return}) explizit einen anderen Wert zurück.
|
\texttt{return} (Siehe \ref{return}) explizit einen anderen Wert zurück.
|
||||||
|
|
||||||
\medskip\emph{Beispiel:} Die Funktion gibt die Anzahl der Dateien im aktuellen
|
\medskip\emph{Beispiel:} Die Funktion gibt die Anzahl der Dateien im aktuellen
|
||||||
Verzeichnis aus. Aufgerufen wird diese Funktion wie ein Befehl, also einfach
|
Verzeichnis aus. Aufgerufen wird diese Funktion wie ein Befehl, also einfach
|
||||||
durch die Eingabe von \verb\count\.\nopagebreak
|
durch die Eingabe von \texttt{count}.
|
||||||
|
|
||||||
\LTXtable{\textwidth}{tab_beisp_funktionen.tex}
|
\LTXtable{\textwidth}{tab_beisp_funktionen.tex}
|
||||||
|
|
||||||
\index{Funktion|)}
|
\index{Funktion|)}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user