diff --git a/schmutzige_tricks.tex b/schmutzige_tricks.tex index 1605b3d..010e119 100644 --- a/schmutzige_tricks.tex +++ b/schmutzige_tricks.tex @@ -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 diff --git a/shell.tex b/shell.tex index ae38140..feaf554 100644 --- a/shell.tex +++ b/shell.tex @@ -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} diff --git a/was_ist_die_shell.tex b/was_ist_die_shell.tex index b294641..bbe8a14 100644 --- a/was_ist_die_shell.tex +++ b/was_ist_die_shell.tex @@ -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 diff --git a/werkzeugkasten.tex b/werkzeugkasten.tex index 28a0f02..2cdd987 100644 --- a/werkzeugkasten.tex +++ b/werkzeugkasten.tex @@ -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}|)} diff --git a/wie_sieht_ein_shell_skript_aus.tex b/wie_sieht_ein_shell_skript_aus.tex index 3ddcddb..998eff1 100644 --- a/wie_sieht_ein_shell_skript_aus.tex +++ b/wie_sieht_ein_shell_skript_aus.tex @@ -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