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

@ -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:

View File

@ -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

View File

@ -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
%==============================================================================

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

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
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\-\-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}|)}

View File

@ -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\-\-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}