Kleine Verbesserungen, neue Kommandos exec und type.

This commit is contained in:
rschaten 2005-02-22 21:30:40 +00:00
parent f72918f75d
commit 577cdbfcd1
5 changed files with 127 additions and 35 deletions

View File

@ -201,12 +201,14 @@ Ausgabedatei, bei der zweiten reichen schon einzelne Zeichen. In jedem Fall
sollte nach dem Auspacken noch einmal mittels \texttt{sum} oder \texttt{md5sum}
eine Checksumme gezogen und verglichen werden.
\section{Dateien, die es nicht gibt}
\section{Dateien, die es nicht gibt}\label{dateien_die_es_nicht_gibt}
Eine Eigenart der Behandlung von Dateien unter Unix besteht im Verhalten beim
Löschen. Gelöscht wird nämlich zunächst nur der Inode, also die Markierung im
Dateisystem unter der die Datei gefunden werden kann. Physikalisch besteht die
Datei noch, sie wird lediglich im Verzeichnis nicht mehr angezeigt.
Löschen. Gelöscht wird nämlich zunächst nur der Verzeichniseintrag. Der Inode,
also die Markierung im Dateisystem unter der die Datei gefunden werden kann,
besteht weiterhin. Er wird erst dann freigegeben, wenn er nicht mehr
referenziert wird. Physikalisch besteht die Datei also noch, sie wird lediglich
im Verzeichnis nicht mehr angezeigt.
Hat ein Prozeß die Datei noch in irgendeiner Form geöffnet, kann er weiter
darauf zugreifen. Erst wenn er die Datei schließt ist sie tatsächlich und
@ -312,7 +314,7 @@ Abschlie
hat, die Variable nCounter ist mit dem Wert aus der Subshell belegt.
\subsection{Dateien gleichzeitig lesen und schreiben}
\subsection{Dateien gleichzeitig lesen und schreiben}\label{lesen_und_schreiben}
Es kommt vor, daß man eine Datei bearbeiten möchte, die hinterher aber wieder
unter dem gleichen Namen zur Verfügung stehen soll. Beispielsweise sollen alle

View File

@ -98,7 +98,7 @@
\rule{5in}{.04in}\\ \vspace{.25in}
\Huge {\bf SHELL\\ \vspace{.4in} PROGRAMMIERUNG}\\ \vspace{.1in}
\rule{5in}{.04in}\\ \vspace{.6in}
\large v2.0.0 RC2\\
\large v2.0.0 RC3\\
\large \today\\ \vspace{.75in}
\large von\\ \vspace{.3in}
\LARGE {\bf Ronald Schaten} \\ \vspace{.6in}

View File

@ -43,10 +43,13 @@ Standard-Shell\index{Shell>Standard-|see{Bourne-Shell}}\index{Standard-Shell|see
einfachste Form. Sie bietet schon Mechanismen wie die Umlenkung der Ein- oder
Ausgaben, Wildcards zur Abkürzung von Dateinamen, Shell-Variablen und einen
Satz interner Befehle zum Schreiben von Shell-Prozeduren. Neuere Versionen
beherrschen auch das Job-Controlling\index{Job-Controlling}. Für die
Entwicklung von Shell-Skripten sollte man sich auf diese Shell beschränken, da
sie auf praktisch allen Systemen zur Verfügung steht. So bleiben die Skripte
portabel.
beherrschen auch das Job-Controlling\index{Job-Controlling}.
Für die Entwicklung von Shell-Skripten sollte man sich auf diese Shell
beschränken, da sie auf praktisch allen Systemen zur Verfügung steht. So
bleiben die Skripte mit kleinen Einschränkungen\footnote{Die verschiedenen
Implementierungen weisen kleine Unterschiede, z. B. bei der Behandlung von \$@
oder den Parametern von \texttt{read} (-r) auf.} portabel.
\item Die
Korn-Shell\index{Korn-Shell|textbf}\index{Shell>Korn-|see{Korn-Shell}}
@ -64,6 +67,9 @@ kann}\index{Job-Controlling}. Au
fast allen anderen Shells die Möglichkeit, Aliase und Shell-Funktionen an
Subshells zu vererben.
Die Korn-Shell existiert in verschiedenen Implementierungen, sowohl kommerziell
(ksh88), kostenlos (ksh93) als auch frei (pdksh).
\item Die C-Shell \index{C-Shell|textbf}\index{Shell>C-|see{C-Shell}}
(\texttt{csh}\index{csh=\texttt{csh}|see{C-Shell}}) bietet ähnliche
Annehmlichkeiten wie die Korn-Shell, lehnt sich aber in der Syntax sehr stark

