Viele Aenderungen, Tabellen durch Syntax-Boxen ausgetauscht, neues Kapitel: date

This commit is contained in:
rschaten
2005-01-28 10:07:07 +00:00
parent 68d30297e6
commit 82d1e3e470
27 changed files with 456 additions and 436 deletions

View File

@@ -83,7 +83,7 @@ Der Weg in die andere Richtung ist ganz
\lstinline_tar cf - datei.txt | ssh 192.168.2.1 "(mkdir -p $PWD ;cd $PWD; tar xf -)"_
Hier wird die Datei verpackt und versendet. Eine Besonderheit gegenüber dem
vorigen Beispiel bestehtdarin, daß das Zielverzeichnis bei Bedarf erstellt
vorigen Beispiel besteht darin, daß das Zielverzeichnis bei Bedarf erstellt
wird, bevor die Datei dort entpackt wird. Zur Erklärung: Die Variable
\texttt{\$PWD} wird, da sie nicht von Ticks `gesichert' wird, schon lokal durch
die Shell expandiert. An dieser Stelle erscheint also auf dem entfernten System
@@ -195,74 +195,24 @@ sechs Kilobytes~--~
Um es nochmal zu betonen: Diese beiden Methoden sind mit Vorsicht zu genießen.
Bei der ersten führt jede zusätzliche oder gelöschte Zeile zu einer kaputten
Ausgabedatei, bei der zweiten reichen schon einzelne Zeilen. In jedem Fall
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}
TODO!!! 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.
\subsection{Speichern in nicht existente Dateien}
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
unwiederbringlich `weg'.
TODO!!! Speichern in nicht existente Dateien
Dieser Effekt der `nicht existenten Dateien' läßt sich an verschiedenen Stellen
geschickt einsetzen.
\subsection{Subshell-Schleifen vermeiden}\label{subshellschleifen}
Wir wollen ein Skript schreiben, das die \texttt{/etc/passwd} liest und dabei
zählt, wie viele Benutzer eine UID kleiner als 100 haben.
Folgendes Skript funktioniert nicht:
\begin{lstlisting}
#!/bin/sh
count=0
cat /etc/passwd | while read i; do
uid=`echo $i | cut -f 3 -d:`
if [ $uid -lt 100 ]; then
count=`expr $count + 1`
echo $count
fi
done
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
\end{lstlisting}
Was ist passiert?
Dieses Skript besteht im Wesentlichen aus einer Pipe. Wir haben ein
\texttt{cat}-Kom\-man\-do, das den Inhalt der \texttt{/etc/passwd} durch eben
diese Pipe an eine Schleife übergibt. Das \texttt{read}-Kommando in der
Schleife liest die einzelnen Zeilen aus, dann folgt ein Bißchen Auswertung.
Es ist zu beobachten, daß bei der Ausgabe in Zeile 7 die Variable
\texttt{\$count} korrekte Werte enthält. Um so unverständlicher ist es, daß sie
nach der Vollendung der Schleife wieder den Wert 0 enthält.
Das liegt daran, daß diese Schleife als Teil einer Pipe in einer Subshell
ausgeführt wird. Die Variable \texttt{\$count} steht damit in der Schleife
praktisch nur lokal zur Verfügung, sie wird nicht an das umgebende Skript
`hochgereicht'.
Neben der Methode in \ref{daten_hochreichen} bietet sich hier eine viel
einfachere Lösung an:
\begin{lstlisting}
#!/bin/sh
count=0
while read i; do
uid=`echo $i | cut -f 3 -d:`
if [ $uid -lt 100 ]; then
count=`expr $count + 1`
echo $count
fi
done < /etc/passwd
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
\end{lstlisting}
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
und den Inhalt der Datei durch die Umlenkung in Zeile 9 direkt auf die
Standardeingabe der Schleife (und somit auf das \texttt{read}-Kommando) legen.
\subsection{Daten aus einer Subshell hochreichen}\label{daten_hochreichen}
@@ -297,7 +247,7 @@ geht man in solchen F
Bei einfachen Zahlenwerten könnte beispielsweise ein Rückgabewert helfen.
Komplexere Informationen können in eine temporäre Datei geschrieben werden, die
danach geparst werden müßte. Wenn die Informationen in Zeilen der Form
`VARIABLE=\dq{}Wert\dq{}' gespeichert werden, kann die Datei einfach mittels
\lstinline|VARIABLE="Wert"| gespeichert werden, kann die Datei einfach mittels
\texttt{source} (Abschnitt \ref{source}) oder einem Konstrukt der Art
\texttt{eval `cat tempfile`} gelesen werden.