Viele grosse Aenderungen

This commit is contained in:
rschaten
2004-11-19 12:09:34 +00:00
parent 14dec49967
commit fe58ca9711
10 changed files with 225 additions and 93 deletions

View File

@@ -1,10 +1,10 @@
% $Id$
\chapter{Nützliche Shell-Kommandos}\label{nuetzliche_shell-kommandos}
Durch die gezeigten Steuerungsmöglichkeiten stehen dem Shell-Pro\-grammie\-rer
Möglichkeiten offen, fast alle gängigen Algorithmen zu implementieren. Es ist
tatsächlich in der Shell möglich, Sortier- oder Suchfunktionen zu schreiben.
Leider kommt aber an dieser Stelle einer der bedeutendsten Nachteile der Shell
zum tragen: Die Geschwindigkeit.
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
schreiben. Leider kommt aber an dieser Stelle einer der bedeutendsten
Nachteile der Shell zum tragen: Die Geschwindigkeit.
In einem Shell-Skript wird für jedes externe Kommando\footnote{Externe
Kommandos sind solche, die nicht direkt in der Shell enthalten sind, für die
@@ -16,9 +16,9 @@ schreibt man besser in Perl, oder noch besser in einer `compilierten' Sprache
wie C oder C++.
Es stehen jedoch an der Shell viele sehr nützliche externe Kommandos zur
Vergung, die einem die Entwicklung entsprechender eigener Routinen ersparen.
Diese externen Kommandos sind zudem in anderen Sprachen geschrieben worden, so
daß sie schneller ablaufen als jedes Shell-Skript. Man kommt als
Ver\-\-gung, die einem die Entwicklung entsprechender eigener Routinen
ersparen. Diese externen Kommandos sind zudem in anderen Sprachen geschrieben
worden, so daß sie schneller ablaufen als jedes Shell-Skript. Man kommt als
Shell-Programmierer nicht sinnvoll um den Einsatz dieser Programme herum.
In diesem Abschnitt sollen einige dieser Programme mit typischen
@@ -66,7 +66,7 @@ Dateien auf der Festplatte.
\item \texttt{echo} (\ref{echo}): Daten ausgeben
\item \texttt{grep} (\ref{grep}): In Dateien suchen
\item \texttt{head} (\ref{head}): Dateianfang ausgeben
\item \texttt{printf} (\ref{printf}): formatierte Datenausgabe
\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
@@ -261,8 +261,8 @@ Hier wird der Modus gesteuert, indem direkt angegeben wird f
Rechte gelten sollen. Mit `+' werden die Rechte erweitert, `-' nimmt Rechte
und mit `=' werden die Rechte hart gesetzt.
\texttt{chmod u+x datei} macht die Datei für den Besitzer ausführbar. Mit
\texttt{chmod u=rw,go=r datei} werden die Rechte auf `rw-r--r--' gesetzt, der
\texttt{chmod u+x datei} macht die Datei für den Besitzer ausführbar. Mit dem
Parameter \texttt{u=rw,go=r} werden die Rechte auf `rw-r--r--' gesetzt, der
Besitzer kann lesen und schreiben, alle anderen nur lesen.
Neben dieser Art der Notation gibt es noch eine~--~wesentlich
@@ -302,7 +302,7 @@ Will man lediglich die Gruppen-ID
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{chpasswd}\label{script}\index{chpasswd=\texttt{chpasswd}|(textbf}
\subsection{chpasswd}\index{chpasswd=\texttt{chpasswd}|(textbf}
Mit diesem Kommando bietet sich dem Administrator des Systems die
Mög\-lich\-keit, scriptgesteuert die Paßwörter für neue Benutzer zu vergeben.
@@ -388,7 +388,24 @@ der Praxis oft als sehr hilfreich:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{eval}\label{eval}\index{eval=\texttt{eval}|(textbf}
TODO!!! eval
Die Wirkungsweise von \texttt{eval} läßt sich wohl am ehesten durch ein kleines
Beispiel erklären:
\LTXtable{\textwidth}{tab_kommandos_eval_beispiel.tex}
Bevor eine Zeile in der Shell tatsächlich ausgeführt wird, wird sie von der
Shell expandiert, bzw. evaluiert. Der letzte Begriff deutet schon an was damit
gemeint ist: Enthaltene Variablennamen werden durch ihre Werte ersetzt.
Das Kommando \texttt{eval} führt die Zeile die durch die Expansion entstanden
ist noch einmal aus. So ist es möglich, Variablennamen aus den Inhalten anderer
Variablen zu bilden.
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
beispielsweise mittels \texttt{eval echo \textbackslash\$arr\$index} ausgegeben
werden, dabei ist \texttt{arr} der Name des Arrays und \texttt{index} der Name
der Variablen, die den Index des auszugebenden Elementes enthält.
\index{eval=\texttt{eval}|)}
@@ -412,7 +429,7 @@ sie sind also durch Anf
\texttt{i=`expr \$i \textbackslash{}* 3`}.
Eine andere Möglichkeit für einfache Rechnungen besteht in der sogenannten
Arithmetik-Expansion (Siehe \ref{arithmetikexpansion}).
Arith\-me\-tik-Ex\-pan\-sion (Siehe \ref{arithmetikexpansion}).
\index{expr=\texttt{expr}|)}
@@ -583,7 +600,39 @@ steht.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{printf}\label{printf}\index{printf=\texttt{printf}|(textbf}
TODO!!! printf
Analog zum gleichnamigen Befehl in Programmiersprachen wie Perl oder C dient
\texttt{printf} der formatierten Ausgabe von Daten. Als Parameter wird ein
sogenannter Format-String und eine Liste von auszugebenden Daten mitgegeben.
Dabei enthält der Format-String eine Reihe von Platzhaltern, die nach
bestimmten Regeln durch die Daten ersetzt werden.
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}.
Hier die wichtigsten Parameter für den Format-String:
\LTXtable{\textwidth}{tab_kommandos_printf_parameter.tex}
Besonders nützlich ist dieses Kommando bei der tabellarischen Ausgabe von
Daten. Im folgenden Beispiel werden alle Benutzernamen, deren
Home-Verzeichnisse und Default-Shells aus der Datei \texttt{/etc/passwd}
extrahiert und übersichtlich ausgegeben:
\footnotesize
\begin{listing}[2]{1}
#!/bin/sh
IFS=:
while read user pass uid gid name home shell; do
printf "%-15s %-25s %s\n" $user $home $shell
done < /etc/passwd
\end{listing}
\normalsize
Zur Erinnerung: Die vordefinierte Variable
\texttt{\$IFS}\index{\$IFS=\texttt{\$IFS}} ist der Feld-Separator, die
Eingabezeilen werden also als Doppelpunkt-separierte Liste gesehen. Näheres
dazu steht im Abschnitt über vordefinierte Variablen
(\ref{vordefinierte_variablen}).
\index{printf=\texttt{printf}|)}
@@ -609,8 +658,9 @@ Variablennamen wird der verbleibende Rest der Eingabezeile zugewiesen. Wenn
also nur ein Variablenname angegeben wird, erhält dieser die komplette
Eingabezeile. Wenn weniger Worte gelesen werden als Variablen angegeben sind,
enthalten die verbleibenden Variablen leere Werte. Als Wort-Trennzeichen dienen
alle Zeichen, die in der vordefinierten Variable \texttt{\$IFS} enthalten sind
(siehe Seite \pageref{IFS}).
alle Zeichen, die in der vordefinierten Variable
\texttt{\$IFS}\index{\$IFS=\texttt{\$IFS}} enthalten sind (siehe Abschnitt
\ref{vordefinierte_variablen}).
Wenn keine Variablennamen angegeben werden, wird die Eingabe in der Variable
\texttt{REPLY} abgelegt.
@@ -657,8 +707,8 @@ Timeout oder ein EOF auf.
Mit diesem Kommando können Dateien und Verzeichnisse gelöscht werden. Dabei
kann man vorsichtig vorgehen, indem man mit \texttt{-i} dafür sorgt, daß jeder
Löschvorgang bestätigt werden muß. Oder rabiat, indem man mit \texttt{-f} das
Löschen erzwingt.
Löschvorgang be\-stä\-tigt werden muß. Oder rabiat, indem man mit \texttt{-f}
das Löschen erzwingt.
Verzeichnisse können mit dem Parameter \texttt{-R} entfernt werden, im
Gegensatz zu \texttt{rmdir} werden dann auch sämtliche enthaltenen Dateien und
@@ -851,7 +901,8 @@ Der Parameter \texttt{-L} gibt die L
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{who}\label{who}\index{who=\texttt{who}|(textbf}
TODO!!! who
Das Kommando \texttt{who} gibt eine Liste aller angemeldeten Benutzer, zusammen
mit deren aktueller Konsole und der Anmeldezeit aus.
\index{who=\texttt{who}|)}
@@ -859,6 +910,34 @@ TODO!!! who
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{xargs}\label{xargs}\index{xargs=\texttt{xargs}|(textbf}
TODO!!! xargs
Bisweilen kommt man in die Verlegenheit, versehentlich zu lange Einzeiler
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
'text' \$(find / -name \textbackslash*.txt)}'. Dieses Kommando sucht alle
Dateien mit der Endung txt, die im System vorhanden sind. Diese werden `in 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
unterscheidet sich von System zu System}.
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
in der Form `\texttt{find / -name \textbackslash*.txt -exec grep 'text' \{\}
\textbackslash;}'. Allerdings hätte das den Nachteil, daß für jede gefundene
Datei ein neuer \texttt{grep} gestartet werden muß. Das kostet Resourcen.
Beide Probleme werden durch eine Zeile in der Form `\texttt{find / -name
\textbackslash*.txt | xargs grep 'text'}' umgangen. Dabei liest \texttt{xargs}
aus der Standardeingabe die Parameter, die dann an den \texttt{grep}-Aufruf
angehängt werden. Sollten zu viele Dateien gefunden werden, wird \texttt{grep}
mehrfach aufgerufen, allerdings im Gegensatz zum obigen Beispiel nicht einmal
pro Fundstelle.
Neben einigen anderen Parametern informiert die Manpage über die Option
\texttt{-r}. Damit kann vermieden werden, daß \texttt{xargs} das Kommando
startet wenn keine Eingabe vorhanden ist. Bezogen auf das angegebene Beispiel
würde \texttt{grep} ohne Dateinamen gestartet, wenn \texttt{find} nichts
findet. Es würde auf Input von der Standardeingabe warten, der aber
wahrscheinlich nicht kommt. Das Skript würde hängen, wenn der Parameter
\texttt{-r} nicht angewandt würde.
\index{xargs=\texttt{xargs}|)}