From fe58ca9711cfa8204869e0d3f7a7deb512c473bd Mon Sep 17 00:00:00 2001 From: rschaten Date: Fri, 19 Nov 2004 12:09:34 +0000 Subject: [PATCH] Viele grosse Aenderungen --- beispiele.tex | 2 +- schmutzige_tricks.tex | 6 +- shell.tex | 88 ++++++++------------- tab_kommandos_eval_beispiel.tex | 19 +++++ tab_kommandos_printf_parameter.tex | 15 ++++ tab_quoting_sonderzeichen.tex | 3 +- tab_vordefinierte_variablen.tex | 1 + was_ist_die_shell.tex | 7 +- werkzeugkasten.tex | 119 ++++++++++++++++++++++++----- wie_sieht_ein_shell_skript_aus.tex | 58 +++++++++++--- 10 files changed, 225 insertions(+), 93 deletions(-) create mode 100644 tab_kommandos_eval_beispiel.tex create mode 100644 tab_kommandos_printf_parameter.tex diff --git a/beispiele.tex b/beispiele.tex index 162482b..021027a 100644 --- a/beispiele.tex +++ b/beispiele.tex @@ -442,7 +442,7 @@ schon}\texttt{\dq} Der Grund dafür ist, daß unter Umständen in der Ausgabe von \texttt{ps} auch das \texttt{grep}-Kommando samt Parameter (\textit{prozessname}) aufgelistet -wird. So findet das \texttt{grep}-Kommando sich quasi selbst. +wird. So findet das \texttt{grep}-Kom\-man\-do sich quasi selbst. Abhilfe schafft entweder \texttt{pgrep} (\ref{pgrep}) oder das folgende Konstrukt: diff --git a/schmutzige_tricks.tex b/schmutzige_tricks.tex index 24e635e..a3760eb 100644 --- a/schmutzige_tricks.tex +++ b/schmutzige_tricks.tex @@ -74,9 +74,9 @@ echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen Was ist passiert? Dieses Skript besteht im Wesentlichen aus einer Pipe. Wir haben ein -\texttt{cat}-Kommando, 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. +\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 diff --git a/shell.tex b/shell.tex index d8b9d78..1191428 100644 --- a/shell.tex +++ b/shell.tex @@ -7,36 +7,20 @@ % Vorspann %============================================================================== -\newif\ifpdf % Feststellen, ob wir PDF oder DVI - % erzeugen -\ifx\pdfoutput\undefined - \pdffalse % Wir haben kein PDFLaTeX -\else - \pdftrue % Wir haben PDFLaTeX -\fi - -\ifpdf % PDF-Einstellungen - \pdfoutput=1 - \pdfcompresslevel=9 - \pdfinfo{ - /Author (Ronald Schaten) - /CreationDate (D:20000301170300) % (D:YYYYMMDDhhmmss) -% /ModDate (D:19980212201000) % ModDate is similar - /Title (Shell-Programmierung) - /Subject (Shell-Programmierung) - /Keywords (Shell) - } - \pdfcatalog{ % Catalog dictionary of PDF output. - /PageMode /UseOutlines - /URI (http://www.fi.muni.cz/) - } -\else % Nicht-PDF-Einstellungen -\fi - % Dokumentstil für Buch -\documentclass[a4paper,12pt,draft,twoside]{book} +\documentclass[ + a4paper, % Seitenformat A4 + 12pt, % 12-Punkt-Schrift + BCOR.5cm, % 0,5cm Rand für die Bindung + headsepline, % Trennlinie unter die Kopfzeile + pointlessnumbers, % Keine Punkte hinter den + % Gliederungsnummern +% draft, % Entwurfsmodus + final, % Release-Modus + twoside % Doppelseitig, für Buch +]{scrbook} + \usepackage{german} % deutsches Paket für Umlaute -%\usepackage{t1enc} % DC-Font mit 8 Bit verwenden \usepackage[latin1]{inputenc} % Codepage latin1 %\usepackage{graphicx} % Grafikpaket für Bilder laden @@ -47,11 +31,6 @@ \usepackage{supertabular} % für Tabellen über die Seitenbreite \usepackage{ltxtable} % für Tabellen über die Seitenbreite -\ifpdf % PDF-Einstellungen - \usepackage{thumbpdf} -\else % Nicht-PDF-Einstellungen -\fi - \usepackage{makeidx} % Index wird später eingefügt \makeindex % durch \printindex @@ -59,24 +38,28 @@ \usepackage{fancybox} % Kästchen für Tastendarstellung -\usepackage{fancyhdr} % Kopf- und Fußzeilen -\pagestyle{fancy} -\renewcommand{\chaptermark}[1]{\markboth{#1}{}} -\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} -\fancyhf{} -\fancyhead[RE]{\bfseries\leftmark} -\fancyhead[LO]{\bfseries\rightmark} -\fancyhead[RO,LE]{\bfseries\thepage} -\renewcommand{\headrulewidth}{0.5pt} -\addtolength{\headheight}{2.5pt} -\fancypagestyle{plain}{ - \fancyhead{} - \renewcommand{\headrulewidth}{0pt} - \fancyfoot[C]{\bfseries\thepage} -} - \usepackage{moreverb} % Für Listings + % Für PDF +\usepackage[ + pdftitle = {Shell-Programmierung}, + pdfsubject = {Programmierung~der~Unix-Shell}, + pdfkeywords = {shell~programmierung}, + pdfauthor = {Ronald~Schaten}, + bookmarks, + bookmarksopen, + bookmarksopenlevel = 1, + bookmarksnumbered, + linktocpage, + colorlinks, + linkcolor = black +]{hyperref} + +%\pdfinfo{/CreationDate (D:20000301170300-01'00')} % (D:YYYYMMDDhhmmss) + +%% /ModDate (D:19980212201000) % ModDate is similar + + \newcommand{\STRUT}{\rule{0in}{3ex}} % Ein vertikaler Abstand für Tabellen \clubpenalty=10000 % gegen Schusterjungen @@ -142,7 +125,7 @@ R \normalsize \newpage \pagenumbering{roman} -\renewcommand{\headrulewidth}{0.5pt} +%\renewcommand{\headrulewidth}{0.5pt} \setcounter{tocdepth}{3} \tableofcontents \newpage @@ -167,11 +150,6 @@ R \end{document} -\ifpdf % PDF-Einstellungen - \bye -\else % Nicht-PDF-Einstellungen -\fi - %============================================================================== % Ende von schema.tex %============================================================================== diff --git a/tab_kommandos_eval_beispiel.tex b/tab_kommandos_eval_beispiel.tex new file mode 100644 index 0000000..2a2ad6c --- /dev/null +++ b/tab_kommandos_eval_beispiel.tex @@ -0,0 +1,19 @@ +% $Id$ +\begin{longtable}{|l|X|} +% KILLED & LINE!!!! \kill + \hline + \endfirsthead + \endhead + \endfoot + \hline + \endlastfoot + +\texttt{foo=42} & Der Variablen namens `foo' wird der Wert `42' zugewiesen. \tabularnewline\STRUT +\texttt{a=foo} & Der Variablen namens `a' wird der Wert `foo' zugewiesen. \tabularnewline\STRUT +\texttt{b='\$'\$a} & Der Variablen `b' wird ein \$ und der Inhalt der Variablen namens `a' zugewiesen. \tabularnewline\STRUT +\texttt{echo \$b} & Der Inhalt der Variablen `b' wird ausgegeben. \tabularnewline\STRUT +\textsl{\$foo} & \tabularnewline\STRUT +\texttt{eval b='\$'\$a} & Zunächst wird die Zeile nach dem \texttt{eval} expandiert, Variablen werden durch Inhalte ersetzt. Es entsteht also ein neuer Ausdruck: `b=\$foo'. Der wird dann von \texttt{eval} ausgeführt. \tabularnewline\STRUT +\texttt{echo \$b} & Der neue Inhalt der Variablen `b' wird ausgegeben. \tabularnewline\STRUT +\textsl{42} & +\end{longtable} diff --git a/tab_kommandos_printf_parameter.tex b/tab_kommandos_printf_parameter.tex new file mode 100644 index 0000000..03f4bc7 --- /dev/null +++ b/tab_kommandos_printf_parameter.tex @@ -0,0 +1,15 @@ +% $Id$ +\begin{longtable}{|l|X|} +% KILLED & LINE!!!! \kill + \hline + \endfirsthead + \endhead + \endfoot + \hline + \endlastfoot + +\texttt{\%b} & Behandelt die Ausgabe von Backslash-Sequenzen. Die Sequenzen sind im Abschnitt über \texttt{echo} (\ref{echo}) beschrieben. \tabularnewline\STRUT +\texttt{\%s} & Gibt den nächsten Datenstring aus \tabularnewline\STRUT +\texttt{\%}\textsl{n}\texttt{\$s} & Gibt den \textsl{n}-ten Datenstring aus \tabularnewline\STRUT +\texttt{\%[-]}\textsl{m}\texttt{[.}\textsl{n}\texttt{]s} & Gibt den nächsten String aus, dazu wird ein Platz von \textsl{m} Zeichen reserviert. Optional können nur die ersten \textsl{n} Zeichen ausgegeben oder mit \texttt{-} eine Rechtsbündige Formatierung festgelegt werden. +\end{longtable} diff --git a/tab_quoting_sonderzeichen.tex b/tab_quoting_sonderzeichen.tex index ea87327..cf06874 100644 --- a/tab_quoting_sonderzeichen.tex +++ b/tab_quoting_sonderzeichen.tex @@ -16,5 +16,6 @@ \texttt{* ? [ ] \~{} + - @ !} & Meta-Zeichen\index{Meta-Zeichen} für Dateinamen \tabularnewline\STRUT \texttt{` ` }(Backticks oder Single Backquotes\footnote{Man erhält sie durch \Ovalbox{SHIFT} und die Taste neben dem Backspace.}) & Befehls-Substitution\index{Befehls>-Substitution} \tabularnewline\STRUT \texttt{\$} & Variablen-Substitution\index{Variablen>-Substitution} \tabularnewline\STRUT -\texttt{\Ovalbox{NEWLINE} \Ovalbox{SPACE} \Ovalbox{TAB}} & Wort-Trennzeichen\footnote{Die Wort-Trennzeichen sind in der Variable \texttt{\$IFS}\label{IFS}\index{\$IFS=\texttt{\$IFS}} abgelegt. Man kann diese Variable auch überschreiben, um elegant Strings zu zerlegen.} +\texttt{\Ovalbox{NEWLINE} \Ovalbox{SPACE} \Ovalbox{TAB}} & +Wort-Trennzeichen\footnote{Die Wort-Trennzeichen sind in der vordefinierten Variable \texttt{\$IFS} abgelegt. Siehe Abschnitt \ref{vordefinierte_variablen}.} \end{longtable} diff --git a/tab_vordefinierte_variablen.tex b/tab_vordefinierte_variablen.tex index b7148a8..cf0e5de 100644 --- a/tab_vordefinierte_variablen.tex +++ b/tab_vordefinierte_variablen.tex @@ -16,6 +16,7 @@ \texttt{\$\$} & Prozeßnummer der aktiven Shell \tabularnewline\STRUT \texttt{\$!} & Prozeßnummer des letzten Hintergrundprozesses \tabularnewline\STRUT \texttt{\$ERRNO} & Fehlernummer des letzten fehlgeschlagenen Systemaufrufs \tabularnewline\STRUT +\texttt{\$IFS} & Feldseparator, wird beispielsweise beim Lesen mittels \texttt{read} benutzt \tabularnewline\STRUT \texttt{\$PWD} & Aktuelles Verzeichnis (wird durch \texttt{cd} gesetzt\footnote{Durch das Kommando \texttt{cd} wird das aktuelle Verzeichnis gewechselt.}) \tabularnewline\STRUT \texttt{\$OLDPWD} & Vorheriges Verzeichnis (wird durch \texttt{cd} gesetzt) \end{longtable} diff --git a/was_ist_die_shell.tex b/was_ist_die_shell.tex index 7b660f2..f3d4d29 100644 --- a/was_ist_die_shell.tex +++ b/was_ist_die_shell.tex @@ -90,13 +90,14 @@ indizierte Arrays\index{Array}. TENEX-C-Shell\index{TENEX-C-Shell|textbf}\index{Shell>TENEX-C-|see{TENEX-C-Shell}} (\texttt{tcsh}\index{tcsh=\texttt{tcsh}|see{TENEX-C-Shell}}) verhält sich zur C-Shell wie die Bourne-Again-Shell zur Standard-Shell. Sie ist voll kompatibel, -bietet aber Komfort-Funktionen wie Kommandozeilen-Editierung, programmierbare -Auto-Completion\index{Auto-Completion}, Rechtschreibhilfen und eine History. +bietet aber Kom\-fort-Funk\-tio\-nen wie Kommandozeilen-Editierung, +programmierbare Auto-Completion\index{Auto-Completion}, +Recht\-schreib\-hil\-fen und eine History. \item Die Z-Shell\index{Z-Shell|textbf}\index{Shell>Z-|see{Z-Shell}} (\texttt{zsh}\index{zsh=\texttt{zsh}|see{Z-Shell}}) ähnelt der Korn-Shell, enthält aber viele Erweiterungen. Die Z-Shell unterstützt -Kommandozeilen-Editing, programmierbares +Kom\-mandozeilen-Editing, programmierbares Auto-Completion\index{Auto-Completion}, Shell-Funktionen und eine History. Zudem ist eine Rechtschreibprüfung eingebaut. \end{itemize} diff --git a/werkzeugkasten.tex b/werkzeugkasten.tex index 99954a6..f49d591 100644 --- a/werkzeugkasten.tex +++ b/werkzeugkasten.tex @@ -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 -Verfü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 +Ver\-fü\-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}|)} diff --git a/wie_sieht_ein_shell_skript_aus.tex b/wie_sieht_ein_shell_skript_aus.tex index df6dad5..4acd6e7 100644 --- a/wie_sieht_ein_shell_skript_aus.tex +++ b/wie_sieht_ein_shell_skript_aus.tex @@ -52,7 +52,12 @@ ausf Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgründen auf den meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet, muß man der Shell noch mitteilen, wo sie zu suchen hat: Mit \texttt{./name} wird versucht, im aktuellen Verzeichnis (\texttt{./}) ein Programm namens \texttt{name} auszuführen. -Auf den meisten Systemen befindet sich im Pfad der Eintrag \texttt{\~{}/bin} bzw. \texttt{/home/benutzername/bin}, das bedeutet daß man Skripte die immer wieder benutzt werden sollen dort ablegen kann, so daß sie auch ohne eine Pfadangabe gefunden werden. Wie der Pfad genau aussieht kann man an der Shell durch Eingabe von \texttt{echo \$PATH}\index{\$PATH=\texttt{\$PATH}} herausfinden. +Auf den meisten Systemen befindet sich im Pfad ein Verweis auf das Verzeichnis +\texttt{bin} unterhalb des Home-Verzeichnisses eines Benutzers. Das bedeutet +daß man Skripte die immer wieder benutzt werden sollen dort ablegen kann, so +daß sie auch ohne eine Pfadangabe gefunden werden. Wie der Pfad genau aussieht +kann man an der Shell durch Eingabe von \texttt{echo +\$PATH}\index{\$PATH=\texttt{\$PATH}} herausfinden. \subsection{Rückgabewerte}\label{exitcode}\index{Rückgabewert|(textbf}\index{Exit-Code|see{Rückgabewert}}\index{Exit-Status|see{Rückgabewert}} @@ -140,16 +145,49 @@ behandelt (expandiert). \section{Vordefinierte Variablen}\label{vordefinierte_variablen}\index{Variablen}\index{vordefinierte Variablen} -\index{\$n=\texttt{\$}$n$|(textbf}\index{\$*=\texttt{\$*}|(textbf}\index{\$@=\texttt{\$@}|(textbf}\index{\$\#=\texttt{\$\#}|(textbf}\index{\$?=\texttt{\$?}|(textbf}\index{\$\$=\texttt{\$\$}|(textbf}\index{\$!!=\texttt{\$!!}|(textbf}\index{\$ERRNO=\texttt{\$ERRNO}|(textbf}\index{\$PWD=\texttt{\$PWD}|(textbf}\index{\$OLDPWD=\texttt{\$OLDPWD}|(textbf} -\index{ERRNO=\texttt{ERRNO}|see{\$ERRNO}}\index{PWD=\texttt{PWD}|see{\$PWD}}\index{OLDPWD=\texttt{OLDPWD}|see{\$OLDPWD}} +\index{\$n=\texttt{\$}$n$|(textbf} +\index{\$*=\texttt{\$*}|(textbf} +\index{\$@=\texttt{\$@}|(textbf} +\index{\$\#=\texttt{\$\#}|(textbf} +\index{\$?=\texttt{\$?}|(textbf} +\index{\$\$=\texttt{\$\$}|(textbf} +\index{\$!!=\texttt{\$!!}|(textbf} +\index{\$ERRNO=\texttt{\$ERRNO}|(textbf} +\index{\$IFS=\texttt{\$IFS}|(textbf} +\index{\$PWD=\texttt{\$PWD}|(textbf} +\index{\$OLDPWD=\texttt{\$OLDPWD}|(textbf} +\index{ERRNO=\texttt{ERRNO}|see{\$ERRNO}} +\index{IFS=\texttt{IFS}|see{\$IFS}} +\index{PWD=\texttt{PWD}|see{\$PWD}} +\index{OLDPWD=\texttt{OLDPWD}|see{\$OLDPWD}} -Es gibt eine Reihe von vordefinierten Variablen, deren Benutzung ein wesentlicher Bestandteil des Shell-Programmierens ist. +Es gibt eine Reihe von vordefinierten Variablen, deren Benutzung ein +wesentlicher Bestandteil des Shell-Programmierens ist. Die wichtigsten eingebauten Shell-Variablen sind:\nopagebreak \LTXtable{\textwidth}{tab_vordefinierte_variablen.tex} -\texttt{\$ERRNO}, \texttt{\$PWD} und \texttt{\$OLDPWD} werden nicht von jeder Shell gesetzt. -\index{\$n=\texttt{\$}$n$|)}\index{\$*=\texttt{\$*}|)}\index{\$@=\texttt{\$@}|)}\index{\$\#=\texttt{\$\#}|)}\index{\$?=\texttt{\$?}|)}\index{\$\$=\texttt{\$\$}|)}\index{\$!!=\texttt{\$!!}|)}\index{\$ERRNO=\texttt{\$ERRNO}|)}\index{\$PWD=\texttt{\$PWD}|)}\index{\$OLDPWD=\texttt{\$OLDPWD}|)} +Die Variable \texttt{\$IFS} enthält per Default die Blank-Zeichen, also +Newline, Space und Tab. Man kann sie aber auch mit anderen Zeichen +überschreiben. Diese werden immer dann als Trennzeichen benutzt, wenn ein +String in mehrere Teile zerlegt werden soll, also beispielsweise in +\texttt{for}-Schleifen oder beim zeilenweisen Einlesen mit \texttt{read}. Ein +gutes Beispiel gibt es in dem Beispielskript zu \texttt{printf} (Abschnitt +\ref{printf}). + +\texttt{\$ERRNO}, \texttt{\$PWD} und \texttt{\$OLDPWD} werden nicht von jeder +Shell gesetzt. +\index{\$n=\texttt{\$}$n$|)} +\index{\$*=\texttt{\$*}|)} +\index{\$@=\texttt{\$@}|)} +\index{\$\#=\texttt{\$\#}|)} +\index{\$?=\texttt{\$?}|)} +\index{\$\$=\texttt{\$\$}|)} +\index{\$!!=\texttt{\$!!}|)} +\index{\$ERRNO=\texttt{\$ERRNO}|)} +\index{\$IFS=\texttt{\$IFS}|)} +\index{\$PWD=\texttt{\$PWD}|)} +\index{\$OLDPWD=\texttt{\$OLDPWD}|)} \section{Variablen-Substitution}\index{Variablen>-Substitution|(textbf}\index{Substitution|see{Variablen-Subst.}}\index{Variablen|(textbf} @@ -307,12 +345,12 @@ einem Konstrukt in der Form \texttt{i=\$((\$i + 1))} k Berechnungen angestellt werden. Dabei wird der Ausdruck in den Klammern bewertet als ob er in doppelten -Anführungszeichen stehen würde. Das bedeutet zum Einen, daß man auch mit -Variablen rechnen kann, zum anderen macht es das Quoten des Sternchens +An\-füh\-rungs\-zei\-chen stehen würde. Das bedeutet zum Einen, daß man auch +mit Variablen rechnen kann, zum anderen macht es das Quoten des Sternchens überflüssig. Für komplexere Berechnungen steht das Tool \texttt{bc} (Siehe Abschnitt -\ref{bc}) zur Verfügung. +\ref{bc}) zur Ver\-fü\-gung. \index{Arithmetik-Expansion|)} @@ -615,7 +653,7 @@ auf einen anderen Rechner portiert und die Datei vergi legt man eine solche Datei sinnvoll ab? Um diesem Ärger zu entgehen, sollte man in einer solchen Situation ein -Here-Dokument benutzen. +Here-Do\-ku\-ment benutzen. \emph{Umlenkung mit Hilfe von Dateideskriptoren:}\nopagebreak \LTXtable{\textwidth}{tab_datenstroeme_deskriptoren.tex}