\texttt{` ` }(Backticks\footnote{Man erh<72>lt sie durch \Ovalbox{SHIFT} und die Taste neben dem Backspace.}) & Befehls-Substitution\index{Befehls>-Substitution}\tabularnewline\STRUT
\texttt{` ` }(Backticks oder Single Backquotes\footnote{Man erh<72>lt sie durch \Ovalbox{SHIFT} und die Taste neben dem Backspace.}) & Befehls-Substitution\index{Befehls>-Substitution}\tabularnewline\STRUT
\texttt{\Ovalbox{NEWLINE}\Ovalbox{SPACE}\Ovalbox{TAB}}& Wort-Trennzeichen\footnote{Die Wort-Trennzeichen sind in der Variable \texttt{\$IFS}\index{\$IFS=\texttt{\$IFS}} abgelegt. Man kann diese Variable auch <20>berschreiben, um elegant Strings zu zerlegen.}
\texttt{\Ovalbox{NEWLINE}\Ovalbox{SPACE}\Ovalbox{TAB}}& Wort-Trennzeichen\footnote{Die Wort-Trennzeichen sind in der Variable \texttt{\$IFS}\index{\$IFS=\texttt{\$IFS}} abgelegt. Man kann diese Variable auch <20>berschreiben, um elegant Strings zu zerlegen.}
\textsl{Variable}\texttt{=}\textsl{Wert}& Setzt die \textsl{Variable} auf den \textsl{Wert}. Dabei ist unbedingt darauf zu achten, da<64> zwischen dem Variablennamen und dem Gleichheitszeichen keine Leerzeichen stehen. \tabularnewline\STRUT
\textsl{Variable}\texttt{=}\textsl{Wert}& Setzt die \textsl{Variable} auf den \textsl{Wert}. Dabei ist unbedingt darauf zu achten, da<64> zwischen dem Variablennamen und dem Gleichheitszeichen keine Leerzeichen stehen. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{\}}& Nutzt den Wert von \textsl{Variable}. Die Klammern m<>ssen nicht mit angegeben werden, wenn die \textsl{Variable}von Trennzeichen umgeben ist. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{\}}& Nutzt den Wert von \textsl{Variable}. Die Klammern m<>ssen nur angegeben werden, wenn auf die \textsl{Variable}eine Zahl, ein Buchstabe oder ein Unterstrich folgen. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{:-}\textsl{Wert}\texttt{\}}& Nutzt den Wert von \textsl{Variable}. Falls die \textsl{Variable} nicht gesetzt ist, wird der \textsl{Wert} benutzt. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{:-}\textsl{Wert}\texttt{\}}& Nutzt den Wert von \textsl{Variable}. Falls die \textsl{Variable} nicht gesetzt oder leer ist, wird \textsl{Wert} benutzt. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{:=}\textsl{Wert}\texttt{\}}& Nutzt den Wert von \textsl{Variable}. Falls die \textsl{Variable} nicht gesetzt ist, wird der \textsl{Wert} benutzt, und \textsl{Variable} erh<72>lt den \textsl{Wert}. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{:=}\textsl{Wert}\texttt{\}}& Nutzt den Wert von \textsl{Variable}. Falls die \textsl{Variable} nicht gesetzt oder leer ist, wird \textsl{Wert} benutzt, und \textsl{Variable} erh<72>lt den \textsl{Wert}. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{:?}\textsl{Wert}\texttt{\}}& Nutzt den Wert von \textsl{Variable}. Falls die \textsl{Variable} nicht gesetzt ist, wird der \textsl{Wert} ausgegeben und die Shell beendet. Wenn kein \textsl{Wert} angegeben wurde, wird der Text \texttt{parameter null or not set} ausgegeben. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{:?}\textsl{Wert}\texttt{\}}& Nutzt den Wert von \textsl{Variable}. Falls die \textsl{Variable} nicht gesetzt oder leer ist, wird der \textsl{Wert} ausgegeben und die Shell beendet. Wenn kein \textsl{Wert} angegeben wurde, wird der Text \texttt{parameter null or not set} ausgegeben. \tabularnewline\STRUT
\texttt{\$\{}\textsl{Variable}\texttt{:+}\textsl{Wert}\texttt{\}}& Nutzt den\textsl{Wert}, falls die \textsl{Variable} gesetzt ist, andernfalls nichts.
\texttt{\$\{}\textsl{Variable}\texttt{:+}\textsl{Wert}\texttt{\}}&\textsl{Wert}, falls die \textsl{Variable} gesetzt und nicht leer ist, andernfalls nichts.
@ -8,6 +8,11 @@ In der Shell stehen viele Mechanismen zur Verf
Zun<EFBFBD>chst soll die Frage gekl<6B>rt werden, wie man <20>berhaupt ein ausf<73>hrbares Shell-Skript schreibt. Dabei wird vorausgesetzt, da<64> dem Benutzer der Umgang mit mindestens einem Texteditor\index{Texteditor} (\texttt{vi}\index{vi=\texttt{vi}}, \texttt{emacs}\index{emacs=\texttt{emacs}} etc.) bekannt ist.
Zun<EFBFBD>chst soll die Frage gekl<6B>rt werden, wie man <20>berhaupt ein ausf<73>hrbares Shell-Skript schreibt. Dabei wird vorausgesetzt, da<64> dem Benutzer der Umgang mit mindestens einem Texteditor\index{Texteditor} (\texttt{vi}\index{vi=\texttt{vi}}, \texttt{emacs}\index{emacs=\texttt{emacs}} etc.) bekannt ist.
Bei der Erstellung oder Bearbeitung von Shell-Skripten mu<6D> darauf geachtet
werden, da<64> sich keine CR/LF-Zeilenumbr<62>che einschleichen, wie dies leicht bei
der Benutzung von MS-DOS bzw. Windows-Systemen zur Bearbeitung von Skripten
<EFBFBD>ber das Netzwerk passieren kann.
\subsection{HowTo}
\subsection{HowTo}
Zun<EFBFBD>chst mu<6D> mit Hilfe des Editors eine Textdatei angelegt werden, in die der `Quelltext' geschrieben wird. Wie der aussieht, sollte man anhand der folgenden Abschnitte und der Beispiele im Anhang erkennen k<>nnen. Beim Schreiben sollte man nicht mit den Kommentaren\index{Kommentar} geizen, da ein Shell-Skript auch schon mal sehr unleserlich werden kann.
Zun<EFBFBD>chst mu<6D> mit Hilfe des Editors eine Textdatei angelegt werden, in die der `Quelltext' geschrieben wird. Wie der aussieht, sollte man anhand der folgenden Abschnitte und der Beispiele im Anhang erkennen k<>nnen. Beim Schreiben sollte man nicht mit den Kommentaren\index{Kommentar} geizen, da ein Shell-Skript auch schon mal sehr unleserlich werden kann.
@ -35,6 +40,9 @@ benutzt man das Kommando \texttt{chmod ugo+rx name} oder einfach \texttt{chmod
+rx name}. Mit \texttt{chmod u+x name} hat nur der Besitzer der Datei
+rx name}. Mit \texttt{chmod u+x name} hat nur der Besitzer der Datei
Ausf<EFBFBD>hrungsrechte.
Ausf<EFBFBD>hrungsrechte.
Um ein Shell-Skript ausf<73>hren zu k<>nnen braucht es aus der Sicht des
ausf<EFBFBD>hrenden Benutzers mindestens die Rechte zum Lesen (r) und Ausf<73>hren (x).
Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgr<67>nden auf den meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet, mu<6D> 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<75>hren.
Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgr<67>nden auf den meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet, mu<6D> 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<75>hren.
Auf den meisten Systemen befindet sich im Pfad der Eintrag \texttt{\~{}/bin} bzw. \texttt{/home/benutzername/bin}, das bedeutet da<64> man Skripte die immer wieder benutzt werden sollen dort ablegen kann, so da<64> 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 der Eintrag \texttt{\~{}/bin} bzw. \texttt{/home/benutzername/bin}, das bedeutet da<64> man Skripte die immer wieder benutzt werden sollen dort ablegen kann, so da<64> 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.
@ -44,7 +52,16 @@ Auf den meisten Systemen befindet sich im Pfad der Eintrag \texttt{\~{}/bin} bzw
Wenn unter Unix ein Proze<7A> beendet wird, gibt er einen R<>ckgabewert (auch Exit-Code oder Exit-Status genannt) an seinen aufrufenden Proze<7A> zur<75>ck. So kann der Mutterproze<7A> kontrollieren, ob die Ausf<73>hrung des Tochterprozesses ohne Fehler beendet wurde. In einigen F<>llen (z. B. \texttt{grep}\index{grep=\texttt{grep}}) werden unterschiedliche Exit-Codes f<>r unterschiedliche Ereignisse benutzt.
Wenn unter Unix ein Proze<7A> beendet wird, gibt er einen R<>ckgabewert (auch Exit-Code oder Exit-Status genannt) an seinen aufrufenden Proze<7A> zur<75>ck. So kann der Mutterproze<7A> kontrollieren, ob die Ausf<73>hrung des Tochterprozesses ohne Fehler beendet wurde. In einigen F<>llen (z. B. \texttt{grep}\index{grep=\texttt{grep}}) werden unterschiedliche Exit-Codes f<>r unterschiedliche Ereignisse benutzt.
Dieser R<>ckgabewert wird bei der interaktiven Benutzung der Shell nur selten benutzt. Aber in der Programmierung von Shell-Skripten ist er von unsch<63>tzbarem Wert. So kann das Skript automatisch entscheiden, ob bestimmte Aktionen ausgef<65>hrt werden sollen, die von anderen Aktionen ab\-h<EFBFBD>n\-gen. Beispiele dazu sieht man bei der Beschreibung der Kommandos \texttt{if}\index{if=\texttt{if}} (\ref{if}), \texttt{case}\index{case=\texttt{case}} (\ref{case}), \texttt{while}\index{while=\texttt{while}} (\ref{while}) und \texttt{until}\index{until=\texttt{until}} (\ref{until}), sowie in dem Abschnitt <20>ber Befehlsformen (\ref{befehlsformen}).
Dieser R<>ckgabewert wird bei der interaktiven Benutzung der Shell nur selten
benutzt, da Fehlermeldungen direkt vom Benutzer abgelesen werden k<>nnen. Aber
in der Programmierung von Shell-Skripten ist er von unsch<63>tzbarem Wert. So kann
das Skript automatisch entscheiden, ob bestimmte Aktionen ausgef<65>hrt werden
sollen, die von anderen Aktionen ab\-h<EFBFBD>n\-gen. Beispiele dazu sieht man bei der
Beschreibung der Kommandos \texttt{if}\index{if=\texttt{if}} (\ref{if}),
In der Bourne-Shell wird der Exit-Code des letzten aufgerufenen Programms in der Variable \texttt{\$?}\index{\$?=\texttt{\$?}} abgelegt. <20>blicherweise geben Programme den Wert 0 zur<75>ck, bei irgendwelchen Problemen einen von 0 verschiedenen Wert. Das wird im folgenden Beispiel deutlich:
In der Bourne-Shell wird der Exit-Code des letzten aufgerufenen Programms in der Variable \texttt{\$?}\index{\$?=\texttt{\$?}} abgelegt. <20>blicherweise geben Programme den Wert 0 zur<75>ck, bei irgendwelchen Problemen einen von 0 verschiedenen Wert. Das wird im folgenden Beispiel deutlich:
\LTXtable{\textwidth}{tab_beisp_exitcode.tex}
\LTXtable{\textwidth}{tab_beisp_exitcode.tex}
@ -84,7 +101,18 @@ Die wichtigsten eingebauten Shell-Variablen sind:\nopagebreak
Unter Variablen-Substitution versteht man verschiedene Methoden um die Inhalte von Variablen zu benutzen. Das umfa<66>t sowohl die einfache Zuweisung eines Wertes an eine Variable als auch einfache M<>glichkeiten zur Fallunterscheidung. In den fortgeschritteneren Shell-Versionen (\texttt{bash}\index{Bourne-Again-Shell}, \texttt{ksh}\index{Korn-Shell}) existieren sogar M<>glichkeiten, auf Substrings von Variableninhalten zuzugreifen. In der Standard-Shell benutzt man f<>r einfache Aufgaben <20>blicherweise Tools wie \texttt{cut}, \texttt{basename}\index{basename=\texttt{basename}} oder \texttt{dirname}; komplexe Bearbeitungen erledigt der Stream-Editor \texttt{sed}\index{sed=\texttt{sed}}. Einleitende Informationen dazu finden sich im Kapitel <20>ber die Mustererkennung (\ref{mustererkennung}).
Unter Variablen-Substitution versteht man verschiedene Methoden um die Inhalte
von Variablen zu benutzen. Das umfa<66>t sowohl die einfache Zuweisung eines
Wertes an eine Variable als auch einfache M<>glichkeiten zur Fallunterscheidung.
existieren sogar M<>glichkeiten, auf Substrings von Variableninhalten
zuzugreifen. In der Standard-Shell benutzt man f<>r einfache Aufgaben
<EFBFBD>blicherweise Tools wie \texttt{cut},
\texttt{basename}\index{basename=\texttt{basename}} oder \texttt{dirname};
komplexe Bearbeitungen erledigt der Stream-Editor
\texttt{sed}\index{sed=\texttt{sed}}. Einleitende Informationen dazu finden
sich im Kapitel <20>ber die Mustererkennung (\ref{mustererkennung}).
Die folgenden Mechanismen stehen in der Standard-Shell bereit, um mit Variablen zu hantieren. Bei allen Angaben ist der Doppelpunkt optional. Wenn er aber angegeben wird, mu<6D> die \textsl{Variable} einen Wert enthalten. \nopagebreak
Die folgenden Mechanismen stehen in der Standard-Shell bereit, um mit Variablen zu hantieren. Bei allen Angaben ist der Doppelpunkt optional. Wenn er aber angegeben wird, mu<6D> die \textsl{Variable} einen Wert enthalten. \nopagebreak
Dies ist ein sehr schwieriges Thema, da hier mehrere <20>hnlich aussehende Zeichen v<>llig verschiedene Effekte bewirken. Unix unterscheidet allein zwischen drei verschiedenen Anf<6E>hrungszeichen. Das Quoten dient dazu, bestimmte Zeichen mit einer Sonderbedeutung vor der Shell zu `verstecken' um zu verhindern, da<64> diese expandiert (ersetzt) werden.
Dies ist ein sehr schwieriges Thema, da hier mehrere <20>hnlich aussehende Zeichen
v<EFBFBD>llig verschiedene Effekte bewirken. Die Bourne-Shell unterscheidet allein
zwischen drei verschiedenen Anf<6E>hrungszeichen. Das Quoten dient dazu, bestimmte
Zeichen mit einer Sonderbedeutung vor der Shell zu `verstecken' um zu
verhindern, da<64> diese expandiert (ersetzt) werden.
Die folgenden Zeichen haben eine spezielle Bedeutung innerhalb der Shell:\nopagebreak
Die folgenden Zeichen haben eine spezielle Bedeutung innerhalb der Shell:\nopagebreak
Ausdruck}}\index{Ausdruck|see{Regul<EFBFBD>rer Ausdruck}} genannt. Sie bieten
Ausdruck}}\index{Ausdruck|see{Regul<EFBFBD>rer Ausdruck}} genannt. Sie bieten
wesentlich mehr M<>glichkeiten als die relativ einfachen Wildcards f<>r
wesentlich mehr M<>glichkeiten als die relativ einfachen Wildcards f<>r
Dateinamen.
Dateinamen.
@ -198,9 +239,20 @@ Kommentare in der Shell beginnen immer mit dem Nummern-Zeichen (\verb\#\). Dabei
\subsection{Auswahl der Shell (\texttt{\#!})}\label{auswahl_der_shell}\index{\#!!=\texttt{\#!!}|see{Shell / Auswahl der\ldots}}\index{Shell>Auswahl der\ldots|(textbf}
\subsection{Auswahl der Shell (\texttt{\#!})}\label{auswahl_der_shell}\index{\#!!=\texttt{\#!!}|see{Shell / Auswahl der\ldots}}\index{Shell>Auswahl der\ldots|(textbf}
In der ersten Zeile eines Shell-Skriptes sollte definiert werden, mit welcher Shell das Skript ausgef<65>hrt werden soll. Das System <20>ffnet dann eine Subshell\index{Subshell} und f<>hrt das restliche Skript in dieser aus.
In der ersten Zeile eines Shell-Skriptes sollte definiert werden, mit welchem
Programm das Skript ausgef<65>hrt werden soll. Das System <20>ffnet dann eine
Subshell\index{Subshell} und f<>hrt das restliche Skript in dieser aus.
Die Angabe erfolgt <20>ber eine Zeile in der Form \verb\#!/bin/sh\, wobei unter
\verb\/bin/sh\ die entsprechende Shell (in diesem Fall die Bourne-Shell) liegt.
Dieser Eintrag wirkt nur dann, wenn er in der ersten Zeile und der ersten
Spalte des Skripts steht.
Dieser Mechanismus ist bei der Bourne-Shell nicht vorhanden, er wurde mit den
moderneren Shells eingef<65>hrt um eben durch die Angabe von \verb\#!/bin/sh\ die
Bourne-Shell f<>r die Ausf<73>hrung von Shell-Skripten benutzen zu k<>nnen. In der
Bourne-Shell wirkt das f<>hrende \verb\#\ als Kommentarzeichen.
Die Angabe erfolgt <20>ber eine Zeile in der Form \verb\#!/bin/sh\, wobei unter \verb\/bin/sh\ die entsprechende Shell (in diesem Fall die Bourne-Shell) liegt. Dieser Eintrag wirkt nur dann, wenn er in der ersten Zeile des Skripts steht.
\index{Shell>Auswahl der\ldots|)}
\index{Shell>Auswahl der\ldots|)}
@ -223,13 +275,17 @@ Die `gesourcte' Datei wird eingelesen und ausgef
Es ist in der Shell auch m<>glich, <20>hnlich wie in einer `richtigen' Programmiersprache Funktionen zu deklarieren und zu benutzen. Da die Bourne-Shell (\verb\sh\) nicht <20>ber Aliase\index{Aliase} verf<72>gt, k<>nnen einfache Funktionen als Ersatz dienen.
Es ist in der Shell auch m<>glich, <20>hnlich wie in einer `richtigen' Programmiersprache Funktionen zu deklarieren und zu benutzen. Da die Bourne-Shell (\verb\sh\) nicht <20>ber Aliase\index{Aliase} verf<72>gt, k<>nnen einfache Funktionen als Ersatz dienen.
Der R<>ckgabewert einer Funktion ist gleich dem R<>ckgabewert des letzten in der Funktion aufgerufenen Kommandos.
Der R<>ckgabewert einer Funktion ist gleich dem R<>ckgabewert des letzten in der
Funktion aufgerufenen Kommandos, es sei denn man gibt mittels
\verb\return\ (Siehe \ref{return}) explizit einen anderen Wert zur<75>ck.
\medskip\emph{Beispiel:} Die Funktion gibt die Anzahl der Dateien im aktuellen Verzeichnis zur<75>ck. Aufgerufen wird diese Funktion wie ein Befehl, also einfach durch die Eingabe von \verb\count\.\nopagebreak
\medskip\emph{Beispiel:} Die Funktion gibt die Anzahl der Dateien im aktuellen
Verzeichnis aus. Aufgerufen wird diese Funktion wie ein Befehl, also einfach
durch die Eingabe von \verb\count\.\nopagebreak
\LTXtable{\textwidth}{tab_beisp_funktionen.tex}
\LTXtable{\textwidth}{tab_beisp_funktionen.tex}
\index{Funktion|)}
\index{Funktion|)}
@ -373,6 +429,17 @@ Die \texttt{exit}-Anweisung wird benutzt, um ein Skript zu beenden. Wenn der Par
Die Shell ist der perfekte Baukasten f<>r das Unix-Paradigma `small is
beautiful'. Die mitgelieferten Unix-Standardkommandos sind einfach gehalten,
erledigen aber auf effiziente Weise die Arbeit f<>r die sie programmiert wurden.
Mit der Shell, bzw. dem Shell-Skript, wird aus dem Heinzelm<6C>nnchen ein starker
Riese.
Shell-Skripte werden im Wesentlichen aus zwei Gr<47>nden geschrieben: Erstens,
Shell-Skripte werden im Wesentlichen aus zwei Gr<47>nden geschrieben: Erstens,
weil man so st<73>ndig wiederkehrende Kommandos zusammenfassen kann, die man dann
weil man so st<73>ndig wiederkehrende Kommandos zusammenfassen kann, die man dann
mit einem einfachen Aufruf starten kann, und zweitens, weil man so einfache
mit einem einfachen Aufruf starten kann, und zweitens, weil man so einfache
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.