Viele Aenderungen
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
% $Id$
|
||||
\chapter{Nützliche Shell-Kommandos}\label{nuetzliche_shell-kommandos}
|
||||
\chapter{Werkzeugkasten}\label{werkzeugkasten}
|
||||
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
|
||||
ist tatsächlich in der Shell möglich, Sortier- oder Suchfunktionen zu
|
||||
@@ -68,11 +68,30 @@ Dateien auf der Festplatte.
|
||||
\item \texttt{head} (\ref{head}): Dateianfang ausgeben
|
||||
\item \texttt{printf} (\ref{printf}): Formatierte Datenausgabe
|
||||
\item \texttt{read} (\ref{read}): Zeilen einlesen
|
||||
\item \texttt{sort} (\ref{sort}): Zeilenweises Sortieren
|
||||
\item \texttt{tail} (\ref{tail}): Dateiende ausgeben
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Dateiinhalte bearbeiten}\label{dateiinhalte}
|
||||
|
||||
Natürlich bietet die Shell eine Reihe von Befehlen, um die Inhalte von Dateien
|
||||
zu bearbeiten. Diese Auflistung ist in weiten Teilen deckungsgleich mit der
|
||||
Liste der Tools zur Manipulation von Pipes, auch diese Kommandos kommen also
|
||||
in mehreren Situationen zum Einsatz.
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{awk} (\ref{awk}): In einer Pipe editieren
|
||||
\item \texttt{cmp} (\ref{cmp}): Binäre Dateien vergleichen
|
||||
\item \texttt{cut} (\ref{cut}): Teile einer Zeile ausschneiden
|
||||
\item \texttt{diff} (\ref{diff}): Textdateien vergleichen
|
||||
\item \texttt{paste} (\ref{paste}): Dateien zusammenführen
|
||||
\item \texttt{sed} (\ref{sed}): In einer Pipe editieren
|
||||
\item \texttt{sort} (\ref{sort}): Zeilenweises Sortieren
|
||||
\item \texttt{tr} (\ref{tr}): Zeichen ersetzen
|
||||
\item \texttt{uniq} (\ref{uniq}): Doppelte Zeilen suchen
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Pfade und Dateien}\label{pfade_und_dateien}
|
||||
|
||||
Eine der Hauptaufgaben von Shell-Skripten ist natürlich das Hantieren mit
|
||||
@@ -85,10 +104,12 @@ Datei kann viel mehr sein als nur ein paar Daten im Filesystem.
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{basename} (\ref{basename}): Den Namen einer Datei (ohne Pfad) ausgeben
|
||||
\item \texttt{cd} (\ref{cd}): Verzeichnis wechseln
|
||||
\item \texttt{cp} (\ref{cp}): Dateien kopieren
|
||||
\item \texttt{chgrp} (\ref{chgrp}): Gruppen-ID einer Datei ändern
|
||||
\item \texttt{chmod} (\ref{chmod}): Zugriffsrechte einer Datei ändern
|
||||
\item \texttt{chown} (\ref{chown}): Eigentümer einer Datei ändern
|
||||
\item \texttt{cmp} (\ref{cmp}): Binäre Dateien vergleichen
|
||||
\item \texttt{dirname} (\ref{dirname}): Den Pfad zu einer Datei (ohne den Namen) ausgeben
|
||||
\item \texttt{find} (\ref{find}): Dateien suchen
|
||||
\item \texttt{mkdir} (\ref{mkdir}): Verzeichnisse anlegen
|
||||
@@ -96,6 +117,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{which} (\ref{which}): Ausführbare Dateien suchen
|
||||
\item \texttt{xargs} (\ref{xargs}): Ausgaben eines Kommandos als Parameter eines anderen Kommandos benutzen
|
||||
\end{itemize}
|
||||
|
||||
@@ -120,12 +142,14 @@ und ausgef
|
||||
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{grep} (\ref{grep}): In einer Pipe suchen
|
||||
\item \texttt{sed} (\ref{sed}): In einer Pipe editieren
|
||||
\item \texttt{awk} (\ref{awk}): In einer Pipe editieren
|
||||
\item \texttt{sort} (\ref{sort}): Zeilenweises Sortieren
|
||||
\item \texttt{tee} (\ref{tee}): Datenstrom in einer Datei protokollieren
|
||||
\item \texttt{tr} (\ref{tr}): Zeichen ersetzen
|
||||
\item \texttt{uniq} (\ref{uniq}): Doppelte Zeilen suchen
|
||||
\item \texttt{wc} (\ref{wc}): Zeilen, Wörter oder Zeichen zählen
|
||||
\end{itemize}
|
||||
|
||||
@@ -149,6 +173,7 @@ Verf
|
||||
\item \texttt{ps} (\ref{ps}): Prozeßliste ausgeben
|
||||
\item \texttt{pgrep} (\ref{pgrep}): Bestimmte Prozesse suchen
|
||||
\item \texttt{pkill} (\ref{pkill}): Bestimmte Prozesse töten
|
||||
\item \texttt{trap} (\ref{trap}): Auf Signale reagieren
|
||||
\end{itemize}
|
||||
|
||||
|
||||
@@ -164,7 +189,154 @@ ausgiebigere Informationen empfehle ich entsprechende B
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{awk}\label{awk}\index{awk=\texttt{awk}|(textbf}
|
||||
|
||||
TODO!!! awk
|
||||
Über die Skriptsprache \texttt{awk} wurden schon ganze Bücher geschrieben, eine
|
||||
vollständige Beschreibung würde den Rahmen dieses Dokumentes bei weitem
|
||||
sprengen. Hier werden nur ein paar grundlegende Techniken beschrieben, die
|
||||
häufig im Zusammenhang mit Shell-Skripten auftauchen.
|
||||
|
||||
Oben wurde \texttt{awk} `Skriptsprache' genannt. Das ist insofern richtig, als
|
||||
daß es eine mächtige und komplexe Syntax zur Verfügung stellt, um Texte
|
||||
automatisiert zu bearbeiten. Es fällt somit in die gleiche Tool-Kategorie wie
|
||||
\texttt{sed} (Abschnitt \ref{sed}).
|
||||
|
||||
Es unterscheidet sich aber in seinen grundlegenden Prinzipien entscheidend von
|
||||
den meisten anderen Programmiersprachen: \texttt{awk} arbeitet `Datenbasiert'.
|
||||
Das bedeutet, daß zunächst die Daten spezifiziert werden mit denen gearbeitet
|
||||
werden soll, dann folgen die auszuführenden Kommandos. Das Prinzip wird schnell
|
||||
klar, wenn man sich einige der Beispiele weiter unten ansieht.
|
||||
|
||||
\subsubsection{Aufruf}
|
||||
|
||||
Auch der Aufruf erfolgt analog zu \texttt{sed}: Bei einfachen Aufgaben kann das
|
||||
\texttt{awk}-Programm direkt an der Kommandozeile mitgegeben werden, komplexere
|
||||
Programme werden in Dateien gespeichert und von dort gelesen.
|
||||
|
||||
Eine weitere Gemeinsamkeit ist die Art der Ein- und Ausgabe. Wenn eine
|
||||
Eingabedatei angegeben wird, wird diese verarbeitet. Ansonsten wird die
|
||||
Standard-Eingabe gelesen. Ausgaben erfolgen immer auf der Standard-Ausgabe.
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
# Aufruf als Filter:
|
||||
kommando1 | awk '{ print $1; print $2 }' | kommando2
|
||||
|
||||
# Aufruf mit einer zu bearbeitenden Datei:
|
||||
awk '{ print $1; print $2 }' datei.txt
|
||||
|
||||
# In einem Skript kann das Kommando auch über mehrere Zeilen gehen:
|
||||
awk '
|
||||
{
|
||||
print $1;
|
||||
print $2;
|
||||
}' datei.txt
|
||||
|
||||
# Alternativ können die Kommandos auch in eine eigene Datei gespeichert und
|
||||
# über den Parameter -f eingebunden werden:
|
||||
awk -f script.awk datei.txt
|
||||
\end{listing}
|
||||
\normalsize
|
||||
|
||||
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
|
||||
folgende Zeile gibt beispielsweise alle Benutzernamen und deren User-IDs aus
|
||||
der Doppelpunktseparierten Datei \texttt{/etc/passwd} aus:
|
||||
|
||||
\texttt{awk -F: '\{ print \$1\dq hat ID \dq\$3 \}' /etc/passwd}
|
||||
|
||||
\subsubsection{Muster und Prozeduren}
|
||||
|
||||
Die Skripte für \texttt{awk} bestehen aus Blöcken von Mustern und Prozeduren.
|
||||
Ein Block hat den folgenden Aufbau:
|
||||
|
||||
\textsl{muster}\texttt{ \{ }\textsl{prozedur}\texttt{ \}}
|
||||
|
||||
Dabei sind beide Bestandteile des Blockes Optional: Wird das Muster
|
||||
weggelassen, wird die Prozedur auf alle Textbestandteile angewandt. Und wird
|
||||
keine Prozedur angegeben, wird der betroffene Text einfach ausgegeben.
|
||||
|
||||
Das Muster kann dabei auf verschiedene Weise angegeben werden:
|
||||
\begin{itemize}
|
||||
\item Als regulärer Ausdruck (siehe Abschnitt \ref{mustererkennung}),
|
||||
eingebettet in Slashes: \texttt{/}\textsl{muster}\texttt{/}
|
||||
\item Als relationaler Ausdruck, bei dem bestimmte Kriterien auf die
|
||||
Eingabedaten zutreffen müssen. Mit \texttt{\$2>\$1} werden beispielsweise
|
||||
Zeilen angesprochen, deren zweites Feld einen größeren Wert hat als das erste.
|
||||
\item Mit Operatoren für das Pattern-Matching, ähnlich wie in Perl (\texttt{\~}
|
||||
oder \texttt{!\~})
|
||||
\item \texttt{BEGIN} kennzeichnet Prozeduren, die vor der Bearbeitung anderer
|
||||
Blöcke zum Tragen kommen sollen.
|
||||
\item Analog dazu gibt es ein \texttt{END}, mit dem abschließende Aktionen
|
||||
gekennzeichnet werden.
|
||||
\end{itemize}
|
||||
|
||||
Abgesehen von \texttt{BEGIN} und \texttt{END} können die Muster auch durch
|
||||
logische Operatoren (\texttt{\&\&}, \texttt{||} oder \texttt{!}) kombiniert
|
||||
werden. Durch Komma getrennt besteht die Möglichkeit, Wirkungsbereiche zu
|
||||
definieren.
|
||||
|
||||
Die Prozeduren können Variablen- oder Array-Zuweisungen, Ausgabeanweisungen,
|
||||
Funktionsaufrufe oder Kontrollstrukturen enthalten.
|
||||
|
||||
\subsubsection{Variablen}
|
||||
|
||||
Es gibt in \texttt{awk} eine Reihe eingebauter Variablen, die in Mustern oder
|
||||
Prozeduren verwendet werden können:
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_awk_variablen.tex}
|
||||
|
||||
Eigene Variablen können nach Belieben verwendet werden, siehe dazu das Beispiel
|
||||
mit den TeX-Dateien weiter unten.
|
||||
|
||||
\subsubsection{Beispiele}
|
||||
|
||||
Hier ein paar Einfache Beispiele für Blocks aus Mustern und Prozeduren:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
# Das erste Feld jeder Zeile ausgeben:
|
||||
{ print $1 }
|
||||
|
||||
# Alle Zeilen ausgeben, die 'regexp' enthalten:
|
||||
/regexp/
|
||||
|
||||
# Das erste Feld jeder Zeile ausgeben, die 'regexp' enthält:
|
||||
/regexp/ { print $1 }
|
||||
|
||||
# Datensätze mit mehr als zwei Feldern auswählen:
|
||||
NF > 2
|
||||
|
||||
# Das dritte und das zweite Feld jeder Zeile ausgeben, deren erstes Feld den
|
||||
# String 'WICHTIG' enthält:
|
||||
$1 ~ /WICHTIG/ { print $3, $2 }
|
||||
|
||||
# Die Vorkommen von 'muster' zählen, und deren Anzahl ausgeben:
|
||||
/muster/ { ++x }
|
||||
END { print x }
|
||||
|
||||
# Alle Zeilen mit weniger als 23 Zeichen ausgeben:
|
||||
length($0) < 23
|
||||
|
||||
# Alle Zeilen ausgeben, die mit 'Name:' anfangen und exakt sieben Felder
|
||||
# enthalten:
|
||||
NF == 7 && /^Name:/
|
||||
|
||||
# Alle Felder der Eingabedaten zeilenweise in umgekehrter Reihenfolge ausgeben:
|
||||
{
|
||||
for (i = NF; i >= 1; i--)
|
||||
print $i
|
||||
}
|
||||
|
||||
# Die Größe aller TeX-Dateien addieren, die Summe in kB umrechnen und ausgeben,
|
||||
# verarbeitet die Ausgabe von 'ls -l':
|
||||
/.*tex/ { summe += $5 }
|
||||
END { summe /= 1024; print "Die Größe aller TeX-Files beträgt", summe, "kB" }
|
||||
|
||||
# Pipe-Separierte Liste aller gemounteten Partitionen und derer Füllstände
|
||||
# ausgeben, verarbeitet die Ausgabe von 'df':
|
||||
BEGIN { OFS="|" }
|
||||
/^\/dev\// { print $1,$5 }
|
||||
\end{listing}
|
||||
\normalsize
|
||||
|
||||
\index{awk=\texttt{awk}|)}
|
||||
|
||||
@@ -220,6 +392,14 @@ werden.
|
||||
\index{cat=\texttt{cat}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{cd}\label{cd}\index{cd=\texttt{cd}|(textbf}
|
||||
|
||||
Mit dem Kommando \texttt{cd} wird das aktuelle Verzeichnis gewechselt.
|
||||
|
||||
\index{cd=\texttt{cd}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{chgrp}\label{chgrp}\index{chgrp=\texttt{chgrp}|(textbf}
|
||||
|
||||
@@ -328,6 +508,14 @@ diese Datei nicht allgemein lesbar ist.
|
||||
\index{chpasswd=\texttt{chpasswd}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{cmp}\label{cmp}\index{cmp=\texttt{cmp}|(textbf}
|
||||
|
||||
TODO!!! cmp GNU?
|
||||
|
||||
\index{cmp=\texttt{cmp}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{cp}\label{cp}\index{cp=\texttt{cp}|(textbf}
|
||||
|
||||
@@ -355,9 +543,20 @@ der Formate N, N-, N-M oder -M benutzt werden.
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_cut_beispiele.tex}
|
||||
|
||||
Praktisch das Gegenstück zu \texttt{cut} ist \texttt{paste}, damit werden
|
||||
Dateien in Spalten zusammengeführt. Nährers dazu in Abschnitt \ref{paste}.
|
||||
|
||||
\index{cut=\texttt{cut}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{diff}\label{diff}\index{diff=\texttt{diff}|(textbf}
|
||||
|
||||
TODO!!! diff
|
||||
|
||||
\index{diff=\texttt{diff}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{dirname}\label{dirname}\index{dirname=\texttt{dirname}|(textbf}
|
||||
|
||||
@@ -437,7 +636,72 @@ Arith\-me\-tik-Ex\-pan\-sion (Siehe \ref{arithmetikexpansion}).
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{find}\label{find}\index{find=\texttt{find}|(textbf}
|
||||
|
||||
TODO!!! find
|
||||
Auf einem modernen System sind nicht selten mehrere zehn- oder hunderttausend
|
||||
Dateien vorhanden. Um eine bestimmte Datei anhand komplexer Kriterien ausfindig
|
||||
zu machen benutzt man \texttt{find}.
|
||||
|
||||
Bei einem Aufruf wird zuerst das zu durchsuchende Verzeichnis, dann die
|
||||
Suchkriterien und eventuell abschließend die durchzuführenden Aktionen
|
||||
angegeben.
|
||||
|
||||
Die Angabe der Suchkriterien ist sehr vielseitig, hier werden nur die
|
||||
wichtigsten Optionen beschrieben. Wie immer empfehle ich das Studium der
|
||||
Man-Page oder eines entsprechenden Buches.
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_find_parameter.tex}
|
||||
|
||||
Die verschiedenen Suchkriterien können kombiniert werden. Mit \texttt{-a} oder
|
||||
\texttt{-o} erreicht man eine logische AND- bzw. OR-Verknüpfung, mit einem
|
||||
vorangestellten \texttt{!} können Kriterien negiert werden. Die AND-Verknüpfung
|
||||
muß nicht explizit angegeben werden, wenn mehrere Kriterien verwandt werden.
|
||||
Komplexere Ausdrücke können durch runde Klammern gruppiert werden, dabei ist
|
||||
jedoch deren Sonderbedeutung in der Shell entsprechend zu quoten (Siehe
|
||||
Abschnitt \ref{quoting}).
|
||||
|
||||
Bei der Angabe numerischer Parameter zu den Suchkriterien wird normalerweise
|
||||
nach dem exakten Wert gesucht. Statt eines einfachen \textsl{n} kann jedoch
|
||||
auch \textsl{+n} oder \textsl{-n} angegeben werden, damit wird dann nach
|
||||
Vorkommen größer bzw. kleiner als \textsl{n} gesucht.
|
||||
|
||||
Da die reine Beschreibung der Parameter manchmal etwas verwirrend ist, folgen
|
||||
hier ein paar praktische Beispiele:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
# Suche alle Einträge in bzw. unter dem aktuellen Verzeichnis:
|
||||
find .
|
||||
# Suche alle normalen Dateien mit der Endung txt unter /home:
|
||||
find /home -type f -name \*.txt
|
||||
# Suche alle Einträge außer symbolischen Links, in die jeder schreiben darf:
|
||||
find / \! -type l -perm 777
|
||||
# Suche alle Dateien unter dem Homeverzeichnis, deren Größe 10000000 Bytes
|
||||
# übersteigt und gib sie ausführlich aus:
|
||||
find ~ -size +10000000c -exec ls -l {} \;
|
||||
# Suche alle Einträge im Homeverzeichnis, die innerhalb der letzten zwei Tage
|
||||
# geändert wurden:
|
||||
find ~ -mtime -2
|
||||
\end{listing}
|
||||
\normalsize
|
||||
|
||||
Wenn mittels \texttt{-exec} weitere Kommandos gestartet werden, sollte beachtet
|
||||
werden daß mindestens ein Prozeß pro Fundstelle gestartet wird. Das kostet sehr
|
||||
viel, unter Umständen macht der Einsatz von \texttt{xargs} (Abschnitt
|
||||
\ref{xargs}) Sinn.
|
||||
|
||||
Die Ausführung von \texttt{find} erzeugt unter Umständen sehr viel Last auf der
|
||||
Festplatte, bei Netzlaufwerken auch Netzwerkbandbreite. In einigen Fällen
|
||||
bieten sich alternative Suchverfahren an:
|
||||
|
||||
\textbf{Alternative 1:} Falls man den Namen der zu suchenden Datei kennt, und
|
||||
das Locate-System installiert ist kann man die Datei auch mittels
|
||||
\texttt{locate} suchen. Das ist ressourcenschonender, da nicht `live' das
|
||||
Filesystem durchforstet wird, sondern nur die Locate-Datenbank. Diese wird
|
||||
allerdings im Regelfall nur einmal täglich aktualisiert, die Suche taugt nicht
|
||||
für schnell wechselnde Bestände.
|
||||
|
||||
\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}).
|
||||
|
||||
Siehe auch: Abschnitt \ref{beispiele_suchen_dateien}.
|
||||
|
||||
@@ -473,11 +737,44 @@ werden allerdings nicht die letzten Zeilen angezeigt, sondern die ersten.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{kill}\label{kill}\index{kill=\texttt{kill}|(textbf}
|
||||
|
||||
TODO!!! kill
|
||||
Die landläufige Annahme ist, daß man mit dem \texttt{kill}-Kom\-man\-do
|
||||
Prozesse `umbringt'. Das ist zwar wahr, aber nicht die ganze Wahrheit.
|
||||
|
||||
Übrigens: Die landläufige Annahme ist, daß man mit dem
|
||||
\texttt{kill}-Kom\-man\-do Prozesse `umbringt'. Das ist zwar wahr, aber nicht
|
||||
die ganze Wahrheit.
|
||||
Im Prinzip sendet \texttt{kill} lediglich ein Signal an einen Prozeß. Ohne
|
||||
weitere Parameter ist das tatsächlich ein SIGTERM, das den Prozeß im Regelfall
|
||||
dazu bewegt sich zu beenden. Jeder Admin kennt das Verfahren, einem hängenden
|
||||
Prozeß mittels \texttt{kill -9} den Gnadenschuß zu geben. Die 9 steht dabei für
|
||||
das Signal mit der Nummer 9, SIGKILL. Noch ein gebräuchliches Signal ist SIGHUP
|
||||
(1), der `Hangup'. Historisch wurde das gesendet wenn die Leitung zum Rechner
|
||||
aufgelegt wurde, mittlerweile ist es gängige Praxis damit einen Daemon neu zu
|
||||
initialisieren.
|
||||
|
||||
Daneben stehen noch eine Reihe weiterer Signale zur Verfügung. Mit \texttt{kill
|
||||
-l} kann man sich eine Liste ansehen.
|
||||
|
||||
Es gibt verschiedene Wege, das Signal abzusetzen. Welchen man wählt ist
|
||||
Geschmackssache. Hier ein paar Beispiele:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
# Die folgenden Befehle sind gleichwertig. Alle senden ein HUP an Prozeß-ID 42:
|
||||
kill -1 42
|
||||
kill -HUP 42
|
||||
kill -SIGHUP 42
|
||||
kill -s 1 42
|
||||
kill -s HUP 42
|
||||
kill -s SIGHUP 42
|
||||
|
||||
# virtueller Selbstmord: Alle Prozesse umbringen, die man umbringen kann:
|
||||
kill -9 -1
|
||||
|
||||
# SIGTERM an mehrere Prozesse senden:
|
||||
kill 123 456 789
|
||||
\end{listing}
|
||||
\normalsize
|
||||
|
||||
Siehe auch: Das Beispiel `Fallensteller' in Abschnitt \ref{traps} zeigt, wie
|
||||
ein Skript auf Signale reagieren kann.
|
||||
|
||||
\index{kill=\texttt{kill}|)}
|
||||
|
||||
@@ -509,14 +806,45 @@ zur Verf
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{ls}\label{ls}\index{ls=\texttt{ls}|(textbf}
|
||||
|
||||
Den Inhalt von Verzeichnissen im Dateisystem bringt man mit \texttt{ls} in
|
||||
Erfahrung. Ein einfacher Aufruf listet lediglich die Dateinamen im aktuellen
|
||||
oder angegebenen Verzeichnis auf, das Kommando hat aber auch sehr viele
|
||||
Parameter mit denen sich die Ausgabe anpassen läßt. Hier sind die wichtigsten,
|
||||
eine vollständige Auflistung bietet wie immer die Man-Page:
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_ls_parameter.tex}
|
||||
|
||||
Besonders informativ gibt sich der Parameter \texttt{-l}, da damit auch die
|
||||
Eigentümer und die Berechtigungen der Dateien angezeigt werden. Die Ausgabe hat
|
||||
die folgende Form:
|
||||
|
||||
\texttt{-rw-r--r-- 1 rschaten users 6252 Nov 19 14:14 shell.tex}
|
||||
|
||||
Die linke Spalte der Ausgabe zeigt die bestehenden Berechtigungen. Es ist ein
|
||||
Block in der Form `drwxrwxrwx'. An Stelle des d können auch andere Buchstaben
|
||||
stehen, hier wird der Dateityp angegeben, also ob es sich um eine einfache
|
||||
Datei (-), ein Verzeichnis (d), einen Link (l) oder ähnliches\footnote{Siehe
|
||||
Man-Page} handelt. An Stelle der rwx-Blöcke können auch Striche stehen, die
|
||||
stehen für nicht gesetzte Attribute.
|
||||
Man-Page} handelt. Die rwx-Blöcke geben die Dateiberechtigungen jeweils für den
|
||||
Besitzer, die Gruppe und andere User an. Dabei steht das r für read, w für
|
||||
write und x für execute. An ihrer Stelle können auch Striche stehen, die
|
||||
repräsentieren nicht gesetzte Attribute. Die Datei im Beispiel ist also für
|
||||
ihren Besitzer les- und schreibbar, für alle anderen nur lesbar. Die
|
||||
Berechtigungen werden mit dem Kommando \texttt{chmod} (Abschnitt \ref{chmod})
|
||||
gesetzt.
|
||||
|
||||
TODO!!! ls
|
||||
Die nächste Spalte stellt die Anzahl der Links dar, die auf diese Datei
|
||||
verweisen, im Beispiel existiert die Datei an nur einer Stelle im Filesystem.
|
||||
|
||||
Dann folgen der Benutzer und die Gruppe, denen die Datei gehört. Diese
|
||||
Parameter werden mit \texttt{chown} (Abschnitt \ref{chown}) bzw. \texttt{chgrp}
|
||||
(Abschnitt \ref{chgrp}) gesetzt.
|
||||
|
||||
Es folgt die Größe der Datei in Bytes, sowie das Datum der letzten Änderung.
|
||||
Liegt dieses mehr als ein halbes Jahr zurück wird an Stelle der Uhrzeit die
|
||||
Jahreszahl angegeben, es gilt also Vorsicht walten zu lassen, wenn dieser Wert
|
||||
in Skripten benutzt werden soll.
|
||||
|
||||
Abschließend wird der Name der jeweiligen Datei ausgegeben.
|
||||
|
||||
\index{ls=\texttt{ls}|)}
|
||||
|
||||
@@ -545,6 +873,25 @@ wird der Vorgang interaktiv, vor jeder Dateibewegung wird nachgefragt.
|
||||
\index{mv=\texttt{mv}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{paste}\label{paste}\index{paste=\texttt{paste}|(textbf}
|
||||
|
||||
Während mit \texttt{cut} (Abschnitt \ref{cut}) Dateien spaltenweise zerlegt
|
||||
werden, werden sie mit \texttt{paste} zusammengeführt. Die Dateinamen werden
|
||||
als Parameter übergeben, woraufhin Zeile für Zeile die Inhalte aller Dateien zu
|
||||
einer Tabelle gemacht werden.
|
||||
|
||||
Die Spalten werden standardmäßig durch Tabulatorzeichen getrennt, man kann mit
|
||||
dem Parameter \texttt{-d} auch ein oder mehrere andere Trennzeichen definieren.
|
||||
Werden mehrere Zeichen angegeben, werden sie der Reihe nach zum trennen der
|
||||
Spalten benutzt.
|
||||
|
||||
Mit \texttt{-s} wird die Tabelle transponiert, also praktisch um 90 Grad
|
||||
gedreht.
|
||||
|
||||
\index{paste=\texttt{paste}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf}
|
||||
|
||||
@@ -640,7 +987,65 @@ dazu steht im Abschnitt
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{ps}\label{ps}\index{ps=\texttt{ps}|(textbf}
|
||||
|
||||
TODO!!! ps
|
||||
Mit \texttt{ps} gibt man einen Schnappschuß des Zustandes der aktuell laufenden
|
||||
Prozesse aus\footnote{Wenn man interaktiv den Zustand der laufenden Prozesse
|
||||
beobachten möchte, benutzt man \texttt{top}, das eignet sich jedoch nicht zur
|
||||
Shell-Programmierung und wird deshalb nicht ausführlich beschrieben.}.
|
||||
|
||||
Ohne weitere Parameter listet \texttt{ps} alle Prozesse auf, die dem
|
||||
aufrufenden Benutzer gehören und die mit dem aktuellen Terminal assoziiert
|
||||
sind. Angezeigt werden dann die Prozeß-ID, das Terminal, die verbrauchte
|
||||
CPU-Zeit und der Name des laufenden Kommandos.
|
||||
|
||||
In Skripten möchte man üblicherweise feststellen, ob ein bestimmtes Kommando
|
||||
aktiv ist, ob also zum Beispiel ein bestimmter Serverdienst läuft. Dazu macht
|
||||
man \texttt{ps} über Optionen gesprächiger.
|
||||
|
||||
Das Kommando versteht in der GNU-Version zwei unterschiedliche Arten von
|
||||
Optionen. Den sogenannten Unix- bzw. Posix-Stil und den BSD-Stil. Zusätzlich
|
||||
gibt es noch ausführliche Parameter, aber die sollen hier nicht beschrieben
|
||||
werden. Die jeweiligen Formen stehen nicht auf allen Systemen zur Verfügung,
|
||||
wenn ein Skript beispielsweise auch unter Solaris benutzt werden soll ist man
|
||||
gezwungen, die Unix-Parametrisierung zu benutzen.
|
||||
|
||||
Unix-Parameter zeichnen sich durch die übliche Angabe mit Bindestrich aus.
|
||||
BSD-Pa\-ra\-me\-ter werden ohne Bindestrich angegeben, was neben den meisten
|
||||
anderen Kommandos etwas ungewohnt aussieht.
|
||||
|
||||
Es gibt sehr viele verschiedene Parameter, die beste Informationsquelle ist wie
|
||||
immer die Man-Page bzw. ein entsprechendes Buch. Hier werden nur ein paar
|
||||
typische Aufrufbeispiele gezeigt, deren Ausgabe sich jeder selber ansehen kann:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
# Alle Prozesse auflisten, Unix-Syntax:
|
||||
ps -e
|
||||
ps -ef
|
||||
ps -eF
|
||||
ps -ely
|
||||
|
||||
# Alle Prozesse auflisten, BSD-Syntax:
|
||||
ps ax
|
||||
ps axu
|
||||
|
||||
# Prozeßbaum ausgeben. Das ist in Skripten weniger Sinnvoll, wird hier aber
|
||||
# angegeben weil es so eine praktische Funktion ist... :-)
|
||||
ps -ejH
|
||||
ps axjf
|
||||
|
||||
# Alle Prozesse ausgeben, die nicht dem Benutzer `root' gehören:
|
||||
ps -U root -u root -N
|
||||
|
||||
# Nur die Prozeß-ID von Syslog ausgeben:
|
||||
ps -C syslogd -o pid=
|
||||
|
||||
# Nur den Namen des Prozesses mit der ID 42 ausgeben:
|
||||
ps -p 42 -o comm=
|
||||
\end{listing}
|
||||
\normalsize
|
||||
|
||||
Für die Suche nach Prozessen bestimmten Namens steht auf manchen Systemen auch
|
||||
das Kommando \texttt{pgrep} (Abschnitt \ref{pgrep}) zur Verfügung.
|
||||
|
||||
Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}.
|
||||
|
||||
@@ -755,7 +1160,203 @@ debuggen, da sowohl Ein- als auch Ausgaben in dem Logfile sichtbar sind.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{sed}\label{sed}\index{sed=\texttt{sed}|(textbf}
|
||||
|
||||
TODO!!! sed
|
||||
Der `Stream Editor' \texttt{sed} stellt, ähnlich wie \texttt{awk} (Abschnitt
|
||||
\ref{awk}) eigentlich eine eigene Skriptsprache dar. Er wird auch
|
||||
`nicht-interaktiver Editor' genannt. Die Kommandos sind minimalistisch, aber
|
||||
exakt auf die Aufgabe zugeschnitten.
|
||||
|
||||
\texttt{sed} liest Zeilenweise aus einer Datei, wenn keine Datei angegeben
|
||||
wurde wird von der Standard-Eingabe gelesen. Auf die eingelesenen Zeilen wird
|
||||
dann ein mehr oder weniger kompliziertes \texttt{sed}-Skript angewendet, bevor
|
||||
auf der Standard-Ausgabe die Resultate ausgegeben werden.
|
||||
|
||||
Eine vollständige Beschreibung von \texttt{sed} würde an dieser Stelle den
|
||||
Rahmen sprengen, es gibt aber im Handel gute Bücher zu dem Thema. Hier sollen
|
||||
nur die gängigsten Kommandos und einige Anwendungsbeispiele genannt werden.
|
||||
|
||||
\subsubsection{Aufruf}
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
# Aufruf als Stream-Editor:
|
||||
kommando1 | sed 's/alt/neu/' | kommando2
|
||||
|
||||
# Aufruf mit einer zu bearbeitenden Datei:
|
||||
sed 's/alt/neu/' datei.txt
|
||||
|
||||
# Wenn mehr als ein Kommando ausgeführt werden soll, muß der Parameter -e
|
||||
# verwendet werden:
|
||||
sed -e 's/alt/neu/' -e '/loeschen/d' datei.txt
|
||||
|
||||
# Man kann auch mehrere Kommandos mit einem -e aufrufen, wenn sie durch ein
|
||||
# Semikolon getrennt werden:
|
||||
sed 's/alt/neu/; /loeschen/d' datei.txt
|
||||
|
||||
# In einem Skript kann das Kommando auch über mehrere Zeilen gehen:
|
||||
sed '
|
||||
s/alt/neu/
|
||||
/loeschen/d' datei.txt
|
||||
|
||||
# Alternativ können die Kommandos auch in eine eigene Datei gespeichert und
|
||||
# über den Parameter -f eingebunden werden:
|
||||
sed -f script.sed datei.txt
|
||||
\end{listing}
|
||||
\normalsize
|
||||
|
||||
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
|
||||
mittels `p' explizit gefordert wird. Die GNU-Version stellt noch ein paar
|
||||
Parameter zur Verfügung, die Man-Page verrät näheres.
|
||||
|
||||
\subsubsection{Addressierung}
|
||||
|
||||
Durch die Adressierung können Befehle gezielt auf bestimmte Zeilen angewandt
|
||||
werden. Dabei können einem Befehl keine, eine oder zwei Adressen mitgegeben
|
||||
werden.
|
||||
|
||||
Wenn keine Zeilen adressiert werden, wirkt der Befehl auf alle Zeilen.
|
||||
|
||||
Wenn eine Adresse mitgegeben wird, wirkt der Befehl auf alle Zeilen die durch
|
||||
diese Adresse angesprochen werden. Das können, zum Beispiel bei einem regulären
|
||||
Ausdruck, auch mehrere Zeilen sein.
|
||||
|
||||
Werden zwei Adressen angegeben, wirkt der Befehl auf die erste betroffene
|
||||
Zeile, sowie auf alle weiteren bis zur zweiten angegebenen Zeile. Die beiden
|
||||
Adressen müssen durch ein Komma getrennt angegeben werden.
|
||||
|
||||
Die Auswahl der Zeilen kann durch ein an die Adresse angehängtes Rufzeichen
|
||||
negiert werden, der Befehl wirkt dann also auf alle Zeilen die \textbf{nicht}
|
||||
adressiert wurden.
|
||||
|
||||
Aber wie sehen solche Adreßangeben aus? Die folgende Tabelle zeigt einige
|
||||
Beispiele anhand des Kommandos `d', mit dem Zeilen gelöscht werden:
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_sed_adressen.tex}
|
||||
|
||||
Adressen können auch vor geschweiften Klammern stehen, dann wirken sie auf die
|
||||
komplette Befehlsfolge innerhalb der Klammern.
|
||||
|
||||
\subsubsection{Kommandos}
|
||||
|
||||
Es gibt eine ganze Reihe von Kommandos, diese Beschreibung konzentriert sich
|
||||
aber auf die wichtigsten `Brot und Butter-Kommandos'. In den Beispielen weiter
|
||||
unten kommen auch andere Kommandos vor, die können bei Bedarf anhand der
|
||||
einschlägigen Quellen nachgeschlagen werden.
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_sed_kommandos.tex}
|
||||
|
||||
Mit \texttt{s} wird substituiert. Das heißt, in der Eingabezeile wird nach
|
||||
einem Muster gesucht, und im Erfolgsfall wird es ersetzt. Wichtigster
|
||||
Modifikator für dieses Kommando ist \texttt{g}, damit wird `global' ersetzt,
|
||||
falls mehrere Fundstellen in einer Zeile vorkommen. Der Aufruf sieht wie folgt
|
||||
aus:
|
||||
|
||||
\texttt{s/Suchmuster/Ersatzmuster/g}
|
||||
|
||||
Im Ersatzmuster können auch Teile der Fundstelle wieder vorkommen, wenn sie
|
||||
durch Klammern in einen Puffer kopiert werden:
|
||||
|
||||
\texttt{s/Seite ([0-9]*) von ([0-9]*)/\textbackslash{}1 aus \textbackslash{}2/}
|
||||
|
||||
Mit \texttt{y} hingegen werden einzelne Buchstaben durch andere vertauscht. Das
|
||||
folgende Kommando wandelt alle eingehenden Kleinbuchstaben in Großbuchstaben
|
||||
um\footnote{Umlaute und Sonderzeichen ausgeschlossen}:
|
||||
|
||||
\texttt{y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/}
|
||||
|
||||
Normalerweise werden alle Eingabezeilen nach der Bearbeitung wieder ausgegeben,
|
||||
unabhängig davon ob sie verändert wurden oder nicht. Das Verhalten kann über
|
||||
den Kommandozeilenparameter \texttt{-n} abgeschaltet werden. Da dann allerdings
|
||||
nichts mehr ausgegeben wird kann durch ein an ein Kommando angehängtes
|
||||
\texttt{p} bestimmt werden, daß die Veränderten Zeilen~--~und nur
|
||||
die~--~ausgegeben werden.
|
||||
|
||||
\subsubsection{Beispiele}
|
||||
|
||||
Da es in diesem Text nicht um \texttt{sed}-Skripte, sondern um Shell-Skripte
|
||||
gehen soll werden hier keine komplexen Sachen vorgestellt, sondern nur ein paar
|
||||
Einzeiler. Nichtsdestotrotz können es auch diese unscheinbaren Aufrufe in sich
|
||||
haben.
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
### SUCHEN UND ERSETZEN
|
||||
|
||||
# Im kompletten Text 'rot' durch 'blau' ersetzen:
|
||||
sed 's/rot/blau/' # Ersetzt nur das erste Vorkommen in jeder Zeile
|
||||
sed 's/rot/blau/4' # Ersetzt nur das vierte Vorkommen in jeder Zeile
|
||||
sed 's/rot/blau/g' # Ersetzt nur jedes Vorkommen in jeder Zeile
|
||||
|
||||
# 'rot' durch 'blau' ersetzen, aber NUR in Zeilen die auch 'gelb' enthalten:
|
||||
sed '/gelb/s/rot/blau/g'
|
||||
|
||||
# 'rot' durch 'blau' ersetzen, AUSSER in Zeilen die auch 'gelb' enthalten:
|
||||
sed '/gelb/!s/rot/blau/g'
|
||||
|
||||
# 'rosa', 'hellrot' und 'magenta' durch 'pink' ersetzen:
|
||||
sed 's/rosa/pink/g;s/hellrot/pink/g;s/magenta/pink/g'
|
||||
gsed 's/rosa\|hellrot\|magenta/pink/g' # nur in GNU sed
|
||||
|
||||
# Jede Zeile um fünf Leerzeichen einrücken:
|
||||
# lies: 'ersetze jeden Zeilenanfang durch fünf Leerzeichen'
|
||||
sed 's/^/ /'
|
||||
|
||||
# Führende Blanks (Leerzeichen, Tabulatoren) von den Zeilenanfängen löschen:
|
||||
# ACHTUNG: An Stelle des \t muß der Tabulator gedrückt werden, die Darstellung
|
||||
# als \t versteht nicht jedes sed!
|
||||
sed 's/^[ \t]*//'
|
||||
|
||||
# Schliessende Blanks vom Zeilenende löschen, siehe oben:
|
||||
sed 's/[ \t]*$//'
|
||||
|
||||
# Führende und schließende Blanks löschen:
|
||||
sed 's/^[ \t]*//;s/[ \t]*$//'
|
||||
|
||||
# Wenn eine Zeile mit Backslash aufhört den Zeilenumbruch entfernen:
|
||||
sed -e :a -e '/\\$/N; s/\\\n//; ta'
|
||||
|
||||
### BESTIMMTE ZEILEN AUSGEBEN
|
||||
|
||||
# Nur Zeile 42 ausgeben:
|
||||
sed -n '42p' # Methode 1
|
||||
sed '42!d' # Methode 2
|
||||
|
||||
# Nur die Zeilen 23-42 ausgeben (inklusive):
|
||||
sed -n '23,42p' # Methode 1
|
||||
sed '23,42!d' # Methode 2
|
||||
|
||||
# Von einem regulären Ausdruck bis zum Dateiende ausgeben:
|
||||
sed -n '/regexp/,$p'
|
||||
|
||||
# Den Bereich zwischen zwei regulären Ausdrücken ausgeben (inklusive):
|
||||
sed -n '/rot/,/blau/p'
|
||||
|
||||
# Nur Zeilen mit mindestens 42 Zeichen ausgeben:
|
||||
sed -n '/^.\{42\}/p'
|
||||
|
||||
# Nur Zeilen mit höchstens 42 Zeichen ausgeben:
|
||||
sed -n '/^.\{42\}/!p' # Methode 1, analog zu oben
|
||||
sed '/^.\{42\}/d' # Methode 2, einfachere Syntax
|
||||
|
||||
### BESTIMMTE ZEILEN LÖSCHEN
|
||||
|
||||
# Die ersten zehn Zeilen löschen:
|
||||
sed '1,10d'
|
||||
|
||||
# Die letzte Zeile löschen:
|
||||
sed '$d'
|
||||
|
||||
# Alles außer dem Bereich zwischen zwei regulären Ausdrücken ausgeben:
|
||||
sed '/rot/,/blau/d'
|
||||
|
||||
# Alle Leerzeilen löschen:
|
||||
sed '/^$/d' # Methode 1
|
||||
sed '/./!d' # Methode 2
|
||||
|
||||
# Alle Leerzeilen am Dateianfang löschen:
|
||||
sed '/./,$!d'
|
||||
\end{listing}
|
||||
\normalsize
|
||||
|
||||
\index{sed=\texttt{sed}|)}
|
||||
|
||||
@@ -882,6 +1483,113 @@ Referenzdatei angepa
|
||||
\index{touch=\texttt{touch}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{tr}\label{tr}\index{tr=\texttt{tr}|(textbf}
|
||||
|
||||
Will man ganze Worte oder komplexe Muster in Dateien oder Pipes suchen und
|
||||
ersetzen, greift man üblicherweise zu \texttt{sed} (Abschnitt \ref{sed}). Für
|
||||
einzelne Buchstaben nimmt man hingegen \texttt{tr}.
|
||||
|
||||
Normalerweise wird \texttt{tr} mit zwei Zeichenketten als Parametern
|
||||
aufgerufen und übernimmt die zu konvertierenden Daten von der Standard-Eingabe.
|
||||
Jedes Zeichen im eingehenden Datenstrom wird anhand der beiden Zeichenketten
|
||||
ersetzt, dabei wird das erste Zeichen der ersten Kette durch das erste Zeichen
|
||||
der zweiten Kette ersetzt, das zweite durch das zweite, und so weiter.
|
||||
|
||||
Ist die zweite Zeichenkette länger als die erste, werden überschüssige Zeichen
|
||||
ignoriert. Ist die zweite Zeichenkette kürzer als die erste, wird ihr letztes
|
||||
Zeichen so lange wiederholt bis sie gleich sind. Durch den Parameter
|
||||
\texttt{-t} kann dieses Verhalten abgeschaltet werden, so daß überschüssige
|
||||
Zeichen abgeschnitten werden.
|
||||
|
||||
Mit dem Parameter \texttt{-c} wird die erste Zeichenkette `invertiert', es
|
||||
werden also alle Zeichen ersetzt die nicht darin vorkommen.
|
||||
|
||||
\texttt{tr} kann aber auch mit nur einer Zeichenkette aufgerufen werden, wenn
|
||||
die Parameter \texttt{-d} oder \texttt{-s} benutzt werden. Mit \texttt{-d}
|
||||
werden alle Zeichen aus dem Eingabestrom gelöscht, die in der Zeichenkette
|
||||
vorkommen. Mit \texttt{-s} werden doppelt vorkommende Zeichen durch ein
|
||||
einzelnes ersetzt.
|
||||
|
||||
Die Zeichenketten an sich können übrigens nicht nur Buchstaben oder Zahlen
|
||||
enthalten, sondern auch Sonderzeichen oder Zeichenklassen. Näheres dazu steht
|
||||
in der Man-Page.
|
||||
|
||||
Die folgenden Beispiele verdeutlichen die Anwendung:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
text="Dies ist ein Testtext"
|
||||
|
||||
# kleine Umlaute durch grosse ersetzen:
|
||||
echo "$text" | tr aeiou AEIOU
|
||||
# -> DIEs Ist EIn TEsttExt
|
||||
|
||||
# Kleinbuchstaben durch Großbuchstaben ersetzen:
|
||||
echo "$text" | tr a-z A-Z
|
||||
# -> DIES IST EIN TESTTEXT
|
||||
|
||||
# alle Vokale durch Unterstriche ersetzen:
|
||||
echo "$text" | tr aeiouAEIOU _
|
||||
# -> D__s _st __n T_stt_xt
|
||||
|
||||
# Großbuchstaben löschen:
|
||||
echo "$text" | tr -d A-Z
|
||||
# -> ies ist ein esttext
|
||||
|
||||
# doppelte Buchstaben löschen:
|
||||
echo "$text" | tr -s "a-zA-Z"
|
||||
# -> Dies ist ein Testext
|
||||
|
||||
# doppelte Buchstaben löschen, mit Zeichenklasse:
|
||||
echo "$text" | tr -s "[:alpha:]"
|
||||
# -> Dies ist ein Testext
|
||||
\end{listing}
|
||||
\normalsize
|
||||
|
||||
\index{tr=\texttt{tr}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{trap}\label{trap}\index{trap=\texttt{trap}|(textbf}
|
||||
|
||||
Wie alle anderen Prozesse in einem Unix-System auch, so können auch
|
||||
Shell-Skripte Signale empfangen. Diese können durch Kommandos wie \texttt{kill}
|
||||
(Abschnitt \ref{kill}) geschickt worden sein, oder zum Beispiel durch einen
|
||||
Tastatur-Interrupt.
|
||||
|
||||
Mit \texttt{trap} kann ein Skript darauf vorbereitet werden, ein oder mehrere
|
||||
Signale zu empfangen. Beim Aufruf wird eine Aktion mitgegeben, und eine oder
|
||||
mehrere Bedingungen die zum Ausführen der Aktion führen sollen. Das folgende
|
||||
Kommando gibt zm Beispiel eine Fehlermeldung aus wenn sein Skript ein Signal 1
|
||||
(HUP), 2 (INT) oder 15 (TERM) erhält:
|
||||
|
||||
\texttt{trap 'echo \dq`basename \$0`: Ooops...\dq 1>\&2' 1 2 15}
|
||||
|
||||
Die Zeile ist dem Beispiel aus Abschnitt \ref{traps} entnommen, dort findet
|
||||
sich auch nochmal eine ausführliche Erklärung.
|
||||
|
||||
\index{trap=\texttt{trap}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{uniq}\label{uniq}\index{uniq=\texttt{uniq}|(textbf}
|
||||
|
||||
Mit dem Kommando \texttt{uniq} werden doppelt vorkommende Zeilen in einer
|
||||
Eingabedatei oder der eingehenden Pipe (Standard-Eingabe) bearbeitet. Per
|
||||
default steht `bearbeitet' an dieser Stelle für `gelöscht', aber durch
|
||||
Parameter kann dieses Verhalten angepaßt werden:
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_uniq_parameter.tex}
|
||||
|
||||
Achtung: \texttt{uniq} betrachtet beim Vergleich nur direkt aufeinander
|
||||
folgende Zeilen. Sollen alle Duplikate Dateiweit betrachtet werden, bietet sich
|
||||
ein `vorsortieren' mit \texttt{sort} (Abschnitt \ref{sort}) an, vielleicht
|
||||
sogar ausschließlich ein \texttt{sort -u}.
|
||||
|
||||
\index{uniq=\texttt{uniq}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{wc}\label{wc}\index{wc=\texttt{wc}|(textbf}
|
||||
|
||||
@@ -898,6 +1606,19 @@ Der Parameter \texttt{-L} gibt die L
|
||||
\index{wc=\texttt{wc}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{which}\label{which}\index{which=\texttt{which}|(textbf}
|
||||
|
||||
Sucht im Pfad (vordefinierte Variable
|
||||
\texttt{\$PATH}\index{\$PATH=\texttt{\$PATH}}, siehe Abschnitt
|
||||
\ref{vordefinierte_variablen}) nach einer Ausführbaren Datei. Wenn mehrere
|
||||
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.
|
||||
|
||||
\index{which=\texttt{which}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{who}\label{who}\index{who=\texttt{who}|(textbf}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user