View File

@ -134,6 +134,7 @@ Datei kann viel mehr sein als nur ein paar Daten im Filesystem.
\item \texttt{rm} (\ref{rm}): Dateien löschen
\item \texttt{rmdir} (\ref{rmdir}): Verzeichnisse löschen
\item \texttt{touch} (\ref{touch}): Eine leere Datei anlegen, bzw. das Zugriffsdatum einer Datei ändern
\item \texttt{type} (\ref{type}): Art eines Kommandos feststellen
\item \texttt{which} (\ref{which}): Ausführbare Dateien suchen
\item \texttt{xargs} (\ref{xargs}): Ausgaben eines Kommandos als Parameter eines anderen Kommandos benutzen
\end{itemize}
@ -161,6 +162,7 @@ kleinsten geeigneten Hammer nehmen.
\begin{itemize}
\item \texttt{awk} (\ref{awk}): In einer Pipe editieren
\item \texttt{cut} (\ref{cut}): Teile einer Zeile ausschneiden
\item \texttt{exec} (\ref{exec}): Dateideskriptoren umhängen
\item \texttt{grep} (\ref{grep}): In einer Pipe suchen
\item \texttt{sed} (\ref{sed}): In einer Pipe editieren
\item \texttt{sort} (\ref{sort}): Zeilenweises Sortieren
@ -185,6 +187,7 @@ F
Verfügung.
\begin{itemize}
\item \texttt{exec} (\ref{exec}): Kommandos ausführen
\item \texttt{kill} (\ref{kill}): Signal an einen Prozeß schicken
\item \texttt{killall} (\ref{killall}): Signal an mehrere Prozesse schicken
\item \texttt{ps} (\ref{ps}): Prozeßliste ausgeben
@ -400,8 +403,11 @@ k
verkettet werden.
Außerdem kann man mit einem Aufruf in der Art
\lstinline|cat datei.txt | kommando| Daten an ein Programm übergeben, das nur
von der Standardeingabe lesen kann (Filter).
\lstinline!cat datei.txt | kommando! Daten an ein Programm übergeben, das nur
von der Standardeingabe lesen kann (Filter). Das geht zwar auch durch eine
Umleitung (siehe Abschnitt \ref{datenstrom}), wird aber in dieser Form von
vielen als lesbarer angesehen. Vorteil der Umleitungs-Methode ist, daß nicht
erst ein externes Kommando ausgeführt werden muß.
\begin{dinglist}{43}
\item GNU-\texttt{cat} verfügt über eine Reihe von Parametern, um die Ausgabe
@ -667,6 +673,12 @@ der Praxis oft als sehr hilfreich:
\LTXtable{\textwidth}{tab_kommandos_echo_parameter.tex}
\begin{dinglist}{43}
\item Die Steuerzeichen, die nach einem \texttt{-e} angegeben werden können
sind nicht in allen Shells gleich. Das sollte berücksichtigt werden, wenn das
Skript portabel bleiben soll.
\end{dinglist}
\index{echo=\texttt{echo}|)}
@ -697,6 +709,28 @@ Array-Elementes ausgegeben werden:
\index{eval=\texttt{eval}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{exec}\label{exec}\index{exec=\texttt{exec}|(textbf}
Dieses Kommando hat zwei wesentliche Einsatzgebiete:
Wenn das laufende Skript nur benutzt wird um ein anderes Programm zu starten,
beispielsweise um die Umgebungsvariablen geeignet zu belegen, sollte das
Programm mit \texttt{exec} ausgeführt werden. Der Effekt ist, daß sich die
Shell in der das Skript ausgeführt wird beendet und die Kontrolle vollständig
an das neue Programm übergibt. So vermeidet man einen überflüssigen Prozeß, der
lediglich auf die Beendigung seiner Kinder wartet.
Der zweite Anwendungsfall ist etwas für den fortgeschrittenen Benutzer: Man
kann mit \texttt{exec} Dateideskriptoren umhängen. Damit ist gemeint, daß zum
Beispiel die Standardausgabe mittels \lstinline|exec >5| auf den
Dateideskriptor mit der Nummer 5 gelegt werden kann. Auf diesem Weg kann mit
mehreren Datenströmen jongliert werden. Die Beispiele in Anhang
\ref{dateien_die_es_nicht_gibt} verdeutlichen die Anwendung.
\index{exec=\texttt{exec}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{expr}\label{expr}\index{expr=\texttt{expr}|(textbf}
@ -792,7 +826,7 @@ f
\textbf{Alternative 2:} Sucht man nach einer ausführbaren Datei, die im Pfad
vorhanden ist (`Wo liegt eigentlich Firefox?'), dann sucht man mittels
\texttt{which} (Abschnitt \ref{which}).
\texttt{which} (Abschnitt \ref{which}) oder \texttt{type} (\ref{type}).
Siehe auch: Abschnitt \ref{beispiele_suchen_dateien}.
@ -1733,14 +1767,28 @@ entkr
\lstinline|trap 'echo "Ctrl-C ist ausser Kraft."' 2|
Eine Sonderbehandlung macht die Shell, wenn als Signal \texttt{DEBUG} angegeben
wird. Dann wird nach jedem ausgeführten Kommando der Trap ausgelöst. Dieses
Feature wird wie der Name schon erahnen läßt zum Debuggen benutzt, ein Beispiel
findet sich in Abschnitt \ref{fehlersuche}.
Eine Sonderbehandlung machen viele Shells, wenn als Signal \texttt{DEBUG}
angegeben wird. Dann wird nach jedem ausgeführten Kommando der Trap ausgelöst.
Dieses Feature wird wie der Name schon erahnen läßt zum Debuggen benutzt, ein
Beispiel findet sich in Abschnitt \ref{fehlersuche}.
\index{trap=\texttt{trap}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{type}\label{type}\index{type=\texttt{type}|(textbf}
Das in die Shell eingebaute Kommando \texttt{type} gibt Auskunft über die Art
eines ausführbaren Kommandos. So kann man herausfinden ob beim Absetzen des
Befehls ein externes Programm gestartet, eine Shell-Funktion ausgeführt oder
ein Alias benutzt wird.
Sucht man nur nach einer ausführbaren Datei, hilft \texttt{which} (Abschnitt
\ref{which}).
\index{type=\texttt{type}|)}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{uniq}\label{uniq}\index{uniq=\texttt{uniq}|(textbf}
@ -1813,6 +1861,8 @@ Dateien auf das Suchwort passen wird die erste Fundstelle ausgegeben, also die
Datei die tatsächlich ausgeführt würde. Mit \texttt{-a} werden alle Fundstellen
ausgegeben.
Einen ähnlichen Zweck erfüllt auch \texttt{type} (Abschnitt \ref{type}).
\index{which=\texttt{which}|)}

View File

@ -555,10 +555,10 @@ unter \lstinline|/bin/sh| die entsprechende Shell (in diesem Fall die
Bourne-Shell) liegt. Dieser Eintrag wirkt nur dann, wenn er in der ersten Zeile
und der ersten Spalte des Skripts steht.
Dieser Mechanismus ist bei der Bourne-Shell nicht vorhanden, er wurde mit den
moderneren Shells eingeführt um eben durch die Angabe von \lstinline|#!/bin/sh|
die Bourne-Shell für die Ausführung von Shell-Skripten benutzen zu können. In
der Bourne-Shell wirkt das führende \verb\#\ als Kommentarzeichen.
Dieser Mechanismus wurde mit dem Aufkommen modernerer Shells eingeführt um eben
durch die Angabe von \lstinline|#!/bin/sh| die Bourne-Shell für die Ausführung
von Shell-Skripten benutzen zu können. Interpretiert wird die Zeile vom Kernel,
in der Shell selbst wirkt das führende \verb\#\ als Kommentarzeichen.
\index{Shell>Auswahl der\ldots|)}
@ -629,21 +629,24 @@ count () {
\subsection{Bedingungen (\texttt{[ ]})}\label{bedingungen}\index{Bedingungen|see{test}}\index{[ ]=\texttt{[ ]}|see{test}}\index{test=\texttt{test}|(textbf}
Da die Standard-Shell keine arithmetischen oder logischen Ausdrücke auswerten
kann\footnote{\texttt{if} und Konsorten prüfen nur den
Ursprünglich konnte die Standard-Shell keine arithmetischen oder logischen
Ausdrücke auswerten\footnote{\texttt{if} und Konsorten prüfen nur den
Rückgabewert\index{Rückgabewert} eines aufgerufenen Programmes~--~0 bedeutet
`true', alles andere bedeutet `false', siehe auch \ref{exitcode}.}, muß dazu
ein externes Programm benutzt werden. Dieses Programm heißt
\verb\test\\index{test=\texttt{test}}. Üblicherweise besteht auf allen Systemen
auch noch ein Link namens \verb\[\ auf dieses Programm. Dieser Link ist fast
absolut gleichwertig zu benutzen (in dieser Form wird allerdings eine
abschließende Klammer nach der Bedingung erwartet). Dementsprechend ist es auch
zwingend erforderlich, nach der Klammer ein Leerzeichen zu schreiben. Das dient
dazu, Bedingungen in \verb\if\-Abfragen u. ä. lesbarer zu machen.
`true', alles andere bedeutet `false', siehe auch \ref{exitcode}.}. Für diese
Aufgabe mußte ein externes Programm benutzt werden, heutzutage ist der Befehl
in die Shell integriert.
Das \verb\test\-Programm bietet sehr umfangreiche Optionen an. Dazu gehören
Dateitests und Vergleiche von Zeichenfolgen oder ganzen Zahlen. Diese
Bedingungen können auch durch Verknüpfungen kombiniert werden.
Dieser Befehl heißt \verb\test\\index{test=\texttt{test}}. Üblicherweise
steht er auf allen Systemen auch noch unter dem Namen \verb\[\ zur Verfügung.
Diese Variante ist fast absolut gleichwertig zu benutzen (in dieser Form wird
allerdings eine abschließende Klammer nach der Bedingung erwartet).
Dementsprechend ist es auch zwingend erforderlich, nach der Klammer ein
Leerzeichen zu schreiben. Das dient dazu, Bedingungen in \verb\if\-Abfragen u.
ä. lesbarer zu machen.
\verb\test\ bietet sehr umfangreiche Optionen an. Dazu gehören Dateitests und
Vergleiche von Zeichenfolgen oder ganzen Zahlen. Diese Bedingungen können auch
durch Verknüpfungen kombiniert werden.
\medskip\medskip\emph{Dateitests:}\index{Dateitests}\nopagebreak
\LTXtable{\textwidth}{tab_bedingungen_dateitests.tex}
@ -883,6 +886,35 @@ while [ $i -le 100 ]; do
done
\end{lstlisting}
Ein weiterer typischer Anwendungsfall ist das zeilenweise Bearbeiten einer
Eingabedatei. Dabei kann es sich entweder um eine einfache Textdatei handeln,
oder um die Ausgabe eines anderen Kommandos.
Um die Ausgabe eines anderen Kommandos zu verarbeiten kann \texttt{while} als
Teil einer Pipeline geschrieben werden:
\begin{lstlisting}
# "hallo" suchen und umstaendlich ausgeben:
grep "hallo" datei.txt | while read zeile; do
echo "Fundstelle: $zeile"
done
\end{lstlisting}
Wenn die Eingabe als Textdatei vorliegt ist es verlockend, diese einfach
mittels \texttt{cat} auszugeben und per Pipe in die Schleife zu schicken.
Allerdings sollte an dieser Stelle eine Umleitung benutzt werden. So vermeidet
man den überflüssigen Start des Kommandos \texttt{cat}:
\begin{lstlisting}
# Zahlen aus einer Datei lesen und aufsummieren:
summe=0
while read zeile; do
summe=`expr $summe + $zeile`
done < datei.txt
echo "Summe: $summe"
\end{lstlisting}
\index{while=\texttt{while}|)}
@ -989,7 +1021,9 @@ Funktion ausgef
\index{\&=\texttt{\&}|(textbf}\index{;=\texttt{;}|(textbf}\index{( )=\texttt{( )}|(textbf}\index{\{ \}=\texttt{\{ \}}|(textbf}\index{Pipe|(textbf}\index{Backticks|(textbf}\index{\&\&=\texttt{\&\&}|(textbf}\index{!|!|=\texttt{!|!|}|(textbf}\index{Befehls>-substitution|(textbf}\index{Befehls>-folge|(textbf}\index{Befehls>-block|(textbf}
\index{!|=\texttt{!|}|see{Pipe}}\index{Substitution|see{Befehls-Subst.}}
Es gibt eine Reihe verschiedener Möglichkeiten, Kommandos auszuführen:\nopagebreak
Es gibt eine Reihe verschiedener Möglichkeiten, Kommandos auszuführen. So
kommen Verkettungen, Abhängigkeiten und Gruppierungen zustande:\nopagebreak
\LTXtable{\textwidth}{tab_befehlsformen.tex}
\medskip\emph{Beispiele:}\nopagebreak