Compare commits
	
		
			52 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 50ed10a887 | ||
|  | 9978ac040b | ||
|  | 577cdbfcd1 | ||
|  | f72918f75d | ||
|  | 75357d86bc | ||
|  | 5b9829acef | ||
|  | 82d1e3e470 | ||
|  | 68d30297e6 | ||
|  | 52635f366a | ||
|  | 5fdc537aa9 | ||
|  | 483c60f1db | ||
|  | 9e6a3f8e7a | ||
|  | 464f0bcf77 | ||
|  | 15af99f29e | ||
|  | c0e556e25d | ||
|  | fe58ca9711 | ||
|  | 14dec49967 | ||
|  | 7eea8ed0e9 | ||
|  | c6e06f8072 | ||
|  | b7c54658b2 | ||
|  | 44b7aa5f9b | ||
|  | 78f93544bd | ||
|  | 2225e88484 | ||
|  | 136b632f8f | ||
|  | ff78ec65e4 | ||
|  | bd36939a90 | ||
|  | a7f9f8ccdd | ||
|  | 31924e5ab5 | ||
|  | 5c655b4df2 | ||
|  | f0daf0d532 | ||
|  | 7a676d4647 | ||
|  | 3582465121 | ||
|  | c1380f16a2 | ||
|  | 80a7166150 | ||
|  | dc7eb4bedf | ||
|  | 516e0c1707 | ||
|  | f921275c10 | ||
|  | cff6123cad | ||
|  | ccc6061c3f | ||
|  | b523791d1b | ||
|  | 029828ff41 | ||
|  | a4c627a1a5 | ||
|  | 90a49f0f52 | ||
|  | 4a00e0290b | ||
|  | e0271effdb | ||
|  | 06193ffb55 | ||
|  | d293f41934 | ||
|  | 3f0e20007f | ||
|  | 85b9643684 | ||
|  | 27e5af6fbe | ||
|  | e2e810895b | ||
|  | 02678fcea4 | 
							
								
								
									
										54
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								Makefile
									
									
									
									
									
								
							| @@ -134,6 +134,10 @@ ifndef DVIVIEWER | |||||||
| DVIVIEWER=xdvi | DVIVIEWER=xdvi | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | ifndef PDFVIEWER | ||||||
|  | PDFVIEWER=acroread | ||||||
|  | endif | ||||||
|  |  | ||||||
| ifndef LATEX2HTML | ifndef LATEX2HTML | ||||||
| LATEX2HTML=latex2html | LATEX2HTML=latex2html | ||||||
| endif | endif | ||||||
| @@ -271,21 +275,6 @@ TEXFILES=$(wildcard *.tex) | |||||||
| 		touch $*.ind; \ | 		touch $*.ind; \ | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| latex: |  | ||||||
| # Below the 'true' is included to prevent unnecessarily many errors. |  | ||||||
| 	@if [ -n "${LATEXTARGET}" ]; then \ |  | ||||||
| 		$(MAKE) ${LATEXTARGET}.dvi; \ |  | ||||||
| 		true; \ |  | ||||||
| 	else \ |  | ||||||
| 		if [ `ls *.tex | wc -l` = "1" ]; then \ |  | ||||||
| 			$(MAKE) `basename \`ls *.tex\` .tex`.dvi; \ |  | ||||||
| 			true; \ |  | ||||||
| 		else \ |  | ||||||
| 			$(MAKE) `echo $$PWD|tr '/' '\n'|tail -1`.dvi; \ |  | ||||||
| 			true; \ |  | ||||||
| 		fi; \ |  | ||||||
| 	fi |  | ||||||
|  |  | ||||||
| pdflatex: | pdflatex: | ||||||
| # Below the 'true' is included to prevent unnecessarily many errors. | # Below the 'true' is included to prevent unnecessarily many errors. | ||||||
| 	@if [ -n "${LATEXTARGET}" ]; then \ | 	@if [ -n "${LATEXTARGET}" ]; then \ | ||||||
| @@ -301,12 +290,27 @@ pdflatex: | |||||||
| 		fi; \ | 		fi; \ | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
|  | latex: | ||||||
|  | # Below the 'true' is included to prevent unnecessarily many errors. | ||||||
|  | 	@if [ -n "${LATEXTARGET}" ]; then \ | ||||||
|  | 		$(MAKE) ${LATEXTARGET}.dvi; \ | ||||||
|  | 		true; \ | ||||||
|  | 	else \ | ||||||
|  | 		if [ `ls *.tex | wc -l` = "1" ]; then \ | ||||||
|  | 			$(MAKE) `basename \`ls *.tex\` .tex`.dvi; \ | ||||||
|  | 			true; \ | ||||||
|  | 		else \ | ||||||
|  | 			$(MAKE) `echo $$PWD|tr '/' '\n'|tail -1`.dvi; \ | ||||||
|  | 			true; \ | ||||||
|  | 		fi; \ | ||||||
|  | 	fi | ||||||
|  |  | ||||||
| latexfigures: | latexfigures: | ||||||
| 	@for i in $(FIGUREOBJS); do \ | 	@for i in $(FIGUREOBJS); do \ | ||||||
| 		$(MAKE) $$i; \ | 		$(MAKE) $$i; \ | ||||||
| 	done | 	done | ||||||
|  |  | ||||||
| view: | viewdvi: | ||||||
| # Below the 'true' is included to prevent unnecessarily many errors. | # Below the 'true' is included to prevent unnecessarily many errors. | ||||||
| 	@if [ -n "${LATEXTARGET}" ]; then \ | 	@if [ -n "${LATEXTARGET}" ]; then \ | ||||||
| 		$(MAKE) ${LATEXTARGET}.dvi && \ | 		$(MAKE) ${LATEXTARGET}.dvi && \ | ||||||
| @@ -324,6 +328,24 @@ view: | |||||||
| 		fi; \ | 		fi; \ | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
|  | view: | ||||||
|  | # Below the 'true' is included to prevent unnecessarily many errors. | ||||||
|  | 	@if [ -n "${LATEXTARGET}" ]; then \ | ||||||
|  | 		$(MAKE) ${LATEXTARGET}.pdf && \ | ||||||
|  | 		$(PDFVIEWER) ${LATEXTARGET}.pdf; \ | ||||||
|  | 		true; \ | ||||||
|  | 	else \ | ||||||
|  | 		if [ `ls *.tex | wc -l` = "1" ]; then \ | ||||||
|  | 			$(MAKE) `basename \`ls *.tex\` .tex`.pdf && \ | ||||||
|  | 			$(PDFVIEWER) `basename \`ls *.tex\` .tex`.pdf; \ | ||||||
|  | 			true; \ | ||||||
|  | 		else \ | ||||||
|  | 			$(MAKE) `echo $$PWD|tr '/' '\n'|tail -1`.pdf && \ | ||||||
|  | 			$(PDFVIEWER) `echo $$PWD|tr '/' '\n'|tail -1`.pdf; \ | ||||||
|  | 			true; \ | ||||||
|  | 		fi; \ | ||||||
|  | 	fi | ||||||
|  |  | ||||||
| %.ps: %.dvi | %.ps: %.dvi | ||||||
| 	$(DVIPS) -o $@ $< | 	$(DVIPS) -o $@ $< | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										560
									
								
								beispiele.tex
									
									
									
									
									
								
							
							
						
						
									
										560
									
								
								beispiele.tex
									
									
									
									
									
								
							| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
| \chapter{Beispiele} | \chapter{Beispiele} | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -12,67 +13,132 @@ Angenommen, bei der Benutzung eines Rechners tritt ein Problem auf, bei dem nur | |||||||
|  |  | ||||||
| Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunden automatisch <20>berpr<70>ft, ob der Admin angemeldet ist. Wir erreichen das mit dem folgenden Code: | Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunden automatisch <20>berpr<70>ft, ob der Admin angemeldet ist. Wir erreichen das mit dem folgenden Code: | ||||||
|  |  | ||||||
| \footnotesize |  | ||||||
| \index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{Pipe}\index{grep=\texttt{grep}}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}} | \index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{Pipe}\index{grep=\texttt{grep}}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}} | ||||||
| \begin{listing}[2]{1} | \begin{lstlisting} | ||||||
| #!/bin/sh | #!/bin/sh | ||||||
| until who | grep "^root " | until who | grep "^root "; do | ||||||
| do sleep 30 |   sleep 30 | ||||||
| done | done | ||||||
| echo Big Brother is watching you! | echo "Big Brother is watching you!" | ||||||
| \end{listing} | \end{lstlisting} | ||||||
| \normalsize |  | ||||||
|  |  | ||||||
| Das Skript f<>hrt also so lange das Kommando aus, bis die Ausf<73>hrung erfolgreich war. Dabei wird die Ausgabe von \texttt{who}\index{who=\texttt{who}} mit einer Pipe (\ref{datenstrom}) in das \texttt{grep}\index{grep=\texttt{grep}}-Kommando umgeleitet. Dieses sucht darin nach einem Auftreten von `\texttt{root~}' am Zeilenanfang. Der R<>ckgabewert von \texttt{grep}\index{grep=\texttt{grep}} ist 0 wenn das Muster\index{Mustererkennung} gefunden wird, 1 wenn es nicht gefunden wird und 2 wenn ein Fehler auftrat. Damit der Rechner nicht die ganze Zeit mit dieser Schleife besch<63>ftigt ist, wird im Schleifenk<6E>rper ein \texttt{sleep 30}\index{sleep=\texttt{sleep}} ausgef<65>hrt, um den Proze<7A> f<>r 30 Sekunden schlafen zu schicken. Sobald der Admin sich eingeloggt hat, wird eine entsprechende Meldung ausgegeben. | Das Skript f<>hrt also so lange das Kommando aus, bis die Ausf<73>hrung erfolgreich | ||||||
|  | war. Dabei wird die Ausgabe von \texttt{who}\index{who=\texttt{who}} mit einer | ||||||
|  | Pipe (\ref{datenstrom}) in das \texttt{grep}\index{grep=\texttt{grep}}-Kommando | ||||||
|  | umgeleitet. Dieses sucht darin nach einem Auftreten von `\texttt{root~}' am | ||||||
|  | Zeilenanfang. Der R<>ckgabewert von \texttt{grep}\index{grep=\texttt{grep}} ist | ||||||
|  | 0 wenn das Muster\index{Mustererkennung} gefunden wird, 1 wenn es nicht | ||||||
|  | gefunden wird und 2 wenn ein Fehler auftrat. Damit der Rechner nicht die ganze | ||||||
|  | Zeit mit dieser Schleife besch<63>ftigt ist, wird im Schleifenk<6E>rper ein | ||||||
|  | \lstinline|sleep 30|\index{sleep=\texttt{sleep}} ausgef<65>hrt, um den Proze<7A> f<>r | ||||||
|  | 30 Sekunden schlafen zu schicken. Sobald der Admin sich eingeloggt hat, wird | ||||||
|  | eine entsprechende Meldung ausgegeben. | ||||||
|  |  | ||||||
|  |  | ||||||
| \subsection{Schleife, bis ein Kommando erfolglos war} | \subsection{Schleife, bis ein Kommando erfolglos war} | ||||||
|  |  | ||||||
| Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das meldet, sobald sich ein Benutzer abgemeldet hat. Dazu ersetzen wir nur die \texttt{until}- Schleife durch eine entsprechende \texttt{while}-Schleife: | Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das | ||||||
|  | meldet, sobald sich ein Benutzer abgemeldet hat. Dazu ersetzen wir nur die | ||||||
|  | \texttt{until}- Schleife durch eine entsprechende \texttt{while}-Schleife: | ||||||
|  |  | ||||||
| \footnotesize |  | ||||||
| \index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{grep=\texttt{grep}}\index{Pipe}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}} | \index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{grep=\texttt{grep}}\index{Pipe}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}} | ||||||
| \begin{listing}[2]{1} | \begin{lstlisting} | ||||||
| #!/bin/sh | #!/bin/sh | ||||||
| while who | grep "^root " | while who | grep "^root "; do | ||||||
| do sleep 30 |   sleep 30 | ||||||
| done | done | ||||||
| echo Die Katze ist aus dem Haus, Zeit, da<64> die M<>use tanzen! | echo "Die Katze ist aus dem Haus, Zeit, da<64> die M<>use tanzen!" | ||||||
| \end{listing} | \end{lstlisting} | ||||||
| \normalsize |  | ||||||
|  |  | ||||||
| Die Schleife wird n<>mlich dann so lange ausgef<65>hrt, bis \texttt{grep}\index{grep=\texttt{grep}} einen Fehler (bzw. eine erfolglose Suche) zur<75>ckmeldet. | Die Schleife wird n<>mlich dann so lange ausgef<65>hrt, bis | ||||||
|  | \texttt{grep}\index{grep=\texttt{grep}} einen Fehler (bzw. eine erfolglose | ||||||
|  | Suche) zur<75>ckmeldet. | ||||||
|  |  | ||||||
|  |  | ||||||
| \section{Eine Datei zeilenweise bearbeiten} | \section{Subshell-Schleifen vermeiden}\label{subshellschleifen} | ||||||
|  |  | ||||||
| \texttt{cat datei.txt | while read i} | Wir wollen ein Skript schreiben, das die \texttt{/etc/passwd} liest und dabei | ||||||
|  | z<EFBFBD>hlt, wie viele Benutzer eine UID kleiner als 100 haben. | ||||||
|  |  | ||||||
| TODO!!! | Folgendes Skript funktioniert nicht: | ||||||
|  |  | ||||||
|  | \begin{lstlisting} | ||||||
|  | #!/bin/sh | ||||||
|  | count=0 | ||||||
|  | cat /etc/passwd | while read i; do | ||||||
|  |   uid=`echo $i | cut -f 3 -d:` | ||||||
|  |   if [ $uid -lt 100 ]; then | ||||||
|  |     count=`expr $count + 1` | ||||||
|  |     echo $count | ||||||
|  |   fi | ||||||
|  | done | ||||||
|  | echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Was ist passiert? | ||||||
|  |  | ||||||
|  | Dieses Skript besteht im Wesentlichen aus einer Pipe. Wir haben ein | ||||||
|  | \texttt{cat}-Kom\-man\-do, das den Inhalt der \texttt{/etc/passwd} durch eben | ||||||
|  | diese Pipe an eine Schleife <20>bergibt. Das \texttt{read}-Kommando in der | ||||||
|  | Schleife liest die einzelnen Zeilen aus, dann folgt ein Bi<42>chen Auswertung. | ||||||
|  |  | ||||||
|  | Es ist zu beobachten, da<64> bei der Ausgabe in Zeile 7 die Variable | ||||||
|  | \texttt{\$count} korrekte Werte enth<74>lt. Um so unverst<73>ndlicher ist es, da<64> sie | ||||||
|  | nach der Vollendung der Schleife wieder den Wert 0 enth<74>lt. | ||||||
|  |  | ||||||
|  | Das liegt daran, da<64> diese Schleife als Teil einer Pipe in einer Subshell | ||||||
|  | ausgef<EFBFBD>hrt wird. Die Variable \texttt{\$count} steht damit in der Schleife | ||||||
|  | praktisch nur lokal zur Verf<72>gung, sie wird nicht an das umgebende Skript | ||||||
|  | `hochgereicht'. | ||||||
|  |  | ||||||
|  | Neben der Methode in \ref{daten_hochreichen} bietet sich hier eine viel | ||||||
|  | einfachere L<>sung an: | ||||||
|  |  | ||||||
|  | \begin{lstlisting} | ||||||
|  | #!/bin/sh | ||||||
|  | count=0 | ||||||
|  | while read i; do | ||||||
|  |   uid=`echo $i | cut -f 3 -d:` | ||||||
|  |   if [ $uid -lt 100 ]; then | ||||||
|  |     count=`expr $count + 1` | ||||||
|  |     echo $count | ||||||
|  |   fi | ||||||
|  | done < /etc/passwd | ||||||
|  | echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Hier befindet sich die Schleife nicht in einer Pipe, daher wird sie auch nicht | ||||||
|  | in einer Subshell ausgef<65>hrt. Man kann auf das \texttt{cat}-Kommando verzichten | ||||||
|  | und den Inhalt der Datei durch die Umlenkung in Zeile 9 direkt auf die | ||||||
|  | Standardeingabe der Schleife (und somit auf das \texttt{read}-Kommando) legen. | ||||||
|  |  | ||||||
| Achtung! while ist eine Subshell - Daten m<>ssen hochgereicht werden. |  | ||||||
|  |  | ||||||
| \section{Ein typisches Init-Skript}\label{init-skript}\index{Init-Skript} | \section{Ein typisches Init-Skript}\label{init-skript}\index{Init-Skript} | ||||||
|  |  | ||||||
| Dieses Skript dient dazu, den Apache HTTP-Server zu starten. Es wird w<>hrend des Bootvorgangs gestartet, wenn der dazugeh<65>rige Runlevel initialisiert wird. | Dieses Skript dient dazu, den Apache HTTP-Server zu starten. Es wird w<>hrend | ||||||
|  | des Bootvorgangs gestartet, wenn der dazugeh<65>rige Runlevel initialisiert wird. | ||||||
|  |  | ||||||
| Das Skript mu<6D> mit einem Parameter\index{Parameter} aufgerufen werden. M<>glich sind hier \textsl{start}, \textsl{stop}, \textsl{status}, \textsl{restart} und  \textsl{reload}. Wenn falsche Parameter\index{Parameter} <20>bergeben wurden, wird eine entsprechende Meldung angezeigt. | Das Skript mu<6D> mit einem Parameter\index{Parameter} aufgerufen werden. M<>glich | ||||||
|  | sind hier \textsl{start}, \textsl{stop}, \textsl{status}, \textsl{restart} und | ||||||
|  | \textsl{reload}. Wenn falsche Parameter\index{Parameter} <20>bergeben wurden, wird | ||||||
|  | eine entsprechende Meldung angezeigt. | ||||||
|  |  | ||||||
| Das Ergebnis der Ausf<73>hrung wird mit Funktionen\index{Funktion} dargestellt, die aus der Datei \texttt{/etc/rc.d/init.d/functions} stammen. Ebenfalls in dieser Datei sind Funktionen, die einen Dienst starten oder stoppen. | Das Ergebnis der Ausf<73>hrung wird mit Funktionen\index{Funktion} dargestellt, | ||||||
|  | die aus der Datei \lstinline|functions| stammen. Ebenfalls in dieser Datei sind | ||||||
|  | Funktionen, die einen Dienst starten oder stoppen. | ||||||
|  |  | ||||||
| \begin{flushright} | Zun<EFBFBD>chst wird festgelegt, da<64> dieses Skript in der Bourne-Shell ausgef<65>hrt | ||||||
| Zun<EFBFBD>chst wird festgelegt, da<64> dieses Skript in der Bourne-Shell ausgef<65>hrt werden soll (\ref{auswahl_der_shell}). | werden soll (\ref{auswahl_der_shell}). | ||||||
| \end{flushright} |  | ||||||
| \footnotesize | \begin{lstlisting} | ||||||
| \begin{listing}[2]{1} |  | ||||||
| #!/bin/sh | #!/bin/sh | ||||||
| \end{listing} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Dann folgen Kommentare\index{Kommentar}, die den Sinn des Skriptes erl<72>utern (\ref{kommentare}). | Dann folgen Kommentare\index{Kommentar}, die den Sinn des Skriptes erl<72>utern | ||||||
| \end{flushright} | (\ref{kommentare}). | ||||||
| \footnotesize |  | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
| # | # | ||||||
| # Startup script for the Apache Web Server | # Startup script for the Apache Web Server | ||||||
| # | # | ||||||
| @@ -84,119 +150,109 @@ Dann folgen Kommentare\index{Kommentar}, die den Sinn des Skriptes erl | |||||||
| # config: /etc/httpd/conf/access.conf | # config: /etc/httpd/conf/access.conf | ||||||
| # config: /etc/httpd/conf/httpd.conf | # config: /etc/httpd/conf/httpd.conf | ||||||
| # config: /etc/httpd/conf/srm.conf | # config: /etc/httpd/conf/srm.conf | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Jetzt wird die Datei mit den Funktionen\index{Funktion} eingebunden (\ref{source}). | Jetzt wird die Datei mit den Funktionen\index{Funktion} eingebunden (\ref{source}). | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{source=\texttt{source}} | \index{source=\texttt{source}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
| # Source function library. | # Source function library. | ||||||
| . /etc/rc.d/init.d/functions | . /etc/rc.d/init.d/functions | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Hier werden die Aufrufparameter ausgewertet (\ref{case}). | Hier werden die Aufrufparameter ausgewertet (\ref{case}). | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}} | \index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
| # See how we were called. | # See how we were called. | ||||||
| case "$1" in | case "$1" in | ||||||
|   start) |   start) | ||||||
|         echo -n "Starting httpd: " |         echo -n "Starting httpd: " | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Nachdem eine Meldung <20>ber den auszuf<75>hrenden Vorgang ausgegeben wurde, wird die Funktion \texttt{daemon} aus der Funktionsbibliothek ausgef<65>hrt. Diese Funktion startet das Programm, dessen Name hier als Parameter\index{Parameter} <20>bergeben wird. Dann gibt sie eine Meldung <20>ber den Erfolg aus. | Nachdem eine Meldung <20>ber den auszuf<75>hrenden Vorgang ausgegeben wurde, wird die Funktion \texttt{daemon} aus der Funktionsbibliothek ausgef<65>hrt. Diese Funktion startet das Programm, dessen Name hier als Parameter\index{Parameter} <20>bergeben wird. Dann gibt sie eine Meldung <20>ber den Erfolg aus. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize | \begin{lstlisting}[firstnumber=last] | ||||||
| \begin{listingcont} |  | ||||||
|         daemon httpd |         daemon httpd | ||||||
|         echo |         echo | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Jetzt wird ein Lock-File\footnote{Ein Lock-File signalisiert anderen Prozessen, da<64> ein bestimmter Proze<7A> bereits gestartet ist. So kann ein zweiter Aufruf verhindert werden.} angelegt. | Jetzt wird ein Lock-File\footnote{Ein Lock-File signalisiert anderen Prozessen, da<64> ein bestimmter Proze<7A> bereits gestartet ist. So kann ein zweiter Aufruf verhindert werden.} angelegt. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{Anf<EFBFBD>hrungszeichen}\index{touch=\texttt{touch}} | \index{Anf<EFBFBD>hrungszeichen}\index{touch=\texttt{touch}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
|         touch /var/lock/subsys/httpd |         touch /var/lock/subsys/httpd | ||||||
|         ;; |         ;; | ||||||
|   stop) |   stop) | ||||||
|         echo -n "Shutting down http: " |         echo -n "Shutting down http: " | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Hier passiert im Prinzip das gleiche wie oben, nur da<64> mit der Funktion \texttt{killproc} der Daemon angehalten wird. | Hier passiert im Prinzip das gleiche wie oben, nur da<64> mit der Funktion \texttt{killproc} der Daemon angehalten wird. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize | \begin{lstlisting}[firstnumber=last] | ||||||
| \begin{listingcont} |  | ||||||
|         killproc httpd |         killproc httpd | ||||||
|         echo |         echo | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Danach werden Lock-File und PID-File\footnote{In einem sogenannten PID-File hinterlegen einige Prozesse ihre Proze<7A>-ID, um anderen Programmen den Zugriff zu erleichtern (z. B. um den Proze<7A> anzuhalten etc).} gel<65>scht. | Danach werden Lock-File und PID-File\footnote{In einem sogenannten PID-File hinterlegen einige Prozesse ihre Proze<7A>-ID, um anderen Programmen den Zugriff zu erleichtern (z. B. um den Proze<7A> anzuhalten etc).} gel<65>scht. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize | \begin{lstlisting}[firstnumber=last] | ||||||
| \begin{listingcont} |  | ||||||
|         rm -f /var/lock/subsys/httpd |         rm -f /var/lock/subsys/httpd | ||||||
|         rm -f /var/run/httpd.pid |         rm -f /var/run/httpd.pid | ||||||
|         ;; |         ;; | ||||||
|   status) |   status) | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Die Funktion \texttt{status} stellt fest, ob der entsprechende Daemon bereits l<>uft, und gibt das Ergebnis aus. | Die Funktion \texttt{status} stellt fest, ob der entsprechende Daemon bereits l<>uft, und gibt das Ergebnis aus. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize | \begin{lstlisting}[firstnumber=last] | ||||||
| \begin{listingcont} |  | ||||||
|         status httpd |         status httpd | ||||||
|         ;; |         ;; | ||||||
|   restart) |   restart) | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Bei Aufruf mit dem Parameter\index{Parameter} \textsl{restart} ruft sich das Skript zwei mal selbst auf (in \texttt{\$0} steht der Aufrufname des laufenden Programms). Einmal, um den Daemon zu stoppen, dann, um ihn wieder zu starten. | Bei Aufruf mit dem Parameter\index{Parameter} \textsl{restart} ruft sich das Skript zwei mal selbst auf (in \texttt{\$0} steht der Aufrufname des laufenden Programms). Einmal, um den Daemon zu stoppen, dann, um ihn wieder zu starten. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen} | \index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
|         $0 stop |         $0 stop | ||||||
|         $0 start |         $0 start | ||||||
|         ;; |         ;; | ||||||
|   reload) |   reload) | ||||||
|         echo -n "Reloading httpd: " |         echo -n "Reloading httpd: " | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Hier sendet die \texttt{killproc}-Funktion dem Daemon ein Signal\index{Signal} das ihm sagt, da<64> er seine Konfiguration neu einlesen soll. | Hier sendet die \texttt{killproc}-Funktion dem Daemon ein Signal\index{Signal} das ihm sagt, da<64> er seine Konfiguration neu einlesen soll. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen} | \index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
|         killproc httpd -HUP |         killproc httpd -HUP | ||||||
|         echo |         echo | ||||||
|         ;; |         ;; | ||||||
|   *) |   *) | ||||||
|         echo "Usage: $0 {start|stop|restart|reload|status}" |         echo "Usage: $0 {start|stop|restart|reload|status}" | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Bei aufruf mit einem beliebigen anderen Parameter\index{Parameter} wird eine Kurzhilfe ausgegeben. Dann wird daf<61>r gesorgt, da<64> das Skript mit dem Exit-Code 1 beendet wird. So kann festgestellt werden, ob das Skript ordnungsgem<65><6D> beendet wurde (\ref{exit}). | Bei aufruf mit einem beliebigen anderen Parameter\index{Parameter} wird eine Kurzhilfe ausgegeben. Dann wird daf<61>r gesorgt, da<64> das Skript mit dem Exit-Code 1 beendet wird. So kann festgestellt werden, ob das Skript ordnungsgem<65><6D> beendet wurde (\ref{exit}). | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{exit=\texttt{exit}} | \index{exit=\texttt{exit}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
|         exit 1 |         exit 1 | ||||||
| esac | esac | ||||||
|  |  | ||||||
| exit 0 | exit 0 | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
|  |  | ||||||
|  |  | ||||||
| \section{Parameter<EFBFBD>bergabe in der Praxis}\label{beisp_parameter}\index{Parameter} | \section{Parameter<EFBFBD>bergabe in der Praxis}\label{beisp_parameter}\index{Parameter} | ||||||
| @@ -205,21 +261,19 @@ Es kommt in der Praxis sehr oft vor, da | |||||||
|  |  | ||||||
| Das soll an folgendem Skript verdeutlicht werden. Das Skript kennt die Optionen \texttt{-a} und \texttt{-b}. Letzterer Option mu<6D> ein zus<75>tzlicher Wert mitgegeben werden. Alle anderen Parameter\index{Parameter} werden als Dateinamen interpretiert. | Das soll an folgendem Skript verdeutlicht werden. Das Skript kennt die Optionen \texttt{-a} und \texttt{-b}. Letzterer Option mu<6D> ein zus<75>tzlicher Wert mitgegeben werden. Alle anderen Parameter\index{Parameter} werden als Dateinamen interpretiert. | ||||||
|  |  | ||||||
| \footnotesize |  | ||||||
| \index{\$@=\texttt{\$@}}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{!|!|=\texttt{!|!|}}\index{getopt=\texttt{getopt}}\index{OR}\index{set=\texttt{set}} | \index{\$@=\texttt{\$@}}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{!|!|=\texttt{!|!|}}\index{getopt=\texttt{getopt}}\index{OR}\index{set=\texttt{set}} | ||||||
| \begin{listing}[2]{1} | \begin{lstlisting} | ||||||
| #!/bin/sh | #!/bin/sh | ||||||
| set -- `getopt "ab:" "$@"` || { | set -- `getopt "ab:" "$@"` || { | ||||||
| \end{listing} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Das \texttt{set}\index{set=\texttt{set}}-Kommando belegt den Inhalt der vordefinierten Variablen (\ref{vordefinierte_variablen}) neu, so da<64> es aussieht, als ob dem Skript die R<>ckgabewerte von \texttt{getopt}\index{getopt=\texttt{getopt}} <20>bergeben wurden. Man mu<6D> die beiden Minuszeichen angeben, da sie daf<61>r sorgen, da<64> die Aufrufparameter an \texttt{getopt}\index{getopt=\texttt{getopt}} und nicht an die Shell selbst <20>bergeben werden. Die originalen Parameter\index{Parameter} werden von \texttt{getopt}\index{getopt=\texttt{getopt}} untersucht und modifiziert zur<75>ckgegeben: \texttt{a} und \texttt{b} werden als Parameter\index{Parameter} Markiert, \texttt{b} sogar mit der M<>glichkeit einer zus<75>tzlichen Angabe. | Das \texttt{set}\index{set=\texttt{set}}-Kommando belegt den Inhalt der vordefinierten Variablen (\ref{vordefinierte_variablen}) neu, so da<64> es aussieht, als ob dem Skript die R<>ckgabewerte von \texttt{getopt}\index{getopt=\texttt{getopt}} <20>bergeben wurden. Man mu<6D> die beiden Minuszeichen angeben, da sie daf<61>r sorgen, da<64> die Aufrufparameter an \texttt{getopt}\index{getopt=\texttt{getopt}} und nicht an die Shell selbst <20>bergeben werden. Die originalen Parameter\index{Parameter} werden von \texttt{getopt}\index{getopt=\texttt{getopt}} untersucht und modifiziert zur<75>ckgegeben: \texttt{a} und \texttt{b} werden als Parameter\index{Parameter} Markiert, \texttt{b} sogar mit der M<>glichkeit einer zus<75>tzlichen Angabe. | ||||||
|  |  | ||||||
| Wenn dieses Kommando fehlschl<68>gt ist das ein Zeichen daf<61>r, da<64> falsche Parameter\index{Parameter} <20>bergeben wurden. Also wird nach einer entsprechenden Meldung das Programm mit Exit-Code 1 verlassen. | Wenn dieses Kommando fehlschl<68>gt ist das ein Zeichen daf<61>r, da<64> falsche Parameter\index{Parameter} <20>bergeben wurden. Also wird nach einer entsprechenden Meldung das Programm mit Exit-Code 1 verlassen. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{\$n=\texttt{\$}$n$}\index{Null-Befehl}\index{!>\&=\texttt{!>\&}}\index{!==\texttt{!=}}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}} | \index{\$n=\texttt{\$}$n$}\index{Null-Befehl}\index{!>\&=\texttt{!>\&}}\index{!==\texttt{!=}}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
|    echo "Anwendung: `basename $0` [-a] [-b Name] Dateien" 1>&2 |    echo "Anwendung: `basename $0` [-a] [-b Name] Dateien" 1>&2 | ||||||
|    exit 1 |    exit 1 | ||||||
| } | } | ||||||
| @@ -227,98 +281,284 @@ echo "Momentan steht in der Kommandozeile folgendes: $*" | |||||||
| aflag=0 name=NONE | aflag=0 name=NONE | ||||||
| while : | while : | ||||||
| do | do | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| In einer Endlosschleife\index{Endlosschleife}, die man mit Hilfe des Null-Befehls (\texttt{:}, \ref{null-befehl}) baut, werden die `neuen' Parameter\index{Parameter} der Reihe nach untersucht. Wenn ein \texttt{-a} vorkommt, wird die Variable \texttt{aflag} gesetzt. Bei einem \texttt{-b} werden per \texttt{shift}\index{shift=\texttt{shift}} alle Parameter\index{Parameter} nach Links verschoben, dann wird der Inhalt des n<>chsten Parameters\index{Parameter} in der Variablen \texttt{name} gesichert. | In einer Endlosschleife\index{Endlosschleife}, die man mit Hilfe des Null-Befehls (\texttt{:}, \ref{null-befehl}) baut, werden die `neuen' Parameter\index{Parameter} der Reihe nach untersucht. Wenn ein \texttt{-a} vorkommt, wird die Variable \texttt{aflag} gesetzt. Bei einem \texttt{-b} werden per \texttt{shift}\index{shift=\texttt{shift}} alle Parameter\index{Parameter} nach Links verschoben, dann wird der Inhalt des n<>chsten Parameters\index{Parameter} in der Variablen \texttt{name} gesichert. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{!==\texttt{!=}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}}\index{shift=\texttt{shift}} | \index{!==\texttt{!=}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}}\index{shift=\texttt{shift}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
|    case "$1" in |    case "$1" in | ||||||
|     -a) aflag=1 ;; |     -a) aflag=1 ;; | ||||||
|     -b) shift; name="$1" ;; |     -b) shift; name="$1" ;; | ||||||
|     --) break ;; |     --) break ;; | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Wenn ein \texttt{-{}-} erscheint, ist das ein Hinweis darauf, da<64> die Liste der Parameter\index{Parameter} abgearbeitet ist. Dann wird per \texttt{break}\index{break=\texttt{break}} (\ref{break}) die Endlosschleife unterbrochen. Die Aufrufparameter enthalten jetzt nur noch die eventuell angegebenen Dateinamen, die jetzt von dem Restlichen Skript wie gewohnt weiterverarbeitet werden k<>nnen.  | Wenn ein \texttt{-{}-} erscheint, ist das ein Hinweis darauf, da<64> die Liste der Parameter\index{Parameter} abgearbeitet ist. Dann wird per \texttt{break}\index{break=\texttt{break}} (\ref{break}) die Endlosschleife unterbrochen. Die Aufrufparameter enthalten jetzt nur noch die eventuell angegebenen Dateinamen, die jetzt von dem Restlichen Skript wie gewohnt weiterverarbeitet werden k<>nnen.  | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{shift=\texttt{shift}} | \index{shift=\texttt{shift}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
|    esac |    esac | ||||||
|    shift |    shift | ||||||
| done | done | ||||||
| shift | shift | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Am Ende werden die Feststellungen ausgegeben. | Am Ende werden die Feststellungen ausgegeben. | ||||||
| \end{flushright} |  | ||||||
| \footnotesize |  | ||||||
| \index{\$*=\texttt{\$*}}\index{Anf<EFBFBD>hrungszeichen} | \index{\$*=\texttt{\$*}}\index{Anf<EFBFBD>hrungszeichen} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
| echo "aflag=$aflag / Name = $name / Die Dateien sind $*" | echo "aflag=$aflag / Name = $name / Die Dateien sind $*" | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
|  |  | ||||||
|  |  | ||||||
| \section{Fallensteller: Auf Traps  | \section{Fallensteller: Auf Traps reagieren}\label{traps}\index{trap=\texttt{trap}|(}\index{Signal|(} | ||||||
| reagieren}\label{traps}\index{trap=\texttt{trap}|(}\index{Signal|(} |  | ||||||
|  |  | ||||||
| Ein laufendes Shell-Skript kann durch Druck auf die Interrupt-Taste (normalerweise \Ovalbox{CTRL}-\Ovalbox{C}) unterbrochen werden. Durch Druck auf diese Taste wird ein Signal an den entsprechenden Proze<7A> gesandt, das ihn bittet sich zu beenden. Dieses Signal hei<65>t SIGINT (f<>r SIGnal INTerrupt) und tr<74>gt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript sich tempor<6F>re Dateien angelegt hat, da diese nach der Ausf<73>hrung nur noch unn<6E>tig Platz verbrauchen und eigentlich gel<65>scht werden sollten.  Man kann sich sicher auch noch wichtigere F<>lle vorstellen, in denen ein Skript bestimmte Aufgaben auf jeden Fall erledigen mu<6D>, bevor es sich beendet. | Ein laufendes Shell-Skript kann durch Druck auf die Interrupt-Taste | ||||||
|  | (\Ovalbox{CTRL}+\Ovalbox{C}) unterbrochen werden. Durch Druck auf | ||||||
|  | diese Taste wird ein Signal an den entsprechenden Proze<7A> gesandt, das ihn | ||||||
|  | bittet sich zu beenden. Dieses Signal hei<65>t SIGINT (f<>r SIGnal INTerrupt) und | ||||||
|  | tr<EFBFBD>gt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript | ||||||
|  | sich tempor<6F>re Dateien angelegt hat, da diese nach der Ausf<73>hrung nur noch | ||||||
|  | unn<EFBFBD>tig Platz verbrauchen und eigentlich gel<65>scht werden sollten.  Man kann | ||||||
|  | sich sicher auch noch wichtigere F<>lle vorstellen, in denen ein Skript | ||||||
|  | bestimmte Aufgaben auf jeden Fall erledigen mu<6D>, bevor es sich beendet. | ||||||
|  |  | ||||||
| Es gibt eine Reihe weiterer Signale, auf die ein Skript reagieren kann. Alle sind in der Man-Page von \texttt{signal} beschrieben. Hier die wichtigsten:\nopagebreak | Es gibt eine Reihe weiterer Signale, auf die ein Skript reagieren kann. Alle | ||||||
|  | sind in der Man-Page von \texttt{signal} beschrieben. Hier die | ||||||
|  | wichtigsten:\nopagebreak | ||||||
|  |  | ||||||
| \LTXtable{\textwidth}{tab_signale.tex} | \LTXtable{\textwidth}{tab_signale.tex} | ||||||
|  |  | ||||||
| Wie l<>st man jetzt dieses Problem? Gl<47>cklicherweise verf<72>gt die Shell <20>ber das \texttt{trap}-Kommando, mit dessen Hilfe man auf diese Signale reagieren kann. Die Anwendung soll in folgendem Skript beispielhaft dargestellt werden. | Wie l<>st man jetzt dieses Problem? Gl<47>cklicherweise verf<72>gt die Shell <20>ber das | ||||||
|  | \texttt{trap}-Kommando, mit dessen Hilfe man auf diese Signale reagieren kann. | ||||||
|  | Die Anwendung soll in folgendem Skript beispielhaft dargestellt werden. | ||||||
|  |  | ||||||
| Das Skript soll eine komprimierte Textdatei mittels \texttt{zcat} in ein tempor<6F>res File entpacken, dieses mit \texttt{pg} seitenweise anzeigen und nachher wieder l<>schen. | Das Skript soll eine komprimierte Textdatei mittels \texttt{zcat} in ein | ||||||
|  | tempor<EFBFBD>res File entpacken, dieses mit \texttt{pg} seitenweise anzeigen und | ||||||
|  | nachher wieder l<>schen. | ||||||
|  |  | ||||||
| \footnotesize |  | ||||||
| \index{!==\texttt{!=}} | \index{!==\texttt{!=}} | ||||||
| \begin{listing}[2]{1} | \begin{lstlisting} | ||||||
| #!/bin/sh | #!/bin/sh | ||||||
| stat=1 | stat=1 | ||||||
| temp=/tmp/zeige$$ | temp=/tmp/zeige$$ | ||||||
| \end{listing} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Zun<EFBFBD>chst werden zwei Variablen belegt, die im weiteren Verlauf benutzt werden sollen. In \texttt{stat} wird der Wert abgelegt, den das Skript im Falle eines Abbruchs als Exit-Status zur<75>ckliefern soll. Die Variable \texttt{temp} enth<74>lt den Namen f<>r eine tempor<6F>re Datei. Dieser setzt sich zusammen aus \texttt{/tmp/zeige} und der Proze<7A>nummer des laufenden Skripts. So soll sichergestellt werden, da<64> noch keine Datei mit diesem Namen existiert. | Zun<EFBFBD>chst werden zwei Variablen belegt, die im weiteren Verlauf benutzt werden | ||||||
| \end{flushright} | sollen. In \texttt{stat} wird der Wert abgelegt, den das Skript im Falle eines | ||||||
| \footnotesize | Abbruchs als Exit-Status zur<75>ckliefern soll. Die Variable \texttt{temp} enth<74>lt | ||||||
|  | den Namen f<>r eine tempor<6F>re Datei. Dieser setzt sich zusammen aus | ||||||
|  | \texttt{/tmp/zeige} und der Proze<7A>nummer des laufenden Skripts. So soll | ||||||
|  | sichergestellt werden, da<64> noch keine Datei mit diesem Namen existiert. | ||||||
|  |  | ||||||
| \index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}} | \index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
| trap 'rm -f $temp; exit $stat' 0 | trap 'rm -f $temp; exit $stat' 0 | ||||||
| trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15 | trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15 | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Hier werden die Traps definiert. Bei Signal 0 wird die tempor<6F>re Datei gel<65>scht und der Wert aus der Variable \texttt{stat} als Exit-Code zur<75>ckgegeben. Dabei wird dem \texttt{rm}-Kommando der Parameter\index{Parameter} \texttt{-f} mitgegeben, damit keine Fehlermeldung ausgegeben wird, falls die Datei (noch) nicht existiert. Dieser Fall tritt bei jedem Beenden des Skriptes auf, also sowohl bei einem normalen Ende, als auch beim Exit-Kommando, bei einem Interrupt oder bei einem Kill\index{kill=\texttt{kill}}. Der zweite Trap reagiert auf die Signale 1, 2 und 15. Das hei<65>t, er wird bei jedem unnormalen Ende ausgef<65>hrt. Er gibt eine entsprechende Meldung auf die Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet, und der erste Trap wird ausgef<65>hrt.  | Hier werden die Traps definiert. Bei Signal 0 wird die tempor<6F>re Datei gel<65>scht | ||||||
| \end{flushright} | und der Wert aus der Variable \texttt{stat} als Exit-Code zur<75>ckgegeben. Dabei | ||||||
| \footnotesize | wird dem \texttt{rm}-Kommando der Parameter\index{Parameter} \texttt{-f} | ||||||
|  | mitgegeben, damit keine Fehlermeldung ausgegeben wird, falls die Datei (noch) | ||||||
|  | nicht existiert. Dieser Fall tritt bei jedem Beenden des Skriptes auf, also | ||||||
|  | sowohl bei einem normalen Ende, als auch beim Exit-Kommando, bei einem | ||||||
|  | Interrupt oder bei einem Kill\index{kill=\texttt{kill}}. Der zweite Trap | ||||||
|  | reagiert auf die Signale 1, 2 und 15. Das hei<65>t, er wird bei jedem unnormalen | ||||||
|  | Ende ausgef<65>hrt. Er gibt eine entsprechende Meldung auf die | ||||||
|  | Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet, | ||||||
|  | und der erste Trap wird ausgef<65>hrt.  | ||||||
|  |  | ||||||
| \index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}} | \index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
| case $# in | case $# in | ||||||
|  1) zcat "$1" > $temp |  1) zcat "$1" > $temp | ||||||
|     pg $temp |     pg $temp | ||||||
|     stat=0 |     stat=0 | ||||||
|     ;; |     ;; | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Jetzt kommt die eigentliche Funktionalit<69>t des Skriptes: Das \texttt{case}-Kommando (\ref{case}) testet die Anzahl der <20>bergebenen Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} <20>bergeben wurde, entpackt \texttt{zcat} die Datei, die im ersten Parameter\index{Parameter} angegeben wurde, in die tempor<6F>re Datei. Dann folgt die Seitenweise Ausgabe mittels \texttt{pg}. Nach Beendigung der Ausgabe wird der Status in der Variablen auf 0 gesetzt, damit beim Skriptende der korrekte Exit-Code zur<75>ckgegeben wird. | Jetzt kommt die eigentliche Funktionalit<69>t des Skriptes: Das | ||||||
| \end{flushright} | \texttt{case}-Kommando (\ref{case}) testet die Anzahl der <20>bergebenen | ||||||
| \footnotesize | Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} <20>bergeben | ||||||
|  | wurde, entpackt \texttt{zcat} die Datei, die im ersten | ||||||
|  | Parameter\index{Parameter} angegeben wurde, in die tempor<6F>re Datei. Dann folgt | ||||||
|  | die Seitenweise Ausgabe mittels \texttt{pg}. Nach Beendigung der Ausgabe wird | ||||||
|  | der Status in der Variablen auf 0 gesetzt, damit beim Skriptende der korrekte | ||||||
|  | Exit-Code zur<75>ckgegeben wird. | ||||||
|  |  | ||||||
| \index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}} | \index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}} | ||||||
| \begin{listingcont} | \begin{lstlisting}[firstnumber=last] | ||||||
|  *) echo "Anwendung: `basename $0` Dateiname" 1>&2 |  *) echo "Anwendung: `basename $0` Dateiname" 1>&2 | ||||||
| esac | esac | ||||||
| \end{listingcont} |  | ||||||
| \normalsize | \end{lstlisting} | ||||||
| \begin{flushright} |  | ||||||
| Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit der Aufrufsyntax auf die Standard-Fehlerausgabe geschrieben. | Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit | ||||||
| \end{flushright} | der Aufrufsyntax auf die Standard-Fehlerausgabe geschrieben. | ||||||
|  |  | ||||||
| \index{trap=\texttt{trap}|)}\index{Signal|)} | \index{trap=\texttt{trap}|)}\index{Signal|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | \section{Chaoten: Dateien in zuf<75>llige Reihenfolge bringen}\label{chaoten}\index{Zufallszahlen|(} | ||||||
|  |  | ||||||
|  | Wir wollen uns einen MP3-Player programmieren, der Alle MP3-Dateien aus einem | ||||||
|  | bestimmten Verzeichnisbaum in zuf<75>lliger Reihenfolge abspielt. Damit dieses | ||||||
|  | Problem f<>r uns eine Herausforderung darstellt\footnote{Denn schlie<69>lich hat | ||||||
|  | mpg123 schon von Hause aus eine Random-Funktion.}, wollen wir vor dem Abspielen | ||||||
|  | der jeweiligen Datei etwas mit dem Dateinamen anstellen. Ob das eine einfache | ||||||
|  | Ausgabe per \texttt{echo} ist, oder ob der Name per Sprachsynthese oder auf | ||||||
|  | einem externen Display angezeigt werden soll ist an dieser Stelle egal. | ||||||
|  |  | ||||||
|  | Das Problem ist, da<64> wir in der Shell nur <20>ber Umwege an Zufallszahlen kommen | ||||||
|  | k<EFBFBD>nnen. Auf Systemen, in denen die Datei \texttt{/dev/urandom} existiert, | ||||||
|  | liefert uns der Kernel aber schon sehr zuf<75>llige Zeichenfolgen. Diese Folgen | ||||||
|  | k<EFBFBD>nnen alle Zeichen enthalten, daher m<>ssen sie vor der Benutzung f<>r unsere | ||||||
|  | Zwecke noch etwas `bereinigt' werden. | ||||||
|  |  | ||||||
|  | Wie das aussieht, wenn es fertig ist, sieht man im folgenden Skript: | ||||||
|  |  | ||||||
|  | \index{!==\texttt{!=}} | ||||||
|  | \begin{lstlisting} | ||||||
|  | #!/bin/sh | ||||||
|  | for i in `find $1 -type f -name "*.[mM][pP]3"`; do | ||||||
|  |  | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Hier beginnt eine Schleife, die <20>ber alle Ausgaben des \texttt{find}-Kommandos | ||||||
|  | iteriert. Dabei sucht \texttt{find} nach allen normalen Dateien (\texttt{-type | ||||||
|  | f}), die die Extension .mp3 tragen (\texttt{-name \dq*.[mM][pP]3\dq} -- wir | ||||||
|  | ignorieren Gro<72>- / Kleinschreibung). | ||||||
|  |  | ||||||
|  | \index{find=\texttt{find}} | ||||||
|  | \begin{lstlisting}[firstnumber=last] | ||||||
|  |   echo `tr -dc "[:alpha:]" < /dev/urandom | \ | ||||||
|  |         dd count=8 bs=1 2> /dev/null`$i | ||||||
|  |  | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Hier ist der `magische Teil'. Mit dem \texttt{echo} wird die Ausgabe einer Pipe | ||||||
|  | ausgegeben, gefolgt von dem aktuellen Dateinamen. Diese Pipe enth<74>lt ein | ||||||
|  | \texttt{tr}, der alle ungewollten Zeichen (alles, was kein Textzeichen ist) aus | ||||||
|  | einem Datenstrom entfernt. Die Daten erh<72>lt \texttt{tr} durch die | ||||||
|  | \texttt{<}-Umleitung aus oben genannter Datei. | ||||||
|  |  | ||||||
|  | Diese Datei liefert `ohne Ende' Zeichen. Wir wollen aber nur acht Zeichen | ||||||
|  | haben, die wir unserem Dateinamen voranstellen k<>nnen. Dazu benutzen wir das | ||||||
|  | Kommando \texttt{dd} mit den angegebenen Parametern. Damit die Erfolgsmeldung | ||||||
|  | von \texttt{dd} nicht die Ausgabe verunstaltet, lenken wir sie nach | ||||||
|  | \texttt{/dev/null} um. | ||||||
|  | \index{tr=\texttt{tr}}\index{dd=\texttt{dd}} | ||||||
|  |  | ||||||
|  | \index{find=\texttt{find}} | ||||||
|  | \begin{lstlisting}[firstnumber=last] | ||||||
|  | done | sort | cut -b 9- | while read i; do | ||||||
|  |  | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Das Ergebnis der obigen Schleife ist also die Liste der Dateinamen, denen | ||||||
|  | jeweils acht zuf<75>llige Zeichen vorangestellt wurden. Die Reihenfolge entspricht | ||||||
|  | allerdings immer noch der Ausgabe von \texttt{find}, wird also nach jedem | ||||||
|  | Durchlauf gleich sein. | ||||||
|  |  | ||||||
|  | Um das zu <20>ndern, pipen wir die Ausgabe der Schleife durch ein \texttt{sort}. | ||||||
|  | Da die ersten acht Zeichen jeder Zeile zuf<75>llig sind, erhalten wir so eine | ||||||
|  | zuf<EFBFBD>llige Reihenfolge der Zeilen. Jetzt m<>ssen wir nur noch durch ein | ||||||
|  | \texttt{cut} die zuf<75>lligen Zeichen abschneiden, und erhalten so die | ||||||
|  | urspr<EFBFBD>ngliche Liste von Dateien in einer zuf<75>lligen Reihenfolge. | ||||||
|  |  | ||||||
|  | Diese lesen wir jetzt zeilenweise mittels \texttt{read} ein. In der | ||||||
|  | \texttt{while}-Schleife k<>nnen wir alle erforderlichen Sachen mit dem | ||||||
|  | Dateinamen anstellen. Hier wird er nur mittels \texttt{echo} ausgegeben. | ||||||
|  | \index{sort=\texttt{sort}}\index{cut=\texttt{cut}} \index{read=\texttt{read}}\index{while=\texttt{while}} | ||||||
|  |  | ||||||
|  | \index{find=\texttt{find}} | ||||||
|  | \begin{lstlisting}[firstnumber=last] | ||||||
|  |   echo "Jetzt wird $i gespielt" | ||||||
|  |   mpg123 "$i" | ||||||
|  | done | ||||||
|  |  | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | \index{Zufallszahlen|)} | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | \section{Wer suchet, der findet}\label{beispiele_suchen}\index{grep=\texttt{grep}|(textbf} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | \subsection{Prozesse suchen}\label{beispiele_suchen_prozesse}\index{ps=\texttt{ps}|(textbf}\index{pgrep=\texttt{pgrep}|(textbf} | ||||||
|  |  | ||||||
|  | Im Zusammenhang mit grep st<73><74>t fast jeder Shell-Skripter fr<66>her oder sp<73>ter auf | ||||||
|  | das Problem, da<64> er irgendwas davon abh<62>ngig machen will, ob ein bestimmter | ||||||
|  | Proze<EFBFBD> l<>uft oder nicht. Im Normalfall wird er zuerst folgendes ausprobieren, | ||||||
|  | was aber oft (nicht immer) in die Hose gehen wird: | ||||||
|  |  | ||||||
|  | \lstinline/ps aux | grep prozessname && echo "l<>uft schon"/ | ||||||
|  |  | ||||||
|  | Der Grund daf<61>r ist, da<64> unter Umst<73>nden in der Ausgabe von \texttt{ps} auch | ||||||
|  | das \texttt{grep}-Kommando samt Parameter (\textit{prozessname}) aufgelistet | ||||||
|  | wird. So findet das \texttt{grep}-Kom\-man\-do sich quasi selbst. | ||||||
|  |  | ||||||
|  | Abhilfe schafft entweder \texttt{pgrep} (\ref{pgrep}) oder das folgende | ||||||
|  | Konstrukt: | ||||||
|  |  | ||||||
|  | \lstinline/ps aux | grep "[p]rozessname" && echo "l<>uft schon"/ | ||||||
|  |  | ||||||
|  | Das p ist jetzt als eine Zeichenmenge (regul<EFBFBD>rer Ausdruck) angegeben worden. | ||||||
|  | Jetzt sucht \texttt{grep} also nach dem String \textit{prozessname}, in der | ||||||
|  | Ausgabe von \texttt{ps} erscheint das \texttt{grep}-Kommando allerdings mit | ||||||
|  | \textit{[p]rozessname} und wird somit ignoriert. | ||||||
|  |  | ||||||
|  | \index{ps=\texttt{ps}|)textbf}\index{pgrep=\texttt{pgrep}|)textbf} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | \subsection{Dateiinhalte suchen}\label{beispiele_suchen_dateien}\index{find=\texttt{find}|(textbf} | ||||||
|  |  | ||||||
|  | Ein weiterer wertvoller Trick, diesmal im Zusammenhang mit \texttt{find}, ist | ||||||
|  | folgendes Szenario: Es gibt ein Verzeichnis mit vielen Unterverzeichnissen, | ||||||
|  | <EFBFBD>berall liegen Perl-Skripte und andere Dateien. Gesucht sind alle Dateien, in | ||||||
|  | denen eine Zeile mit dem Inhalt `strict' vorkommt. Man k<>nnte jetzt | ||||||
|  | folgendes versuchen: | ||||||
|  |  | ||||||
|  | \lstinline|grep -r strict *| | ||||||
|  |  | ||||||
|  | Das f<>hrt allerdings dazu, da<64> alle Dateien durchsucht werden, nicht nur die | ||||||
|  | Perl-Skripte. Diese tragen nach unserer Konvention\footnote{Perl-Skripte m<>ssen | ||||||
|  | keine spezielle Extension haben, es sei aber um des Beispiels Willen mal | ||||||
|  | angenommen.} die Extension `.pl'. Wir starten also eine rekursive Suche <20>ber | ||||||
|  | alle Dateien, die dem Muster entsprechen: | ||||||
|  |  | ||||||
|  | \lstinline|grep -r strict *.pl| | ||||||
|  |  | ||||||
|  | Und wieder f<>hrt es nicht zu dem gew<65>nschten Ergebnis. Da die | ||||||
|  | Unterverzeichnisse nicht die Extension `*.pl' tragen, werden sie nicht | ||||||
|  | ber<EFBFBD>cksichtigt. F<>r die Suche in Unterverzeichnissen ziehen wir \texttt{find} | ||||||
|  | (Siehe Abschnitt \ref{find}) heran: | ||||||
|  |  | ||||||
|  | \lstinline|find . -name \*.pl -exec grep strict {} \;| | ||||||
|  |  | ||||||
|  | Dieser Befehl gibt uns zwar die gefundenen Zeilen aus, nicht aber die Namen der | ||||||
|  | Dateien. Es sieht f<>r \texttt{grep} so aus als ob nur eine Datei durchsucht | ||||||
|  | w<EFBFBD>rde, da besteht keine Notwendigkeit den Namen anzugeben. Das ginge mit dem | ||||||
|  | Parameter \texttt{-l}, allerdings w<>rden uns dann nur noch die Dateinamen | ||||||
|  | angezeigt. Eine Ausgabe mit beiden Informationen erhalten wir mit dem folgenden | ||||||
|  | Konstrukt: | ||||||
|  |  | ||||||
|  | \lstinline|find . -name \*.pl -exec grep strict /dev/null {} \;| | ||||||
|  |  | ||||||
|  | Hier durchsucht \texttt{grep} nicht nur die gefundenen Dateien, sondern bei | ||||||
|  | jedem Aufruf auch \texttt{/dev/null}, also den digitalen M<>lleimer der per | ||||||
|  | Definition leer ist. Da es f<>r \texttt{grep} so aussieht als ob mehr als eine | ||||||
|  | Datei durchsucht w<>rden, wird bei jeder Fundstelle sowohl der Dateiname als | ||||||
|  | auch die gefundene Zeile ausgegeben. | ||||||
|  |  | ||||||
|  | \index{find=\texttt{find}|)textbf} | ||||||
|  | \index{grep=\texttt{grep}|)textbf} | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								quellen.tex
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								quellen.tex
									
									
									
									
									
								
							| @@ -1,10 +1,17 @@ | |||||||
| \chapter{Quellen} | % $Id$ | ||||||
|  | \chapter{Quellen}\label{quellen} | ||||||
|  |  | ||||||
| \begin{itemize} | \begin{itemize} | ||||||
| \item Bash Reference Manual (\texttt{http://www.gnu.org/manual/bash-2.02/\\bashref.html}) | \item Bash Reference Manual (\href{http://www.gnu.org/manual/bash-2.02/bashref.html}{http://www.gnu.org/manual/bash-2.02/bashref.html}) | ||||||
| \item Unix In A Nutshell (\texttt{http://www.oreilly.com/catalog/unixnut3/}) | \item Die Man-Page der Bash | ||||||
| \item Unix Power Tools (\texttt{http://www.oreilly.com/catalog/upt2/}) | \item Die deutschsprachige Shell-Newsgroup (\href{news://de.comp.os.unix.shell}{news://de.comp.os.unix.shell}) | ||||||
| \item Von DOS nach Linux HOWTO (\texttt{http://www.tu-harburg.de/\\\~{}semb2204/dlhp/HOWTO/DE-DOS-nach-Linux-HOWTO.html}) | \item Unix In A Nutshell (\href{http://www.oreilly.com/catalog/unixnut3/}{http://www.oreilly.com/catalog/unixnut3/}) | ||||||
|  | \item Unix Power Tools (\href{http://www.oreilly.com/catalog/upt2/}{http://www.oreilly.com/catalog/upt2/}) | ||||||
|  | \item Von DOS nach Linux HOWTO (\href{http://www.linuxhaven.de/dlhp/HOWTO/DE-DOS-nach-Linux-HOWTO.html}{http://www.linuxhaven.de/dlhp/HOWTO/DE-DOS-nach-Linux-HOWTO.html}) | ||||||
|  | \item Bash Guide for Beginners (\href{http://tldp.org/LDP/Bash-Beginners-Guide/}{http://tldp.org/LDP/Bash-Beginners-Guide/}) | ||||||
|  | \item Advanced Bash-Scripting Guide (\href{http://tldp.org/LDP/abs/}{http://tldp.org/LDP/abs/}) | ||||||
|  | \item The Open Group Base Specifications | ||||||
|  | \item Single Unix Specifications V2 | ||||||
| \item ... und eine Menge Skripte, die ich im Laufe der Zeit gelesen habe (das | \item ... und eine Menge Skripte, die ich im Laufe der Zeit gelesen habe (das | ||||||
| kann ich nur jedem empfehlen - es ist spannender als es sich anh<6E>rt...). | kann ich nur jedem empfehlen - es ist spannender als es sich anh<6E>rt...). | ||||||
| \end{itemize} | \end{itemize} | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
| \chapter{Schmutzige Tricks :-)} | \chapter{Schmutzige Tricks :-)} | ||||||
|  |  | ||||||
| Eigentlich sind diese Tricks gar nicht so schmutzig. Hier ist lediglich eine | Eigentlich sind diese Tricks gar nicht so schmutzig. Hier ist lediglich eine | ||||||
| @@ -23,29 +24,378 @@ haben. | |||||||
|  |  | ||||||
| \section{Die Tar-Br<42>cke} | \section{Die Tar-Br<42>cke} | ||||||
|  |  | ||||||
| TODO!!! | Eine sogenannte Tar-Br<42>cke benutzt man, wenn eine oder mehrere Dateien zwischen | ||||||
|  | Rechnern <20>bertragen werden sollen, aber kein Dienst wie SCP oder FTP zur | ||||||
|  | Verf<EFBFBD>gung steht. Au<41>erdem hat die Methode den Vorteil, da<64> Benutzerrechte und | ||||||
|  | andere Dateiattribute bei der <20>bertragung erhalten | ||||||
|  | bleiben\footnote{Vorausgesetzt nat<61>rlich, da<64> der Benutzer auf der entfernten | ||||||
|  | Seite <20>ber die n<>tigen Rechte verf<72>gt.}. | ||||||
|  |  | ||||||
|  | Der Trick besteht darin, auf einer Seite der Verbindung etwas mit \texttt{tar} | ||||||
|  | einzupacken, dies durch eine Pipe auf die andere Seite der Verbindung zu | ||||||
|  | bringen und dort wieder zu entpacken. | ||||||
|  |  | ||||||
|  | Wenn dem Kommando \texttt{tar} an Stelle eines Dateinamens ein Minus-Zeichen | ||||||
|  | als Archiv gegeben wird, benutzt es~--~je nach der gew<65>hlten Aktion~--~die | ||||||
|  | Standard-Ein- bzw. -Ausgabe. Diese kann an ein weiteres \texttt{tar} <20>bergeben | ||||||
|  | werden um wieder entpackt zu werden. | ||||||
|  |  | ||||||
|  | Ein Beispiel verdeutlicht diese Kopier-F<>higkeit: | ||||||
|  |  | ||||||
|  | \lstinline_tar cf - . | ( cd /tmp/backup; tar xf - )_ | ||||||
|  |  | ||||||
|  | Hier wird zun<75>chst der Inhalt des aktuellen Verzeichnisses `verpackt'. Das | ||||||
|  | Resultat wird an die Standard-Ausgabe geschrieben. Auf der Empf<70>ngerseite der | ||||||
|  | Pipe wird eine Subshell ge<67>ffnet. Das ist notwendig, da das empfangende | ||||||
|  | \texttt{tar} in einem anderen Verzeichnis laufen soll. In der Subshell wird | ||||||
|  | zun<EFBFBD>chst das Verzeichnis gewechselt. Dann liest ein \texttt{tar} von der | ||||||
|  | Standard-Eingabe und entpackt alles was er findet. Sobald keine Eingaben mehr | ||||||
|  | kommen, beendet sich der Proze<7A> mitsamt der Subshell. | ||||||
|  |  | ||||||
|  | Am Ziel-Ort finden sich jetzt die gleichen Dateien wie am Quell-Ort. | ||||||
|  |  | ||||||
|  | Das lie<69>e sich lokal nat<61>rlich auch anders l<>sen. Man k<>nnte erst ein Archiv | ||||||
|  | erstellen, das dann an anderer Stelle wieder auspacken. Nachteil: Es mu<6D> | ||||||
|  | gen<EFBFBD>gend Platz f<>r das Archiv vorhanden sein. Denkbar w<>re auch ein in den Raum | ||||||
|  | gestelltes | ||||||
|  |  | ||||||
|  | \lstinline_cp -Rp * /tmp/backup_ | ||||||
|  |  | ||||||
|  | Allerdings fehlen einem dabei mitunter n<>tzliche | ||||||
|  | \texttt{tar}-Optionen\footnote{Mit \texttt{-l} verl<72><6C>t \texttt{tar} | ||||||
|  | beispielsweise nicht das File-System. N<>tzlich wenn nur eine Partition | ||||||
|  | gesichert werden soll.}, und die oben erw<72>hnte Br<42>cke w<>re mit einem reinen | ||||||
|  | \texttt{cp} nicht m<>glich. | ||||||
|  |  | ||||||
|  | Eine Seite der Pipe kann n<>mlich auch ohne Probleme auf einem entfernten | ||||||
|  | Rechner `stattfinden'. Kommandos wie \texttt{ssh} oder \texttt{rsh} (letzteres | ||||||
|  | nur unter Vorsicht einsetzen!) schlagen die Br<42>cke zu einem anderen System, | ||||||
|  | dort wird entweder gepackt und versendet oder quasi die Subshell gestartet und | ||||||
|  | gelesen. Das sieht wie folgt aus: | ||||||
|  |  | ||||||
|  | \lstinline_ssh 192.168.2.1 tar clf - / | (cd /mnt/backup; tar xf - )_ | ||||||
|  |  | ||||||
|  | Hier wird auf einem entfernten Rechner die Root-Partition verpackt, per SSH in | ||||||
|  | das lokale System geholt und lokal im Backup-Verzeichnis entpackt. | ||||||
|  |  | ||||||
|  | Der Weg in die andere Richtung ist ganz <20>hnlich: | ||||||
|  |  | ||||||
|  | \lstinline_tar cf - datei.txt | ssh 192.168.2.1 "(mkdir -p $PWD ;cd $PWD; tar xf -)"_ | ||||||
|  |  | ||||||
|  | Hier wird die Datei verpackt und versendet. Eine Besonderheit gegen<65>ber dem | ||||||
|  | vorigen Beispiel besteht darin, da<64> das Zielverzeichnis bei Bedarf erstellt | ||||||
|  | wird, bevor die Datei dort entpackt wird. Zur Erkl<6B>rung: Die Variable | ||||||
|  | \texttt{\$PWD} wird, da sie nicht von Ticks `gesichert' wird, schon lokal durch | ||||||
|  | die Shell expandiert. An dieser Stelle erscheint also auf dem entfernten System | ||||||
|  | der Name des aktuellen Verzeichnisses auf dem lokalen System. | ||||||
|  |  | ||||||
|  |  | ||||||
| \section{Binaries inside} | \section{Binaries inside} | ||||||
|  |  | ||||||
| TODO!!! | Software wird meistens in Form von Paketen verteilt. Entweder handelt es sich | ||||||
|  | dabei um auf das Betriebssystem abgestimmte Installationspakete (rpm, deb, pkg | ||||||
|  | usw.), gepackte Archive (zip, tgz) oder Installationsprogramme. Unter | ||||||
|  | Unix-Systemen bietet sich f<>r letztere die Shell als Tr<54>gersystem an. | ||||||
|  | Shell-Skripte sind mit wenigen Einschr<68>nkungen plattformunabh<62>ngig, sie k<>nnen | ||||||
|  | also ohne vorherige Installations- oder Compilier-Arbeiten gestartet werden und | ||||||
|  | die Umgebung f<>r das zu installierende Programm testen und / oder vorbereiten. | ||||||
|  |  | ||||||
|  | Abgesehen davon k<>nnen Skripte mit den hier vorgestellten Techniken auch andere | ||||||
|  | Daten, z. B. Bilder oder T<>ne, enthalten. | ||||||
|  |  | ||||||
|  | Doch wie werden die~--~<7E>blicherweise bin<69>ren~--~Pakete auf das Zielsystem | ||||||
|  | gebracht? | ||||||
|  |  | ||||||
|  | Im Prinzip gibt es daf<61>r zwei unterschiedliche Verfahren: | ||||||
|  |  | ||||||
| \subsection{Bin<EFBFBD>re Here-Dokumente} | \subsection{Bin<EFBFBD>re Here-Dokumente} | ||||||
|  | \index{Here-Dokument} | ||||||
|  |  | ||||||
| TODO!!! | Eine M<>glichkeit ist es, die bin<69>re Datei in Form eines Here-Dokuments | ||||||
|  | mitzuliefern. Da es aber in der Natur einer bin<69>ren Datei liegt nicht-druckbare | ||||||
|  | Zeichen zu enthalten, kann die Datei mit Hilfe des Tools \texttt{uuencode} | ||||||
|  | vorbereitet werden. Das Tool codiert Eingabedateien so, da<64> sie nur noch | ||||||
|  | einfache Textzeichen enthalten. | ||||||
|  |  | ||||||
|  | Sehen wir uns das folgende einfache Beispiel an. Es ist etwas wild konstruiert | ||||||
|  | und nicht sehr sinnvoll, aber es zeigt das Prinzip. | ||||||
|  |  | ||||||
|  | \begin{lstlisting} | ||||||
|  | #!/bin/sh | ||||||
|  |  | ||||||
|  | echo "Das Bild wird ausgepackt..." | ||||||
|  |  | ||||||
|  | uudecode << 'EOF' | ||||||
|  | begin 644 icon.png | ||||||
|  | MB5!.1PT*&@H````-24A$4@```!8````6"`8```#$M&P[````"7!(67,```L3 | ||||||
|  | M```+$P$`FIP8````!&=!34$``+&.?/M1DP```"!C2%)-``!Z)0``@(,``/G_ | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Nach einem Hinweis wird also das Here-Dokument als Eingabe f<>r das Tool | ||||||
|  | \texttt{uudecode} benutzt. Erstellt wurde das Dokument mit einer Zeile der | ||||||
|  | folgenden Form: | ||||||
|  |  | ||||||
|  | \lstinline|uuencode icon.png icon.png| | ||||||
|  |  | ||||||
|  | Wie man sieht ist der Name der Datei in dem Here-Dokument enthalten. Die Datei | ||||||
|  | wird entpackt und unter diesem gespeichert. In der `realen Welt' mu<6D> an der | ||||||
|  | Stelle auf jeden Fall sichergestellt werden, da<64> keine existierenden Dateien | ||||||
|  | versehentlich <20>berschrieben werden. | ||||||
|  |  | ||||||
|  | Um diesen Abschnitt nicht allzu lang werden zu lassen <20>berspringen wir einen | ||||||
|  | Teil der Datei. | ||||||
|  |  | ||||||
|  | \begin{lstlisting}[firstnumber=38] | ||||||
|  | M#-""F4%,@%4.GUZ``"(*`6VW6!S#\>C_?/;__Q<R_S]<P/F7AXDA'I\>@``B | ||||||
|  | K!>E;2S-,]5!A7`,,U'0@GQ6?8H```P`#@&?)O'P'L0````!)14Y$KD)@@@`` | ||||||
|  | ` | ||||||
|  | end | ||||||
|  | EOF | ||||||
|  |  | ||||||
|  | if [ $? -ne 0 ]; then | ||||||
|  |   echo "Fehler beim Auspacken der Datei" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | display icon.png | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Nach dem Entpacken wird noch der Exit-Code von \texttt{uudecode} <20>berpr<70>ft und | ||||||
|  | im Fehlerfall eine Ausgabe gemacht. Im Erfolgsfall wird das Bild mittels | ||||||
|  | \texttt{display} angezeigt. | ||||||
|  |  | ||||||
| \subsection{Schwanz ab!} | \subsection{Schwanz ab!} | ||||||
|  |  | ||||||
| TODO!!! | Diese Variante basiert darauf, da<64> die bin<69>re Datei ohne weitere Codierung an | ||||||
|  | das Shell-Skript angeh<65>ngt wurde. Nachteil dieses Verfahrens ist, da<64> das | ||||||
|  | `abschneidende Kommando' nach jeder <20>nderung der L<>nge des Skriptes angepa<70>t | ||||||
|  | werden mu<6D>. | ||||||
|  |  | ||||||
| \section{Dateien, die es nicht gibt} | Dabei gibt es zwei Methoden, die angeh<65>ngte Datei wieder abzuschneiden. Die | ||||||
|  | einfachere Methode funktioniert mit \texttt{tail}: | ||||||
|  |  | ||||||
| TODO!!! | \lstinline|tail -n +227 $0 > icon.png| | ||||||
|  |  | ||||||
| \subsection{Speichern in nicht existente Dateien} | Dieses Beispiel geht davon aus, da<64> das Skript selbst 227 Zeilen umfa<66>t. Die | ||||||
|  | bin<EFBFBD>re Datei wurde mit einem Kommando wie \lstinline|cat icon.png >> skript.sh| | ||||||
|  | an das Skript angeh<65>ngt. | ||||||
|  |  | ||||||
| TODO!!! | F<EFBFBD>r die etwas kompliziertere Variante mu<6D> die L<>nge des eigentlichen | ||||||
|  | Skript-Teiles genau angepa<70>t werden. Wenn das Skript beispielsweise etwa 5,5kB | ||||||
|  | lang ist, m<>ssen genau passend viele Leerzeilen oder Kommentarzeichen angeh<65>ngt | ||||||
|  | werden, damit sich eine L<>nge von 6kB ergibt. Dann kann das Anh<6E>ngsel mit dem | ||||||
|  | Kommando \texttt{dd} in der folgenden Form abgeschnitten werden: | ||||||
|  |  | ||||||
| \subsection{Daten aus einer Subshell hochreichen} | \lstinline|dd bs=1024 if=$0 of=icon.png skip=6| | ||||||
|  |  | ||||||
|  | Das Kommando kopiert Daten aus einer Eingabe- in eine Ausgabedatei. Im | ||||||
|  | einzelnen wird hier eine Blockgr<67><72>e (blocksize, bs) von 1024 Bytes festgelegt. | ||||||
|  | Dann werden Eingabe- und Ausgabedatei benannt, dabei wird als Eingabedatei | ||||||
|  | \texttt{\$0} und somit der Name des laufenden Skriptes benutzt. Schlie<69>lich | ||||||
|  | wird festgelegt, da<64> bei der Aktion die ersten sechs Block~--~also die ersten | ||||||
|  | sechs Kilobytes~--~<7E>bersprungen werden sollen. | ||||||
|  |  | ||||||
|  | Um es nochmal zu betonen: Diese beiden Methoden sind mit Vorsicht zu genie<69>en. | ||||||
|  | Bei der ersten f<>hrt jede zus<75>tzliche oder gel<65>schte Zeile zu einer kaputten | ||||||
|  | Ausgabedatei, bei der zweiten reichen schon einzelne Zeichen. In jedem Fall | ||||||
|  | sollte nach dem Auspacken noch einmal mittels \texttt{sum} oder \texttt{md5sum} | ||||||
|  | eine Checksumme gezogen und verglichen werden. | ||||||
|  |  | ||||||
|  | \section{Dateien, die es nicht gibt}\label{dateien_die_es_nicht_gibt} | ||||||
|  |  | ||||||
|  | Eine Eigenart der Behandlung von Dateien unter Unix besteht im Verhalten beim | ||||||
|  | L<EFBFBD>schen. Gel<65>scht wird n<>mlich zun<75>chst nur der Verzeichniseintrag. Der Inode, | ||||||
|  | also die Markierung im Dateisystem unter der die Datei gefunden werden kann, | ||||||
|  | besteht weiterhin. Er wird erst dann freigegeben, wenn er nicht mehr | ||||||
|  | referenziert wird. Physikalisch besteht die Datei also noch, sie wird lediglich | ||||||
|  | im Verzeichnis nicht mehr angezeigt. | ||||||
|  |  | ||||||
|  | Hat ein Proze<7A> die Datei noch in irgendeiner Form ge<67>ffnet, kann er weiter | ||||||
|  | darauf zugreifen. Erst wenn er die Datei schlie<69>t ist sie tats<74>chlich und | ||||||
|  | unwiederbringlich `weg'. | ||||||
|  |  | ||||||
|  | Dieser Effekt der `nicht existenten Dateien' l<><6C>t sich an verschiedenen Stellen | ||||||
|  | geschickt einsetzen. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | \subsection{Daten aus einer Subshell hochreichen}\label{daten_hochreichen} | ||||||
|  |  | ||||||
|  | Ein immer wieder auftretendes und oft sehr verwirrendes Problem ist, da<64> | ||||||
|  | Variablen die in einer Subshell definiert wurden au<61>erhalb dieser nicht | ||||||
|  | sichtbar sind (siehe Abschnitt \ref{subshellschleifen}). Dies ist um so | ||||||
|  | <EFBFBD>rgerlicher, als da<64> Subshells auch bei vergleichsweise einfachen Pipelines | ||||||
|  | ge<EFBFBD>ffnet werden. | ||||||
|  |  | ||||||
|  | Ein Beispiel f<>r ein mi<6D>lingendes Skriptfragment w<>re das folgende: | ||||||
|  |  | ||||||
|  | \begin{lstlisting} | ||||||
|  | nCounter=0 | ||||||
|  | cat datei.txt | while read VAR; do | ||||||
|  |   nCounter=`expr $nCounter + 1` | ||||||
|  | done | ||||||
|  | echo "nCounter=$nCounter" | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Die Variable nCounter wird mit 0 initialisiert. Dann wird eine Datei per Pipe | ||||||
|  | in eine \texttt{while}-Schleife geleitet. Innerhalb der Schleife wird f<>r jede | ||||||
|  | eingehende Zeile die Variable hochgez<65>hlt. Am Ende der Schleife enth<74>lt die | ||||||
|  | Variable tats<74>chlich den korrekten Wert, aber da die Pipe eine Subshell | ||||||
|  | ge<EFBFBD>ffnet hat ist der Wert nach Beendigung der Schleife nicht mehr sichtbar. Das | ||||||
|  | \texttt{echo}-Kommando gibt die Zahl 0 aus. | ||||||
|  |  | ||||||
|  | Es gibt mehrere Ans<6E>tze, diesem Problem zu begegnen. Am einfachsten w<>re es in | ||||||
|  | diesem Fall, dem Rat aus Abschnitt \ref{subshellschleifen} zu folgen und die | ||||||
|  | Subshell geschickt zu vermeiden. Doch das ist leider nicht immer m<>glich. Wie | ||||||
|  | geht man in solchen F<>llen vor? | ||||||
|  |  | ||||||
|  | Bei einfachen Zahlenwerten k<>nnte beispielsweise ein R<>ckgabewert helfen. | ||||||
|  | Komplexere Informationen k<>nnen in eine tempor<6F>re Datei geschrieben werden, die | ||||||
|  | danach geparst werden m<><6D>te. Wenn die Informationen in Zeilen der Form | ||||||
|  | \lstinline|VARIABLE="Wert"| gespeichert werden, kann die Datei einfach mittels | ||||||
|  | \texttt{source} (Abschnitt \ref{source}) oder einem Konstrukt der folgenden Art | ||||||
|  | gelesen werden: | ||||||
|  |  | ||||||
|  | \lstinline|eval `cat tempfile`| | ||||||
|  |  | ||||||
|  | Und genau mit dieser <20>berlegung kommen wir zu einem eleganten~--~wenn auch | ||||||
|  | nicht ganz einfachen~--~Trick. | ||||||
|  |  | ||||||
|  | Anstatt die Daten in eine tempor<6F>re Datei zu schreiben, wo sie wom<6F>glich durch | ||||||
|  | andere Prozesse ver<65>ndert oder ausgelesen werden k<>nnten, kann man sie auch in | ||||||
|  | `nicht existente' Dateien schreiben. Das folgende Beispiel demonstriert das | ||||||
|  | Verfahren: | ||||||
|  |  | ||||||
|  | \begin{lstlisting} | ||||||
|  | #!/bin/sh -x | ||||||
|  | TMPNAME="/tmp/`date '+%Y%m%d%H%M%S'`$$.txt" | ||||||
|  | exec 3> "$TMPNAME" | ||||||
|  | exec 4< "$TMPNAME" | ||||||
|  | rm -f "$TMPNAME" | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Bis hierher wurde zun<75>chst eine tempor<6F>re Datei angelegt. Die Filehandles 3 und | ||||||
|  | 4 wurden zum Schreiben bzw. Lesen mit dieser Datei verbunden. Daraufhin wurde | ||||||
|  | die Datei entfernt. Die Filehandles verweisen weiterhin auf die Datei, obwohl | ||||||
|  | sie im Dateisystem nicht mehr sichtbar ist. | ||||||
|  |  | ||||||
|  | Kommen wir zum n<>tzlichen Teil des Skriptes: | ||||||
|  |  | ||||||
|  | \begin{lstlisting}[firstnumber=6] | ||||||
|  | nCounter=0 | ||||||
|  | cat datei.txt | ( while read VAR; do | ||||||
|  |   while read VAR; do | ||||||
|  |     nCounter=`expr $nCounter + 1` | ||||||
|  |   done | ||||||
|  |   echo "nCounter=$nCounter" | ||||||
|  | ) >&3 | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Hier wurde wieder die Variable nCounter initialisiert und in der Subshell die | ||||||
|  | Zeilen gez<65>hlt wie im ersten Beispiel. Allerdings wurde explizit eine Subshell | ||||||
|  | um die Schleife gestartet. Dadurch steht die in der Schleife hochgez<65>hlte | ||||||
|  | Variable auch nach Beendigung der Schleife zur Verf<72>gung, allerdings immernoch | ||||||
|  | nur in der Subshell. Um das zu <20>ndern, wird in Zeile 11 der Wert ausgegeben. | ||||||
|  | Die Ausgaben der Subshell werden in den oben erstellen Deskriptor umgeleitet. | ||||||
|  |  | ||||||
|  | \begin{lstlisting}[firstnumber=13] | ||||||
|  | echo "(vor eval)  nCounter=$nCounter" | ||||||
|  | eval `cat <&4` | ||||||
|  | echo "(nach eval) nCounter=$nCounter" | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Das \texttt{echo}-Kommando in Zeile 13 beweist, da<64> der Wert von nCounter | ||||||
|  | tats<EFBFBD>chlich au<61>erhalb der Subshell nicht zur Verf<72>gung steht. Zun<75>chst. | ||||||
|  |  | ||||||
|  | In Zeile 14 wird dann die ebenfalls oben schon angesprochene | ||||||
|  | \texttt{eval}-Zeile benutzt, um die Informationen aus dem Filedeskriptor zu | ||||||
|  | lesen, die die Schleife dort hinterlassen hat. | ||||||
|  |  | ||||||
|  | Abschlie<EFBFBD>end zeigt die Zeile 15, da<64> der Transport tats<74>chlich funktioniert | ||||||
|  | hat, die Variable nCounter ist mit dem Wert aus der Subshell belegt. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | \subsection{Dateien gleichzeitig lesen und schreiben}\label{lesen_und_schreiben} | ||||||
|  |  | ||||||
|  | Es kommt vor, da<64> man eine Datei bearbeiten m<>chte, die hinterher aber wieder | ||||||
|  | unter dem gleichen Namen zur Verf<72>gung stehen soll. Beispielsweise sollen alle | ||||||
|  | Zeilen aus einer Datei entfernt werden, die nicht das Wort \textit{wichtig} | ||||||
|  | enthalten. | ||||||
|  |  | ||||||
|  | Der erste Versuch an der Stelle wird etwas in der Form | ||||||
|  |  | ||||||
|  | \lstinline|grep wichtig datei.txt > datei.txt| | ||||||
|  |  | ||||||
|  | sein. Das kann funktionieren, es kann aber auch in die sprichw<68>rtliche Hose | ||||||
|  | gehen. Das Problem an der Stelle ist, da<64> die Datei an der Stelle gleichzeitig | ||||||
|  | zum Lesen und zum Schreiben ge<67>ffnet wird. Das Ergebnis ist undefiniert. | ||||||
|  |  | ||||||
|  | Eine Elegante L<>sung besteht darin, einen Filedeskriptor auf die Quelldatei zu | ||||||
|  | legen und diese dann zu l<>schen. Die Datei wird erst dann wirklich aus dem | ||||||
|  | Dateisystem entfernt, wenn kein Deskriptor mehr auf sie zeigt. Dann kann aus | ||||||
|  | dem gerade angelegten Deskriptor gelesen werden, w<>hrend eine neue Datei unter | ||||||
|  | dem alten Namen angelegt wird: | ||||||
|  |  | ||||||
|  | \begin{lstlisting} | ||||||
|  | #!/bin/sh | ||||||
|  | FILE=datei.txt | ||||||
|  | exec 3< "$FILE" | ||||||
|  | rm "$FILE" | ||||||
|  | grep "wichtig" <&3 > "$FILE" | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Allerdings sollte man bei dieser Methode beachten, da<64> man im Falle eines | ||||||
|  | Fehlers die Quelldaten verliert, da die Datei ja bereits gel<65>scht wurde. | ||||||
|  |  | ||||||
|  | \section{Auf der Lauer: Wachhunde}\label{wachhunde}\index{Watchdog} | ||||||
|  |  | ||||||
|  | Es kommt vor, da<64> man einen Proze<7A> startet, bei dem man sich nicht sicher sein | ||||||
|  | kann da<64> er sich auch in absehbarer Zeit wieder beendet. Beispielsweise kann | ||||||
|  | der Timeout f<>r einen Netzwerkzugriff deutlich h<>her liegen als erw<72>nscht, und | ||||||
|  | wenn der `gegnerische' Dienst nicht antwortet bleibt einem nur zu warten. | ||||||
|  |  | ||||||
|  | Es sei denn, man legt einen geeigneten Wachhund\footnote{Der englische Begriff | ||||||
|  | `Watchdog' ist in diesem Zusammenhang wahrscheinlich gel<65>ufiger...} auf die | ||||||
|  | Lauer, der im Notfall rettend eingreift. In einem Shell-Skript k<>nnte das wie | ||||||
|  | folgt aussehen: | ||||||
|  |  | ||||||
|  | \begin{lstlisting} | ||||||
|  | #!/bin/sh | ||||||
|  | timeout=5 | ||||||
|  | ping 192.168.0.254 & | ||||||
|  | cmdpid=$! | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Bis hierher nichts aufregendes. Eine Variable wird mit dem Timeout belegt, also | ||||||
|  | mit der Anzahl an Sekunden nach denen der zu <20>berwachende Proze<7A> unterbrochen | ||||||
|  | werden soll. Dann wird der zu <20>berwachende Proze<7A> gestartet und mittels \& in | ||||||
|  | den Hintergrund geschickt. Die Proze<7A>-ID des Prozesses wird in der Variablen | ||||||
|  | cmdpid gesichert. | ||||||
|  |  | ||||||
|  | \begin{lstlisting}[firstnumber=5] | ||||||
|  | (sleep $timeout; kill -9 $cmdpid) & | ||||||
|  | watchdogpid=$! | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | In Zeile 5 findet sich der eigentliche Watchdog. Hier wird eine Subshell | ||||||
|  | gestartet, in der zun<75>chst der oben eingestellte Timeout abgewartet und dann | ||||||
|  | der zu <20>berwachende Proze<7A> get<65>tet wird. Diese Subshell wird ebenfalls mit \& | ||||||
|  | in den Hintergrund geschickt. Die ID der Subshell wird in der Variablen | ||||||
|  | watchdogpid gesichert. | ||||||
|  |  | ||||||
|  | \begin{lstlisting}[firstnumber=7] | ||||||
|  | wait $cmdpid | ||||||
|  | kill $watchdogpid > /dev/null 2>&1 | ||||||
|  | exit 0 | ||||||
|  | \end{lstlisting} | ||||||
|  |  | ||||||
|  | Dann wird durch ein \texttt{wait}\index{wait} darauf gewartet, da<64> sich der | ||||||
|  | <EFBFBD>berwachte Proze<7A> beendet. Dabei w<>rde \texttt{wait} bis in alle Ewigkeit | ||||||
|  | warten, w<>re da nicht der Watchdog in der Subshell. Wenn dem die Ausf<73>hrung zu | ||||||
|  | lange dauert, sorgt er daf<61>r da<64> der Proze<7A> beendet wird. | ||||||
|  |  | ||||||
|  | Kommt der <20>berwachte Proze<7A> aber rechtzeitig zur<75>ck, sorgt \texttt{kill} in | ||||||
|  | Zeile 8 daf<61>r da<64> der Wachhund `eingeschl<68>fert' wird. | ||||||
|  |  | ||||||
|  | Auf diese Weise ist sichergestellt, da<64> der \texttt{ping} auf keinen Fall | ||||||
|  | l<EFBFBD>nger als f<>nf Sekunden l<>uft. | ||||||
|  |  | ||||||
| TODO!!! |  | ||||||
|   | |||||||
							
								
								
									
										229
									
								
								shell.tex
									
									
									
									
									
								
							
							
						
						
									
										229
									
								
								shell.tex
									
									
									
									
									
								
							| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
| %============================================================================== | %============================================================================== | ||||||
| % LaTeX-Schema-Datei schema.tex | % LaTeX-Schema-Datei schema.tex | ||||||
| %============================================================================== | %============================================================================== | ||||||
| @@ -6,50 +7,38 @@ | |||||||
| % Vorspann | % 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 |                                        % 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 | ||||||
|  |   halfparskip,                         % Abst<73>nde zwischen den Abs<62>tzen, statt | ||||||
|  |                                        % Einr<6E>ckung der ersten Zeile | ||||||
|  | %  draft,                               % Entwurfsmodus | ||||||
|  |   final,                               % Release-Modus | ||||||
|  |   twoside                              % Doppelseitig, f<>r Buch | ||||||
|  | ]{scrbook} | ||||||
|  |  | ||||||
| \usepackage{german}                    % deutsches Paket f<>r Umlaute | \usepackage{german}                    % deutsches Paket f<>r Umlaute | ||||||
| %\usepackage{t1enc}                     % DC-Font mit 8 Bit verwenden |  | ||||||
| \usepackage[latin1]{inputenc}          % Codepage latin1 | \usepackage[latin1]{inputenc}          % Codepage latin1 | ||||||
|  |  | ||||||
| %\usepackage{graphicx}                  % Grafikpaket f<>r Bilder laden | \usepackage{mathptmx}                  % Andere Schriften benutzen | ||||||
|  | \usepackage[scaled=.90]{helvet} | ||||||
|  | \usepackage{courier} | ||||||
|  | \usepackage{pifont}                    % f<>r dinglist (Icon neben Text) | ||||||
|  |  | ||||||
|  | %\usepackage[dvips]{graphicx}           % Grafikpaket f<>r Bilder laden | ||||||
|  | %\usepackage{epstopdf}                  % .eps bei Bedarf nach .pdf wandeln | ||||||
| %\DeclareGraphicsRule{.tif}{bmp}{}{}    % Grafikformate | %\DeclareGraphicsRule{.tif}{bmp}{}{}    % Grafikformate | ||||||
|  |  | ||||||
| \usepackage{tabularx}                  % f<>r Tabellen <20>ber die Seitenbreite |  | ||||||
| \usepackage{longtable}                 % f<>r Tabellen <20>ber die Seitenbreite |  | ||||||
| \usepackage{supertabular}              % f<>r Tabellen <20>ber die Seitenbreite |  | ||||||
| \usepackage{ltxtable}                  % f<>r Tabellen <20>ber die Seitenbreite |  | ||||||
|  |  | ||||||
| \ifpdf                                 % PDF-Einstellungen | %\usepackage{tabularx}                  % f<>r Tabellen <20>ber die Seitenbreite | ||||||
|   \usepackage{thumbpdf} | %\usepackage{longtable}                 % f<>r Tabellen <20>ber die Seitenbreite | ||||||
| \else                                  % Nicht-PDF-Einstellungen | %\usepackage{supertabular}              % f<>r Tabellen <20>ber die Seitenbreite | ||||||
| \fi | \usepackage{ltxtable}                  % f<>r Tabellen <20>ber die Seitenbreite | ||||||
|  |  | ||||||
| \usepackage{makeidx}                   % Index wird sp<73>ter eingef<65>gt | \usepackage{makeidx}                   % Index wird sp<73>ter eingef<65>gt | ||||||
| \makeindex                             % durch \printindex | \makeindex                             % durch \printindex | ||||||
| @@ -58,23 +47,39 @@ | |||||||
|  |  | ||||||
| \usepackage{fancybox}                  % K<>stchen f<>r Tastendarstellung | \usepackage{fancybox}                  % K<>stchen f<>r Tastendarstellung | ||||||
|  |  | ||||||
| \usepackage{fancyhdr}                  % Kopf- und Fu<46>zeilen | %\usepackage{moreverb}                  % F<EFBFBD>r Listings | ||||||
| \pagestyle{fancy} | \usepackage{listings}                  % F<>r Listings | ||||||
| \renewcommand{\chaptermark}[1]{\markboth{#1}{}} | \lstset{ | ||||||
| \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} |         extendedchars=true, | ||||||
| \fancyhf{} |         backgroundcolor=\color[gray]{0.95}, | ||||||
| \fancyhead[RE]{\bfseries\leftmark} |         basicstyle=\ttfamily\footnotesize, | ||||||
| \fancyhead[LO]{\bfseries\rightmark} |         numbers=left, | ||||||
| \fancyhead[RO,LE]{\bfseries\thepage} |         numberstyle=\scriptsize, | ||||||
| \renewcommand{\headrulewidth}{0.5pt} |         stepnumber=2, | ||||||
| \addtolength{\headheight}{2.5pt} |         numbersep=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, | ||||||
|  |   urlcolor = 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 | \newcommand{\STRUT}{\rule{0in}{3ex}}   % Ein vertikaler Abstand f<>r Tabellen | ||||||
|  |  | ||||||
| @@ -87,12 +92,13 @@ | |||||||
|  |  | ||||||
| \begin{document}                       % hiermit mu<6D> jedes Dokument beginnen | \begin{document}                       % hiermit mu<6D> jedes Dokument beginnen | ||||||
|  |  | ||||||
| \vspace*{.75in}                        % Die Titelseite | \vspace*{.6in}                         % Die Titelseite | ||||||
| \thispagestyle{empty} | \thispagestyle{empty} | ||||||
| \begin{centering} | \begin{centering} | ||||||
|   \rule{5in}{.04in}\\                                 \vspace{.25in} |   \rule{5in}{.04in}\\                                 \vspace{.25in} | ||||||
|   \Huge {\bf SHELL\\ \vspace{.4in} PROGRAMMIERUNG}\\  \vspace{.1in} |   \Huge {\bf SHELL\\ \vspace{.4in} PROGRAMMIERUNG}\\  \vspace{.1in} | ||||||
|   \rule{5in}{.04in}\\                                 \vspace{.5in} |   \rule{5in}{.04in}\\                                 \vspace{.6in} | ||||||
|  |   \large v2.0.0\\ | ||||||
|   \large \today\\                                     \vspace{.75in} |   \large \today\\                                     \vspace{.75in} | ||||||
|   \large von\\                                        \vspace{.3in} |   \large von\\                                        \vspace{.3in} | ||||||
|   \LARGE {\bf Ronald Schaten} \\                      \vspace{.6in} |   \LARGE {\bf Ronald Schaten} \\                      \vspace{.6in} | ||||||
| @@ -102,41 +108,127 @@ | |||||||
| \newpage | \newpage | ||||||
| \thispagestyle{empty}                  % eine Leerseite | \thispagestyle{empty}                  % eine Leerseite | ||||||
| ~\vfill | ~\vfill | ||||||
|  |  | ||||||
|  | % Syntax-Boxen (sybox) definieren: | ||||||
|  | \fboxsep 1.36mm | ||||||
|  | \definecolor{g1}{gray}{0.95} | ||||||
|  | \newsavebox{\syntaxbox} | ||||||
|  | \newenvironment{sybox} | ||||||
|  | {\begin{lrbox}{\syntaxbox} | ||||||
|  | \begin{minipage}{\textwidth}} | ||||||
|  | {\end{minipage} | ||||||
|  | \end{lrbox} | ||||||
|  | {\fcolorbox{g1}{g1} | ||||||
|  | {\parbox{\textwidth}{\usebox{\syntaxbox}\hfill\hbox{}}}}} | ||||||
|  |  | ||||||
|  |  | ||||||
| \footnotesize | \footnotesize | ||||||
| Copyright \copyright{} 2001 Ronald Schaten (\texttt{ronald@schatenseite.de})\bigskip | Die aktuellste Version dieses Dokumentes befindet sich auf | ||||||
|  | \href{http://www.schatenseite.de/}{http://www.schatenseite.de/}. | ||||||
|  |  | ||||||
| Die aktuellste Version dieses Dokumentes befindet sich im World Wide Web auf meiner Homepage (\texttt{http://www.schatenseite.de/}).\bigskip | Dieses Dokument ist entstanden, weil ich f<>r mich selbst eine kompakte | ||||||
|  | <EFBFBD>bersicht zu diesem Thema haben wollte. Ich beabsichtige nicht, damit in | ||||||
|  | irgendeiner Form Kommerz zu machen. Ich stelle es zur Verf<72>gung, in der | ||||||
|  | Hoffnung, da<64> andere Leute daraus vielleicht einen Nutzen ziehen k<>nnen. | ||||||
|  | \textbf{Aber ich <20>bernehme keine Garantie f<>r die Korrektheit der hier | ||||||
|  | dargestellten Dinge.} | ||||||
|  |  | ||||||
| Dieses Dokument ist entstanden, weil ich f<>r mich selbst eine kompakte <20>bersicht zu diesem Thema haben wollte. Ich beabsichtige nicht, damit in irgendeiner Form Kommerz zu machen. Ich stelle es frei zur Verf<72>gung, in der Hoffnung, da<64> andere Leute daraus vielleicht einen Nutzen ziehen k<>nnen. \textbf{Aber ich <20>bernehme keine Garantie f<>r die Korrektheit der hier dargestellten Dinge.} Mit der Formulierung \textsl{'daraus vielleicht einen Nutzen ziehen k<>nnen'} meine ich nicht, da<64> dieses Dokument~---~oder Teile daraus~---~verkauft werden darf. \textbf{Dieses Dokument darf nur kostenlos weitergegeben werden.}\bigskip | Copyright \copyright{} 2000-2005 Ronald Schaten (ronald@schatenseite.de) | ||||||
|  |  | ||||||
| Ich danke folgenden Personen, die mir bei der Durchsicht behilflich waren und durch ihre konstruktive Kritik zu Verbesserungen beigetragen haben (in chronologischer Reihenfolge ihres Eingreifens): | \textbf{Dieses Dokument steht unter der Creative Commons Lizenz.} Die | ||||||
|  | Weiterverbreitung ist unter gewissen Bedingungen (Namensnennung, keine | ||||||
|  | kommerzielle Nutzung und keine Bearbeitung) erlaubt und gew<65>nscht. Ich habe | ||||||
|  | diese Lizenz gew<65>hlt um sicherzustellen da<64> Verbesserungen am Inhalt des | ||||||
|  | Dokumentes bei mir ankommen, damit ich sie in die `Hauptversion' einflie<69>en | ||||||
|  | lassen kann. | ||||||
|  |  | ||||||
|  | Die Lizenzbedingungen stehen unter | ||||||
|  | \href{http://creativecommons.org/licenses/by-nc-nd/2.0/de/}{http://creativecommons.org/licenses/by-nc-nd/2.0/de/}. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % <!-- Creative Commons-Lizenzvertrag --> | ||||||
|  | % <a rel="license" | ||||||
|  | % href="http://creativecommons.org/licenses/by-nc-nd/2.0/de/"><img alt="Creative | ||||||
|  | % Commons-Lizenzvertrag" border="0" | ||||||
|  | % src="http://creativecommons.org/images/public/somerights20.gif" /></a><br /> | ||||||
|  | % Diese Inhalt ist unter einer <a rel="license" | ||||||
|  | % href="http://creativecommons.org/licenses/by-nc-nd/2.0/de/">Creative | ||||||
|  | % Commons-Lizenz</a> lizenziert. | ||||||
|  | % <!-- /Creative Commons-Lizenzvertrag --> | ||||||
|  | % | ||||||
|  | % | ||||||
|  | % <!-- | ||||||
|  | % | ||||||
|  | % <rdf:RDF xmlns="http://web.resource.org/cc/" | ||||||
|  | %    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  | %    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> | ||||||
|  | % <Work rdf:about=""> | ||||||
|  | %   <dc:title>Shell&#45;Programmierung</dc:title> | ||||||
|  | %   <dc:date>2005</dc:date> | ||||||
|  | %   <dc:description>Einf<6E>hrung in die | ||||||
|  | % Shell&#45;Programmierung</dc:description> | ||||||
|  | %   <dc:creator><Agent> | ||||||
|  | %     <dc:title>Ronald Schaten</dc:title> | ||||||
|  | %   </Agent></dc:creator> | ||||||
|  | %   <dc:rights><Agent> | ||||||
|  | %     <dc:title>Ronald Schaten</dc:title> | ||||||
|  | %   </Agent></dc:rights> | ||||||
|  | %   <dc:type rdf:resource="http://purl.org/dc/dcmitype/Text" /> | ||||||
|  | %   <license rdf:resource="http://creativecommons.org/licenses/by-nc-nd/2.0/de/" | ||||||
|  | % /> | ||||||
|  | % </Work> | ||||||
|  | % | ||||||
|  | % <License rdf:about="http://creativecommons.org/licenses/by-nc-nd/2.0/de/"> | ||||||
|  | %   <permits rdf:resource="http://web.resource.org/cc/Reproduction" /> | ||||||
|  | %   <permits rdf:resource="http://web.resource.org/cc/Distribution" /> | ||||||
|  | %   <requires rdf:resource="http://web.resource.org/cc/Notice" /> | ||||||
|  | %   <requires rdf:resource="http://web.resource.org/cc/Attribution" /> | ||||||
|  | %   <prohibits rdf:resource="http://web.resource.org/cc/CommercialUse" /> | ||||||
|  | % </License> | ||||||
|  | % | ||||||
|  | % </rdf:RDF> | ||||||
|  | % | ||||||
|  | % --> | ||||||
|  |  | ||||||
|  | Ich danke folgenden Personen, die mir bei der Durchsicht behilflich waren und | ||||||
|  | durch ihre konstruktive Kritik zu Verbesserungen beigetragen haben (in | ||||||
|  | chronologischer Reihenfolge ihres Eingreifens): | ||||||
|  |  | ||||||
| \begin{list}{$\bullet$}{\itemsep=-0.5cm} | \begin{list}{$\bullet$}{\itemsep=-0.5cm} | ||||||
| \item J<>rgen Ilse (\texttt{ilse@asys-h.de})\\ | \item J<>rgen Ilse (ilse@asys-h.de)\\ | ||||||
| \item Christian Perle (\texttt{christian.perle@tu-clausthal.de})\\ | \item Christian Perle (christian.perle@tu-clausthal.de)\\ | ||||||
| \item Andreas Metzler (\texttt{ametzler@downhill.at.eu.org})\\ | \item Andreas Metzler (ametzler@downhill.at.eu.org)\\ | ||||||
| \item Johannes Kolb (\texttt{johannes.kolb@web.de})\\ | \item Johannes Kolb (johannes.kolb@web.de)\\ | ||||||
|  | \item Falk Friedrich (falk@gmx.de)\\ | ||||||
|  | \item Kai Th<54>ne (kai.thoene@gmx.de)\\ | ||||||
| \end{list} | \end{list} | ||||||
|  |  | ||||||
| Und ich bitte alle Leser, auf eventuelle Fehler zu achten und mich darauf aufmerksam zu machen. Auch abgesehen davon freue ich mich <20>ber jede R<>ckmeldung. | Und ich bitte alle Leser, auf eventuelle Fehler zu achten und mich darauf | ||||||
|  | aufmerksam zu machen. Auch abgesehen davon freue ich mich <20>ber jede | ||||||
|  | R<EFBFBD>ckmeldung. | ||||||
|  |  | ||||||
|  | Dieses Dokument entstand unter Verwendung von Linux, vim und \LaTeX. Dank an | ||||||
|  | deren Entwickler. | ||||||
|  |  | ||||||
| \normalsize | \normalsize | ||||||
| \newpage | \newpage | ||||||
| \pagenumbering{roman} | \pagenumbering{roman} | ||||||
| \renewcommand{\headrulewidth}{0.5pt} | %\renewcommand{\headrulewidth}{0.5pt} | ||||||
| \setcounter{tocdepth}{3} | \setcounter{tocdepth}{3} | ||||||
| \tableofcontents | \tableofcontents | ||||||
| \newpage | \newpage | ||||||
| \pagenumbering{arabic} | \pagenumbering{arabic} | ||||||
|                                        % Haupttextteil |                                        % Haupttextteil | ||||||
| \include{was_ist_die_shell} | \include{was_ist_die_shell} | ||||||
|  | \include{wo_sind_unterschiede_zu_dos_batchdateien} | ||||||
| \include{wofuer_shell_programmierung} | \include{wofuer_shell_programmierung} | ||||||
| \include{wie_sieht_ein_shell_skript_aus} | \include{wie_sieht_ein_shell_skript_aus} | ||||||
| \include{nuetzliche_shell-kommandos} | \include{werkzeugkasten} | ||||||
| \include{wo_sind_unterschiede_zu_dos_batchdateien} |  | ||||||
| \appendix | \appendix | ||||||
| \include{beispiele} | \include{beispiele} | ||||||
| \include{schmutzige_tricks} | \include{schmutzige_tricks} | ||||||
| \include{quellen} | \include{quellen} | ||||||
|  | \include{todo} | ||||||
|  |  | ||||||
| \printindex                            % Index einf<6E>gen | \printindex                            % Index einf<6E>gen | ||||||
|  |  | ||||||
| @@ -146,11 +238,6 @@ Und ich bitte alle Leser, auf eventuelle Fehler zu achten und mich darauf aufmer | |||||||
|  |  | ||||||
| \end{document} | \end{document} | ||||||
|  |  | ||||||
| \ifpdf                                 % PDF-Einstellungen  |  | ||||||
|   \bye |  | ||||||
| \else                                  % Nicht-PDF-Einstellungen |  | ||||||
| \fi |  | ||||||
|  |  | ||||||
| %============================================================================== | %============================================================================== | ||||||
| % Ende von schema.tex | % Ende von schema.tex | ||||||
| %============================================================================== | %============================================================================== | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
| @@ -10,9 +11,10 @@ | |||||||
| \textsl{Befehl}\texttt{ \&} & Ausf<73>hrung von \textsl{Befehl} im Hintergrund \tabularnewline\STRUT | \textsl{Befehl}\texttt{ \&} & Ausf<73>hrung von \textsl{Befehl} im Hintergrund \tabularnewline\STRUT | ||||||
| \textsl{Befehl1}\texttt{ ; }\textsl{Befehl2} & Befehlsfolge, f<>hrt mehrere Befehle nacheinander aus \tabularnewline\STRUT | \textsl{Befehl1}\texttt{ ; }\textsl{Befehl2} & Befehlsfolge, f<>hrt mehrere Befehle nacheinander aus \tabularnewline\STRUT | ||||||
| \texttt{(}\textsl{Befehl1}\texttt{ ; }\textsl{Befehl2}\texttt{)} & Subshell\index{Subshell}, behandelt \textsl{Befehl1} und \textsl{Befehl2} als Befehlsblock und f<>hrt sie in einer Subshell aus \tabularnewline\STRUT | \texttt{(}\textsl{Befehl1}\texttt{ ; }\textsl{Befehl2}\texttt{)} & Subshell\index{Subshell}, behandelt \textsl{Befehl1} und \textsl{Befehl2} als Befehlsblock und f<>hrt sie in einer Subshell aus \tabularnewline\STRUT | ||||||
| \texttt{\{ }\textsl{Befehl1}\texttt{ ; }\textsl{Befehl2}\texttt{ \}} & Befehlsblock; alle Befehle werden in der momentanen Shell ausgef<65>hrt, aber die Ausgaben werden behandelt, als ob nur ein Befehl ausgef<65>hrt w<>rde \tabularnewline\STRUT | \texttt{\{ }\textsl{Befehl1}\texttt{ ; }\textsl{Befehl2}\texttt{; \}} & Befehlsblock; alle Befehle werden in der momentanen Shell ausgef<65>hrt, aber die Ausgaben werden behandelt, als ob nur ein Befehl ausgef<65>hrt w<>rde \tabularnewline\STRUT | ||||||
| \textsl{Befehl1}\texttt{ | }\textsl{Befehl2} & Pipe\index{Pipe}, verwendet die Ausgabe von \textsl{Befehl1} als Eingabe f<>r \textsl{Befehl2} \tabularnewline\STRUT | \textsl{Befehl1}\texttt{ | }\textsl{Befehl2} & Pipe\index{Pipe}, verwendet die Ausgabe von \textsl{Befehl1} als Eingabe f<>r \textsl{Befehl2} \tabularnewline\STRUT | ||||||
| \textsl{Befehl1}\texttt{ `}\textsl{Befehl2}\texttt{`} & Befehls-Substitution, verwendet die Ausgabe von \textsl{Befehl2} als Argumente\index{Parameter}\index{Argument|see{Parameter}} f<>r \textsl{Befehl1} \tabularnewline\STRUT | \textsl{Befehl1}\texttt{ `}\textsl{Befehl2}\texttt{`} & Befehls-Substitution, verwendet die Ausgabe von \textsl{Befehl2} als Argumente\index{Parameter}\index{Argument|see{Parameter}} f<>r \textsl{Befehl1} \tabularnewline\STRUT | ||||||
|  | \textsl{Befehl1}\texttt{ \$(}\textsl{Befehl2}\texttt{)} & Befehls-Substitution, andere Schreibweise\tabularnewline\STRUT | ||||||
| \textsl{Befehl1}\texttt{ \&\& }\textsl{Befehl2} & AND\index{AND}, f<>hrt zuerst \textsl{Befehl1} und dann (wenn \textsl{Befehl1} erfolgreich war) \textsl{Befehl2} aus\footnote{Einen <20>hnlichen Mechanismus kennt man aus verschiedenen Programmiersprachen unter dem Begriff \textsl{Kurzschlu<EFBFBD>auswertung}\index{Kurzschlu<EFBFBD>auswertung} bzw. \textsl{lazy evaluation}\index{Lazy Evaluation|see{Kurzschlu<EFBFBD>auswertung}}.} \tabularnewline\STRUT | \textsl{Befehl1}\texttt{ \&\& }\textsl{Befehl2} & AND\index{AND}, f<>hrt zuerst \textsl{Befehl1} und dann (wenn \textsl{Befehl1} erfolgreich war) \textsl{Befehl2} aus\footnote{Einen <20>hnlichen Mechanismus kennt man aus verschiedenen Programmiersprachen unter dem Begriff \textsl{Kurzschlu<EFBFBD>auswertung}\index{Kurzschlu<EFBFBD>auswertung} bzw. \textsl{lazy evaluation}\index{Lazy Evaluation|see{Kurzschlu<EFBFBD>auswertung}}.} \tabularnewline\STRUT | ||||||
| \textsl{Befehl1}\texttt{ || }\textsl{Befehl2} & OR\index{OR}, entweder \textsl{Befehl1} ausf<73>hren oder \textsl{Befehl2} (Wenn \textsl{Befehl1} nicht erfolgreich war) | \textsl{Befehl1}\texttt{ || }\textsl{Befehl2} & OR\index{OR}, entweder \textsl{Befehl1} ausf<73>hren oder \textsl{Befehl2} (Wenn \textsl{Befehl1} nicht erfolgreich war) | ||||||
| \end{longtable} | \end{longtable} | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
| @@ -10,7 +11,8 @@ | |||||||
| \texttt{\$ nroff }\textsl{Datei}\texttt{ \&} & Formatiert die \textsl{Datei} im Hintergrund \tabularnewline\STRUT | \texttt{\$ nroff }\textsl{Datei}\texttt{ \&} & Formatiert die \textsl{Datei} im Hintergrund \tabularnewline\STRUT | ||||||
| \texttt{\$ cd; ls} & Sequentieller Ablauf \tabularnewline\STRUT | \texttt{\$ cd; ls} & Sequentieller Ablauf \tabularnewline\STRUT | ||||||
| \texttt{\$ (date; who; pwd) > logfile}\index{!>=\texttt{!>}} & F<>hrt die Befehle in einer Subshell\index{Subshell} aus und lenkt alle Ausgaben um \tabularnewline\STRUT | \texttt{\$ (date; who; pwd) > logfile}\index{!>=\texttt{!>}} & F<>hrt die Befehle in einer Subshell\index{Subshell} aus und lenkt alle Ausgaben um \tabularnewline\STRUT | ||||||
| \texttt{\$ \{ date; who; pwd \} > logfile}\index{!>=\texttt{!>}} & Lenkt alle Ausgaben um \tabularnewline\STRUT | \texttt{\$ \{ date; who; pwd; \} > logfile}\index{!>=\texttt{!>}} & Lenkt alle Ausgaben um \tabularnewline\STRUT | ||||||
|  | \texttt{\$ time \{ date; who; pwd; \}}\index{time=\texttt{time}} & Summiert die Laufzeit der drei Kommandos\tabularnewline\STRUT | ||||||
| \texttt{\$ sort }\textsl{Datei}\texttt{ | lp} & Sortiert die \textsl{Datei} und druckt sie\index{sort=\texttt{sort}} \tabularnewline\STRUT | \texttt{\$ sort }\textsl{Datei}\texttt{ | lp} & Sortiert die \textsl{Datei} und druckt sie\index{sort=\texttt{sort}} \tabularnewline\STRUT | ||||||
| \texttt{\$ vi `grep -l ifdef *.c`}\index{*=\texttt{*}}\index{grep=\texttt{grep}} & Editiert die mittels grep gefundenen Dateien \tabularnewline\STRUT | \texttt{\$ vi `grep -l ifdef *.c`}\index{*=\texttt{*}}\index{grep=\texttt{grep}} & Editiert die mittels grep gefundenen Dateien \tabularnewline\STRUT | ||||||
| \texttt{\$ grep }\textsl{XX Datei}\texttt{ \&\& lp }\textsl{Datei}\index{grep=\texttt{grep}} & Druckt die \textsl{Datei}, wenn sie \textsl{XX} enth<74>lt\index{AND} \tabularnewline\STRUT | \texttt{\$ grep }\textsl{XX Datei}\texttt{ \&\& lp }\textsl{Datei}\index{grep=\texttt{grep}} & Druckt die \textsl{Datei}, wenn sie \textsl{XX} enth<74>lt\index{AND} \tabularnewline\STRUT | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|X l|} |  \begin{longtable}{|X l|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|X l|} |  \begin{longtable}{|X l|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|X l|} |  \begin{longtable}{|X l|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|X l|} |  \begin{longtable}{|X l|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|X l|} |  \begin{longtable}{|X l|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,29 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|   |  | ||||||
| \multicolumn{2}{|X|}{\textsl{Seitenweises Formatieren der Dateien, die auf der Befehlszeile angegeben wurden, und speichern des jeweiligen Ergebnisses:}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{for file do}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~pr \$file > \$file.tmp~~\# pr: Formatiert Textdateien}\index{!>=\texttt{!>}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{done}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\STRUT\textsl{Durchsuche Kapitel zur Erstellung einer Wortliste (wie \texttt{fgrep -f}):}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{for item in `cat program\_list`~~\# cat: Datei ausgeben}\index{cat=\texttt{cat}}\index{Backticks}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{do}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~echo \dq Pruefung der Kapitel auf\dq}\index{Anf<EFBFBD>hrungszeichen}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~echo \dq Referenzen zum Programm \$item ...\dq}\index{Anf<EFBFBD>hrungszeichen}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~grep -c \dq\$item.[co]\dq~chap*~~\# grep: nach Muster\index{Mustererkennung} suchen}\index{[abc]=\texttt{[}\textsl{abc}\texttt{]}}\index{Anf<EFBFBD>hrungszeichen}\index{grep=\texttt{grep}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{done}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\STRUT\textsl{Ermittle einen Ein-Wort-Titel aus jeder Datei und verwende ihn als neuen Dateinamen:}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{for file do}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~name=`sed -n 's/NAME: //p' \$file`}\index{!==\texttt{!=}}\index{Backticks}\index{Ticks}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~\# sed: Skriptsprache zur}\index{sed=\texttt{sed}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~\# Textformatierung}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~mv \$file \$name~~\# mv: Datei verschieben}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~~~~~~~~\# bzw. umbenennen}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{done}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{count () \{}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~ls -1 | wc -l~~\# ls: Liste aller Dateien im Verzeichnis}\index{Pipe}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~~~~~~~\#~~~~~Mit Parameter -1 einspaltig}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~~~~~~~\# wc: Word-Count, z<>hlt W<>rter}\index{wc=\texttt{wc}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~~~~~~~\#~~~~~Mit Parameter -l Zeilen}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{\}}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\textsl{F<EFBFBD>ge eine 0 vor Zahlen kleiner 10 ein:}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{if [ \$counter -lt 10 ]; then}\index{;=\texttt{;}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~number=0\$counter; else number=\$counter; fi}\index{!==\texttt{!=}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\STRUT\textsl{L<EFBFBD>sche ein Verzeichnis, wenn es existiert:}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{if [ -d \$dir ]; then}\index{!!=\texttt{!!}}\index{;=\texttt{;}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~rmdir \$dir; fi~~\# rmdir: Verzeichnis l<>schen}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
|  \begin{longtable}{|l|X|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \texttt{\$ ls neu*} & Listet alle Dateien, die mit `neu' anfangen \tabularnewline\STRUT |  | ||||||
| \texttt{\$ ls neu?} & Listet `neuX', `neu4', aber nicht `neu10' \tabularnewline\STRUT |  | ||||||
| \texttt{\$ ls [D-R]*} & Listet alle Dateien, die mit einem Gro<72>buchstaben\index{Gro<EFBFBD>buchstaben}\footnote{Nat<EFBFBD>rlich wird in Shell-Skripten --- wie <20>berall in der Unix-Welt --- zwischen Gro<72>- und Kleinschreibung unterschieden.} zwischen D und R anfangen |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,15 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{if who | grep \$1 > /dev/null~~\# who: Liste der Benutzer}\index{Pipe}\index{\$n=\texttt{\$}$n$}\index{!>=\texttt{!>}}\index{who=\texttt{who}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\# grep: Suche nach Muster}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{then :~~~~~~~~~~~~~~~~~~~~~~~~\# tut nichts}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~else echo \dq Benutzer \$1 ist nicht angemeldet\dq}\index{Anf<EFBFBD>hrungszeichen}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{fi}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{\$ echo 'Ticks \dq sch<63>tzen\dq~Anf<6E>hrungszeichen'}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{Ticks \dq sch<63>tzen\dq~Anf<6E>hrungszeichen}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\STRUT\texttt{\$ echo \dq Ist dies ein \textbackslash\dq Sonderfall\textbackslash\dq ?\dq}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{Ist dies ein \dq Sonderfall\dq ?}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\STRUT\texttt{\$ echo \dq Sie haben `ls | wc -l` Dateien in `pwd`\dq}\index{wc=\texttt{wc}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{Sie haben 43 Dateien in /home/rschaten}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\STRUT\texttt{\$ echo \dq Der Wert von \textbackslash\$x ist \$x\dq}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{Der Wert von \$x ist 100}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,17 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\textsl{Warten, bis sich der Administrator einloggt:}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{until who | grep \dq root\dq; do}\index{;=\texttt{;}}\index{Anf<EFBFBD>hrungszeichen}\index{who=\texttt{who}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~\# who: Liste der Benutzer}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~~~~~~~~~~\# grep: Suchen nach Muster}\index{Mustererkennung}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~sleep 2~~\# sleep: warten}\index{sleep=\texttt{sleep}}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{done}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{echo \dq Der Meister ist anwesend\dq}\index{Anf<EFBFBD>hrungszeichen}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
| @@ -10,7 +11,7 @@ | |||||||
| \texttt{\$ \textsl{h}=\textsl{hoch} \textsl{r}=\textsl{runter} \textsl{l}=} & Weist den drei Variablen Werte zu, wobei \textsl{l} einen leeren Wert erh<72>lt. \tabularnewline\STRUT | \texttt{\$ \textsl{h}=\textsl{hoch} \textsl{r}=\textsl{runter} \textsl{l}=} & Weist den drei Variablen Werte zu, wobei \textsl{l} einen leeren Wert erh<72>lt. \tabularnewline\STRUT | ||||||
| \texttt{\$ echo \$\{h\}sprung} & Gibt \textsl{hochsprung} aus. Die Klammern m<>ssen gesetzt werden, damit \textsl{h} als Variablenname erkannt werden kann. \tabularnewline\STRUT | \texttt{\$ echo \$\{h\}sprung} & Gibt \textsl{hochsprung} aus. Die Klammern m<>ssen gesetzt werden, damit \textsl{h} als Variablenname erkannt werden kann. \tabularnewline\STRUT | ||||||
| \texttt{\$ echo \$\{h-\$r\}} & Gibt \textsl{hoch} aus, da die Variable \textsl{h} belegt ist. Ansonsten w<>rde der Wert von \textsl{r} ausgegeben. \tabularnewline\STRUT | \texttt{\$ echo \$\{h-\$r\}} & Gibt \textsl{hoch} aus, da die Variable \textsl{h} belegt ist. Ansonsten w<>rde der Wert von \textsl{r} ausgegeben. \tabularnewline\STRUT | ||||||
| \texttt{\$ echo \$\{tmp-`date`\}} & Gibt das aktuelle Datum aus, wenn die Variable \textsl{tmp} nicht gesetzt ist.\footnote{Der Befehl \texttt{date} gibt das Datum zur<75>ck.} \tabularnewline\STRUT | \texttt{\$ echo \$\{tmp-`date`\}} & Gibt das aktuelle Datum aus, wenn die Variable \textsl{tmp} nicht gesetzt ist. \tabularnewline\STRUT | ||||||
| \texttt{\$ echo \$\{l:=\$r\}} & Gibt \textsl{runter} aus, da die Variable \textsl{l} keinen Wert enth<74>lt. Gleichzeitig wird \textsl{l} der Wert von \textsl{r} zugewiesen. \tabularnewline\STRUT | \texttt{\$ echo \$\{l:=\$r\}} & Gibt \textsl{runter} aus, da die Variable \textsl{l} keinen Wert enth<74>lt. Gleichzeitig wird \textsl{l} der Wert von \textsl{r} zugewiesen. \tabularnewline\STRUT | ||||||
| \texttt{\$ echo \$l} & Gibt \textsl{runter} aus, da \textsl{l} jetzt den gleichen Inhalt hat wie \textsl{r}. | \texttt{\$ echo \$l} & Gibt \textsl{runter} aus, da \textsl{l} jetzt den gleichen Inhalt hat wie \textsl{r}. | ||||||
| \end{longtable} | \end{longtable} | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|X l|} |  \begin{longtable}{|X l|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|X l|} |  \begin{longtable}{|X l|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,11 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{break }\textsl{[ n ]}} \\ |  | ||||||
| \end{longtable} |  | ||||||
							
								
								
									
										15
									
								
								tab_case.tex
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								tab_case.tex
									
									
									
									
									
								
							| @@ -1,15 +0,0 @@ | |||||||
| \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
| \hline |  | ||||||
| \endfirsthead |  | ||||||
| \endhead |  | ||||||
| \endfoot |  | ||||||
| \hline |  | ||||||
| \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{case }\textsl{Wert}\texttt{ in}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~}\textsl{Muster1}\texttt{) }\textsl{Befehle1}\texttt{;;}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~}\textsl{Muster2}\texttt{) }\textsl{Befehle2}\texttt{;;}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~\vdots}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{esac}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{continue }\textsl{[ n ]}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|X|X|X|X|} |  \begin{longtable}{|X|X|X|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								tab_exit.tex
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								tab_exit.tex
									
									
									
									
									
								
							| @@ -1,11 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{exit }\textsl{[ n ]}} \\ |  | ||||||
| \end{longtable} |  | ||||||
							
								
								
									
										14
									
								
								tab_for.tex
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tab_for.tex
									
									
									
									
									
								
							| @@ -1,14 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{for }\textsl{x [}\texttt{ in }\textsl{Liste ]}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{do}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~}\textsl{Befehle}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{done}} \\ |  | ||||||
| \end{longtable} |  | ||||||
							
								
								
									
										17
									
								
								tab_if.tex
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								tab_if.tex
									
									
									
									
									
								
							| @@ -1,17 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{if }\textsl{Bedingung1}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{then }\textsl{Befehle1}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\textsl{[}\texttt{ elif }\textsl{Bedingung2}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{  then }\textsl{Befehle2 ]}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{  \vdots}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\textsl{[}\texttt{ else }\textsl{Befehle3 ]}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{fi}} \\ |  | ||||||
| \end{longtable} |  | ||||||
							
								
								
									
										21
									
								
								tab_kommandos_awk_variablen.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tab_kommandos_awk_variablen.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{FILENAME} & Der Name der aktuellen Eingabedatei, oder `-' wenn von der Standard-Eingabe gelesen wird\tabularnewline\STRUT | ||||||
|  | \texttt{FS} & Field Separator, das Trennzeichen nach dem die Felder unterteilt werden \tabularnewline\STRUT | ||||||
|  | \texttt{OFS} & Feldtrennzeichen f<>r die Ausgabe \tabularnewline\STRUT | ||||||
|  | \texttt{RS} & Record Separator, das Trennzeichen nach dem Datens<6E>tze unterteilt werden \tabularnewline\STRUT | ||||||
|  | \texttt{ORS} & Datensatztrennzeichen f<>r die Ausgabe \tabularnewline\STRUT | ||||||
|  | \texttt{NF} & Anzahl der Felder im aktuellen Datensatz \tabularnewline\STRUT | ||||||
|  | \texttt{NR} & Laufende Nummer des aktuellen Datensatzes \tabularnewline\STRUT | ||||||
|  | \texttt{OFMT} & Ausgabeformat f<>r die Ausgabe von Zahlen und Strings,  \tabularnewline\STRUT | ||||||
|  | \texttt{\$0} & Der komplette aktuelle Datensatz \tabularnewline\STRUT | ||||||
|  | \texttt{\$}\textsl{n} & Feld \textsl{n} des aktuellen Datensatzes | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										16
									
								
								tab_kommandos_chmod_beispiele.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tab_kommandos_chmod_beispiele.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | a-x &  & Allen Benutzern werden die Ausf<73>hrungsrechte genommen \tabularnewline\STRUT | ||||||
|  | ug+rw &  & Dem Besitzer und der Gruppe werden Lese- und Schreibrechte gegeben \tabularnewline\STRUT | ||||||
|  | u=rw,go-rwx & 600 & Nur der Besitzer kann die Datei lesen und schreiben \tabularnewline\STRUT | ||||||
|  | u=rw,go=r & 644 & Der Besitzer darf lesen und schreiben, alle anderen nur lesen  \tabularnewline\STRUT | ||||||
|  | u=rwx,go=rx & 755 & Der Besitzer darf lesen, schreiben und ausf<73>hren, alle anderen nur lesen und ausf<73>hren | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										16
									
								
								tab_kommandos_cut_beispiele.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tab_kommandos_cut_beispiele.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \textsl{s=\dq{}Dies ist ein Test\dq{}} & ~  \tabularnewline\STRUT | ||||||
|  | \texttt{echo \dq{}\$s\dq{} | cut -c 2-6} & gibt `ies i' aus \tabularnewline\STRUT | ||||||
|  | \texttt{echo \dq{}\$s\dq{} | cut -d \dq{}~\dq{} -f 2} & gibt `ist' aus \tabularnewline\STRUT | ||||||
|  | \texttt{echo \dq{}\$s\dq{} | cut -d \dq{}~\dq{} -f 2-3} & gibt `ist ein' aus \tabularnewline\STRUT | ||||||
|  | \texttt{echo \dq{}\$s\dq{} | cut -d \dq{}~\dq{} -f 2-} & gibt `ist ein Test' aus | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										16
									
								
								tab_kommandos_echo_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tab_kommandos_echo_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{-n} & Unterdr<64>ckt den Zeilenumbruch am Ende der Ausgabe \tabularnewline\STRUT | ||||||
|  | \texttt{-e} & Aktiviert die Interpretation von Steuerzeichen. Diese | ||||||
|  | Steuerzeichen werden mit einem Backslash gequoted, der ganze String mu<6D> in | ||||||
|  | Ticks eingeschlossen werden. Beispielsweise gibt \texttt{echo -e | ||||||
|  | 'hallo\textbackslash a'} das Wort hallo und einen Piepton aus. | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										19
									
								
								tab_kommandos_eval_beispiel.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tab_kommandos_eval_beispiel.tex
									
									
									
									
									
										Normal 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<75>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<65>hrt. \tabularnewline\STRUT | ||||||
|  | \texttt{echo \$b} & Der neue Inhalt der Variablen `b' wird ausgegeben. \tabularnewline\STRUT | ||||||
|  | \textsl{42} &  | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										29
									
								
								tab_kommandos_expr_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tab_kommandos_expr_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{|} & logisches `oder' \tabularnewline\STRUT | ||||||
|  | \texttt{\&} & logisches `und' \tabularnewline\STRUT | ||||||
|  | \texttt{<} & kleiner als \tabularnewline\STRUT | ||||||
|  | \texttt{<=} & kleiner als oder gleich \tabularnewline\STRUT | ||||||
|  | \texttt{=} & gleich \tabularnewline\STRUT | ||||||
|  | \texttt{!=} & ungleich \tabularnewline\STRUT | ||||||
|  | \texttt{>=} & gr<67><72>er als oder gleich \tabularnewline\STRUT | ||||||
|  | \texttt{>} & gr<67><72>er als \tabularnewline\STRUT | ||||||
|  | \texttt{+} & Addition \tabularnewline\STRUT | ||||||
|  | \texttt{-} & Subtraktion \tabularnewline\STRUT | ||||||
|  | \texttt{*} & Multiplikation \tabularnewline\STRUT | ||||||
|  | \texttt{/} & Division \tabularnewline\STRUT | ||||||
|  | \texttt{\%} & Modulo (`Divisionsrest') \tabularnewline\STRUT | ||||||
|  | \texttt{:} & Pattern-Match mit regul<75>ren Ausdr<64>cken \tabularnewline\STRUT | ||||||
|  | \texttt{match} & Analog zu `:' \tabularnewline\STRUT | ||||||
|  | \texttt{substr} & Teil einer Zeichenkette zur<75>ckgeben \tabularnewline\STRUT | ||||||
|  | \texttt{index} & Position einer Zeichenkette in einer anderen finden \tabularnewline\STRUT | ||||||
|  | \texttt{length} & L<>nge einer Zeichenkette | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										31
									
								
								tab_kommandos_find_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								tab_kommandos_find_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | Kriterien: & \tabularnewline\STRUT | ||||||
|  | \texttt{-name }\textsl{pattern} & Suchmuster f<>r den Dateinamen, auch mit Meta-Zeichen (Abschnitt \ref{metazeichen}) \tabularnewline\STRUT | ||||||
|  | \texttt{-perm [-]}\textsl{mode} & Sucht nach Dateien, deren Berechtigungen dem angegebenen Modus entsprechen. Die Notation erfolgt dabei analog zu \texttt{chmod} (Abschnitt \ref{chmod}), wahlweise in der Buchstaben- oder in der Zahlenform \tabularnewline\STRUT | ||||||
|  | \texttt{-type }\textsl{c} & Sucht nach Dateien des angegebenen Typs. Dabei kann f<>r \textsl{c} `b' (block device), `c' (character device), `d' (directory), `l' (symbolic link), `p' (pipe), `f' (regular file), oder `s' (socket) eingesetzt werden \tabularnewline\STRUT | ||||||
|  | \texttt{-user }\textsl{name} & Sucht nach Dateien, die dem angegebenen Benutzer geh<65>ren. Die Angabe kann als Name oder als UID erfolgen \tabularnewline\STRUT | ||||||
|  | \texttt{-group }\textsl{name} & Sucht nach Dateien, die der angegebenen Gruppe geh<65>ren. Die Angabe kann als Name oder als GID erfolgen \tabularnewline\STRUT | ||||||
|  | \texttt{-size }\textsl{n}\texttt{[c]} & Sucht nach Dateien, deren Gr<47><72>e \textsl{n} Blocks\footnote{Blocks geben die Dateigr<67><72>e in Bytes dividiert durch 512 und aufgerundet auf den n<>chsten Integer an. Das hat historische Gr<47>nde.} oder bei nachgestelltem \texttt{c} \textsl{n} Bytes ist \tabularnewline\STRUT | ||||||
|  | \texttt{-atime }\textsl{n} & Sucht nach Dateien, deren letzter Zugriff (access time) \texttt{n}*24 Stunden zur<75>ck liegt \tabularnewline\STRUT | ||||||
|  | \texttt{-ctime }\textsl{n} & Sucht nach Dateien, deren letzte Status<75>nderung (change time) \texttt{n}*24 Stunden zur<75>ck liegt \tabularnewline\STRUT | ||||||
|  | \texttt{-mtime }\textsl{n} & Sucht nach Dateien, deren letzte <20>nderung (modification time) \texttt{n}*24 Stunden zur<75>ck liegt \tabularnewline\STRUT | ||||||
|  | \texttt{-newer }\textsl{file} & Sucht nach Dateien, die j<>nger sind als \textsl{file} \tabularnewline\STRUT | ||||||
|  | Optionen: & \tabularnewline\STRUT | ||||||
|  | \texttt{-xdev} & Nur auf einem Filesystem suchen \tabularnewline\STRUT | ||||||
|  | \texttt{-depth } & Normalerweise wird eine Breitensuche durchgef<65>hrt, dieser Parameter schaltet auf Tiefensuche um \tabularnewline\STRUT | ||||||
|  | Aktionen: & \tabularnewline\STRUT | ||||||
|  | \texttt{-print} & Dies ist default, die gefundenen Dateinamen werden ausgegeben \tabularnewline\STRUT | ||||||
|  | \texttt{-exec }\textsl{kommando}\texttt{ \{\};} & F<>hrt das Kommando f<>r jede | ||||||
|  | Fundstelle aus, an Stelle der geschweiften Klammern wird der gefundene | ||||||
|  | Dateiname eingesetzt. Das abschlie<69>ende Semikolon mu<6D> wegen seiner | ||||||
|  | Sonderbedeutung in der Regel durch einen Backslash gequoted werden | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										20
									
								
								tab_kommandos_grep_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tab_kommandos_grep_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{-E} & Benutzt erweiterte regul<75>re Ausdr<64>cke \tabularnewline\STRUT | ||||||
|  | \texttt{-F} & Der Suchbegriff wird nicht als regul<75>rer Ausdruck, sondern als `fixed String' benutzt \tabularnewline\STRUT | ||||||
|  | \texttt{-c} & Gibt f<>r jede durchsuchte Datei die Anzahl der Fundstellen aus \tabularnewline\STRUT | ||||||
|  | \texttt{-f} & Liest die Suchbegriffe Zeile f<>r Zeile aus einer Textdatei \tabularnewline\STRUT | ||||||
|  | \texttt{-i} & Ignoriert die Unterscheidung zwischen Gro<72>- und Kleinschreibung \tabularnewline\STRUT | ||||||
|  | \texttt{-l} & Gibt nur die Dateinamen aus \tabularnewline\STRUT | ||||||
|  | \texttt{-n} & Gibt zus<75>tzlich die Zeilennummern der Fundstellen aus \tabularnewline\STRUT | ||||||
|  | \texttt{-q} & Gibt die Fundstellen nicht aus, am Exitcode ist zu erkennen ob etwas gefunden wurde \tabularnewline\STRUT | ||||||
|  | \texttt{-v} & Findet alle Zeilen, in denen das Suchmuster \emph{nicht} vorkommt | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										23
									
								
								tab_kommandos_ls_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tab_kommandos_ls_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{-1} & Formatiert die Ausgabe einspaltig \tabularnewline\STRUT | ||||||
|  | \texttt{-a} & Zeigt alle Dateien an, auch solche deren Name mit einem Punkt anf<6E>ngt \tabularnewline\STRUT | ||||||
|  | \texttt{-A} & \ding{43} Zeigt `fast alle' Dateien an, also auch alle deren Name mit einem Punkt anf<6E>ngt, allerdings nicht `.' und `..', die in jedem Verzeichnis vorkommen \tabularnewline\STRUT | ||||||
|  | \texttt{-d} & Verzeichnisse werden behandelt wie jede andere Datei auch, ein \texttt{ls -ld verzeichnis} gibt also die Eigenschaften des Verzeichnisses aus, nicht dessen Inhalt \tabularnewline\STRUT | ||||||
|  | \texttt{-h} & \ding{43} Gibt bei einer langen Ausgabe mittels \texttt{-l} die Gr<47><72>e der Datei `human readable' aus, also nicht zwingend in Bytes \tabularnewline\STRUT | ||||||
|  | \texttt{-l} & Lange Ausgabe, inklusiv der Dateiattribute \tabularnewline\STRUT | ||||||
|  | \texttt{-L} & \ding{43} `Dereferenziert' Links vor der Ausgabe. Es werden nicht die Eigenschaften des Links angezeigt, sondern die der verlinkten Datei \tabularnewline\STRUT | ||||||
|  | \texttt{-r} & Sortierreihenfolge umkehren \tabularnewline\STRUT | ||||||
|  | \texttt{-R} & Rekursiv in Verzeichnisse absteigen und deren Inhalte anzeigen \tabularnewline\STRUT | ||||||
|  | \texttt{-S} & \ding{43} Nach der Gr<47><72>e der Datei sortieren \tabularnewline\STRUT | ||||||
|  | \texttt{-t} & Nach der letzten <20>nderungszeit sortieren \tabularnewline\STRUT | ||||||
|  | \texttt{-X} & \ding{43} Nach der Extension (also dem Namensteil nach dem letzten Punkt) sortieren | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										15
									
								
								tab_kommandos_pgrep_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tab_kommandos_pgrep_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{-f} & Normalerweise wird nur nach Proze<7A>-Namen gesucht, mit diesem Parameter wird das volle Kommando (incl. Pfad und Parametern) betrachtet\tabularnewline\STRUT | ||||||
|  | \texttt{-l} & Nicht nur die Proze<7A>-ID, sondern das volle Kommando wird ausgegeben\tabularnewline\STRUT | ||||||
|  | \texttt{-v} & Findet alle Zeilen, in denen das Suchmuster \emph{nicht} vorkommt\tabularnewline\STRUT | ||||||
|  | \texttt{-x} & Sucht nach Kommandos, deren Name dem Muster \emph{exakt} entspricht | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										15
									
								
								tab_kommandos_printf_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tab_kommandos_printf_parameter.tex
									
									
									
									
									
										Normal 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 <20>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<73>ndige Formatierung festgelegt werden. | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										19
									
								
								tab_kommandos_sed_adressen.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tab_kommandos_sed_adressen.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{d} & Keine Adresse angegeben, alle Zeilen werden gel<65>scht \tabularnewline\STRUT | ||||||
|  | \texttt{23d} & Zeile 23 wird gel<65>scht \tabularnewline\STRUT | ||||||
|  | \texttt{\$d} & Die letzte Eingabezeile wird gel<65>scht \tabularnewline\STRUT | ||||||
|  | \texttt{/}\textsl{pattern}\texttt{/d} & Jede Zeile, die den regul<75>ren Ausdruck \textsl{pattern} enth<74>lt wird gel<65>scht \tabularnewline\STRUT | ||||||
|  | \texttt{23,42d} & Die Zeilen 23 bis einschlie<69>lich 42 werden gel<65>scht \tabularnewline\STRUT | ||||||
|  | \texttt{23,\$d} & Von Zeile 23 bis zum Ende wird gel<65>scht \tabularnewline\STRUT | ||||||
|  | \texttt{1,/\^\$/d} & Von der ersten bis zur ersten Leerzeile wird gel<65>scht \tabularnewline\STRUT | ||||||
|  | \texttt{23,42!d} & Alles au<61>er den Zeilen 23 bis 42 wird gel<65>scht | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										17
									
								
								tab_kommandos_sed_kommandos.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tab_kommandos_sed_kommandos.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | Editieren: & \tabularnewline\STRUT | ||||||
|  | \texttt{/}\textsl{adresse}\texttt{/d} & Zeilen l<>schen \tabularnewline\STRUT | ||||||
|  | \texttt{s/}\textsl{regexp1}\texttt{/}\textsl{regexp2}\texttt{/} & Substitution: Suchen und ersetzen \tabularnewline\STRUT | ||||||
|  | \texttt{y/}\textsl{menge1}\texttt{/}\textsl{menge2}\texttt{/} & Zeichen ersetzen \tabularnewline\STRUT | ||||||
|  | Zeileninformation: & \tabularnewline\STRUT | ||||||
|  | \texttt{/}\textsl{adresse}\texttt{/p} & Zeilen ausgeben | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										16
									
								
								tab_kommandos_sort_beispiele.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tab_kommandos_sort_beispiele.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{-k 3} & Sortiert nach dem dritten Feld \tabularnewline\STRUT | ||||||
|  | \texttt{-k 3.5} & Sortiert nach dem f<>nften Zeichen des dritten Feldes \tabularnewline\STRUT | ||||||
|  | \texttt{-k 3.5r} & Sortiert r<>ckw<6B>rts nach dem f<>nften Zeichen des dritten Feldes \tabularnewline\STRUT | ||||||
|  | \texttt{-k 3,5} & Beachtet bei der Sortierung nur das dritte bis f<>nfte Feld \tabularnewline\STRUT | ||||||
|  | \texttt{-k 3.5,3.8} & Beachtet die Zeichen f<>nf bis acht des dritten Feldes | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										20
									
								
								tab_kommandos_sort_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tab_kommandos_sort_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{-b} & Ignoriert f<>hrende Leerzeichen \tabularnewline\STRUT | ||||||
|  | \texttt{-c} & Pr<50>ft nur, ob die Eingabedaten bereits sortiert sind \tabularnewline\STRUT | ||||||
|  | \texttt{-f} & Gro<72>- / Kleinschreibung nicht beachten \tabularnewline\STRUT | ||||||
|  | \texttt{-i} & Nur `printable' Zeichen beachten \tabularnewline\STRUT | ||||||
|  | \texttt{-k} & Sortiert nicht nach der ersten, sondern nach der angegebenen Spalte (siehe unten) \tabularnewline\STRUT | ||||||
|  | \texttt{-n} & Numerische Sortierung \tabularnewline\STRUT | ||||||
|  | \texttt{-r} & Sortierreihenfolge umkehren \tabularnewline\STRUT | ||||||
|  | \texttt{-t} & Normalerweise f<>ngt ein Feld (siehe \texttt{-k}) beim <20>bergang von `blank' nach `non-blank' an, mit diesem Parameter k<>nnen ander Feld-Trenner definiert werden \tabularnewline\STRUT | ||||||
|  | \texttt{-u} & Gibt bei identischen Zeilen nur die erste Fundstelle aus (unique) | ||||||
|  | \end{longtable} | ||||||
							
								
								
									
										19
									
								
								tab_kommandos_uniq_parameter.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tab_kommandos_uniq_parameter.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | % $Id$ | ||||||
|  | \begin{longtable}{|l|X|} | ||||||
|  | % KILLED & LINE!!!! \kill | ||||||
|  |  \hline | ||||||
|  |  \endfirsthead | ||||||
|  |  \endhead | ||||||
|  |  \endfoot | ||||||
|  |  \hline | ||||||
|  |  \endlastfoot | ||||||
|  |  | ||||||
|  | \texttt{-c} & Anzahl der Vorkommnisse vor die Zeilen schreiben \tabularnewline\STRUT | ||||||
|  | \texttt{-d} & Nur doppelte Zeilen ausgeben, jede nur einmal \tabularnewline\STRUT | ||||||
|  | \texttt{-D} & \ding{43} Alle doppelten Zeilen ausgeben \tabularnewline\STRUT | ||||||
|  | \texttt{-f }\textsl{n} & Die ersten \textsl{n} Felder ignorieren \tabularnewline\STRUT | ||||||
|  | \texttt{-i} & \ding{43} Gro<72>- / Kleinschreibung ignorieren \tabularnewline\STRUT | ||||||
|  | \texttt{-s }\textsl{n} & Die ersten \textsl{n} Zeichen ignorieren \tabularnewline\STRUT | ||||||
|  | \texttt{-u} & Nur einfach vorkommende Zeilen ausgeben \tabularnewline\STRUT | ||||||
|  | \texttt{-w }\textsl{n} & \ding{43} Nur die ersten \textsl{n} Zeichen betrachten | ||||||
|  | \end{longtable} | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|c|c|c|X|} |  \begin{longtable}{|l|c|c|c|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|c|c|c|c|c|c|c|X|} |  \begin{longtable}{|l|c|c|c|c|c|c|c|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
| @@ -9,11 +10,12 @@ | |||||||
|  |  | ||||||
| \texttt{;} & Befehls-Trennzeichen\index{Befehls>-Trennzeichen} \tabularnewline\STRUT | \texttt{;} & Befehls-Trennzeichen\index{Befehls>-Trennzeichen} \tabularnewline\STRUT | ||||||
| \texttt{\&} & Hintergrund-Verarbeitung \tabularnewline\STRUT | \texttt{\&} & Hintergrund-Verarbeitung \tabularnewline\STRUT | ||||||
| \texttt{( )} & Befehlsfolge\index{Befehls>-folge} \tabularnewline\STRUT | \texttt{( ) \{ \}} & Befehlsfolge\index{Befehls>-folge} \tabularnewline\STRUT | ||||||
| \texttt{|} & Pipe \tabularnewline\STRUT | \texttt{|} & Pipe \tabularnewline\STRUT | ||||||
| \texttt{< > >\&} & Umlenkungssymbole \tabularnewline\STRUT | \texttt{< > >\&} & Umlenkungssymbole \tabularnewline\STRUT | ||||||
| \texttt{* ? [ ] \~{} + - @ !} & Meta-Zeichen\index{Meta-Zeichen} f<>r Dateinamen \tabularnewline\STRUT | \texttt{* ? [ ] \~{} + - @ !} & Meta-Zeichen\index{Meta-Zeichen} f<>r Dateinamen \tabularnewline\STRUT | ||||||
| \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 <EFBFBD>blicherweise 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{\$} & 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}\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 vordefinierten Variable \texttt{\$IFS} abgelegt. Siehe Abschnitt \ref{vordefinierte_variablen}.} | ||||||
| \end{longtable} | \end{longtable} | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
| @@ -7,17 +8,18 @@ | |||||||
|  \hline |  \hline | ||||||
|  \endlastfoot |  \endlastfoot | ||||||
|  |  | ||||||
| \texttt{\dq~\dq} & (Anf<6E>hrungszeichen) Alles zwischen diesen Zeichen ist | \texttt{\dq~\dq} & (Anf<6E>hrungszeichen oder Double Quotes) Alles zwischen diesen | ||||||
| buchstabengetreu zu interpretieren. Ausnahmen sind folgende Zeichen, die ihre | Zeichen ist buchstabengetreu zu interpretieren. Ausnahmen sind folgende | ||||||
| spezielle Bedeutung beibehalten: \texttt{\$ ` \dq} \tabularnewline\STRUT | Zeichen, die ihre spezielle Bedeutung beibehalten: \texttt{\$ ` \dq} | ||||||
|  |  | ||||||
| \texttt{' '} & (Ticks\footnote{Sie liegen auf der Tastatur <20>ber der Raute.}) |  | ||||||
| Alls zwischen diesen Zeichen wird w<>rtlich genommen, mit Ausnahme eines |  | ||||||
| weiteren \texttt{'} oder eines Backslashes (\texttt{\textbackslash}) |  | ||||||
| \tabularnewline\STRUT | \tabularnewline\STRUT | ||||||
|  |  | ||||||
|  | \texttt{' '} & (Ticks oder (Single) Quotes\footnote{Sie liegen auf der Tastatur | ||||||
|  | <EFBFBD>ber der Raute.}) Alls zwischen diesen Zeichen wird w<>rtlich genommen, mit | ||||||
|  | Ausnahme eines weiteren \texttt{'} oder eines Backslashes | ||||||
|  | (\texttt{\textbackslash}) \tabularnewline\STRUT | ||||||
|  |  | ||||||
| \texttt{\textbackslash} & (Backslash\index{Backslash}) Das Zeichen nach einem | \texttt{\textbackslash} & (Backslash\index{Backslash}) Das Zeichen nach einem | ||||||
| \textbackslash wird w<>rtlich genommen. Anwendung z. B. innerhalb von | \textbackslash wird w<>rtlich genommen. Anwendung z.~B. innerhalb von | ||||||
| \texttt{\dq~\dq}, um \texttt{\dq}, \texttt{\$} und \texttt{`} zu entwerten. | \texttt{\dq~\dq}, um \texttt{\dq}, \texttt{\$} und \texttt{`} zu entwerten. | ||||||
| H<EFBFBD>ufig verwendet zur Angabe von Leerzeichen (space) und Zeilenendezeichen, oder | H<EFBFBD>ufig verwendet zur Angabe von Leerzeichen (space) und Zeilenendezeichen, oder | ||||||
| um ein \textbackslash -Zeichen selbst anzugeben. | um ein \textbackslash -Zeichen selbst anzugeben. | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|l|X|} |  \begin{longtable}{|l|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
| @@ -11,6 +12,6 @@ Nummer & Name & Bedeutung \\ | |||||||
|  |  | ||||||
| 0 & Normal Exit & Wird durch das \texttt{exit}\index{exit=\texttt{exit}}-Kommando ausgel<65>st. \tabularnewline\STRUT | 0 & Normal Exit & Wird durch das \texttt{exit}\index{exit=\texttt{exit}}-Kommando ausgel<65>st. \tabularnewline\STRUT | ||||||
| 1 & SIGHUP & Wenn die Verbindung abbricht (z. B. wenn das Terminal geschlossen wird). \tabularnewline\STRUT | 1 & SIGHUP & Wenn die Verbindung abbricht (z. B. wenn das Terminal geschlossen wird). \tabularnewline\STRUT | ||||||
| 2 & SIGINT & Zeigt einen Interrupt an (\Ovalbox{CTRL}-\Ovalbox{C}). \tabularnewline\STRUT | 2 & SIGINT & Zeigt einen Interrupt an (\Ovalbox{CTRL}+\Ovalbox{C}). \tabularnewline\STRUT | ||||||
| 15 & SIGTERM & Wird vom \texttt{kill}\index{kill=\texttt{kill}}-Kommando gesendet. | 15 & SIGTERM & Wird vom \texttt{kill}\index{kill=\texttt{kill}}-Kommando gesendet. | ||||||
| \end{longtable} | \end{longtable} | ||||||
|   | |||||||
| @@ -1,14 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{until }\textsl{Bedingung}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{do}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~}\textsl{Befehle}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{done}} \\ |  | ||||||
| \end{longtable} |  | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
| @@ -8,9 +9,9 @@ | |||||||
|  \endlastfoot |  \endlastfoot | ||||||
|  |  | ||||||
| \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. | ||||||
| \end{longtable} | \end{longtable} | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | % $Id$ | ||||||
|  \begin{longtable}{|l|X|} |  \begin{longtable}{|l|X|} | ||||||
| % KILLED & LINE!!!! \kill | % KILLED & LINE!!!! \kill | ||||||
|  \hline |  \hline | ||||||
| @@ -15,6 +16,8 @@ | |||||||
| \texttt{\$\$} & Proze<7A>nummer der aktiven Shell \tabularnewline\STRUT | \texttt{\$\$} & Proze<7A>nummer der aktiven Shell \tabularnewline\STRUT | ||||||
| \texttt{\$!} & Proze<7A>nummer des letzten Hintergrundprozesses \tabularnewline\STRUT | \texttt{\$!} & Proze<7A>nummer des letzten Hintergrundprozesses \tabularnewline\STRUT | ||||||
| \texttt{\$ERRNO} & Fehlernummer des letzten fehlgeschlagenen Systemaufrufs \tabularnewline\STRUT | \texttt{\$ERRNO} & Fehlernummer des letzten fehlgeschlagenen Systemaufrufs \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{\$IFS} & Feldseparator, wird beispielsweise beim Lesen mittels \texttt{read} benutzt \tabularnewline\STRUT | ||||||
|  | \texttt{\$PATH} & Pfad, in dem nach ausf<73>hrbaren Kommandos gesucht wird\footnote{Mit dem Kommando \texttt{type}\index{type=\texttt{type}} findet man heraus, welches Executable tats<74>chlich verwendet wird.}.  Mehrere Eintr<74>ge werden durch Doppelpunkte getrennt angegeben \tabularnewline\STRUT | ||||||
|  | \texttt{\$PWD} & Aktuelles Verzeichnis (wird durch \texttt{cd} gesetzt\footnote{Durch das Kommando \texttt{cd} wird das aktuelle Verzeichnis gewechselt, siehe Abschnitt \ref{cd}.}) \tabularnewline\STRUT | ||||||
| \texttt{\$OLDPWD} & Vorheriges Verzeichnis (wird durch \texttt{cd} gesetzt) | \texttt{\$OLDPWD} & Vorheriges Verzeichnis (wird durch \texttt{cd} gesetzt) | ||||||
| \end{longtable} | \end{longtable} | ||||||
|   | |||||||
| @@ -1,14 +0,0 @@ | |||||||
|  \begin{longtable}{|X l|} |  | ||||||
| % KILLED & LINE!!!! \kill |  | ||||||
|  \hline |  | ||||||
|  \endfirsthead |  | ||||||
|  \endhead |  | ||||||
|  \endfoot |  | ||||||
|  \hline |  | ||||||
|  \endlastfoot |  | ||||||
|  |  | ||||||
| \multicolumn{2}{|X|}{\texttt{while }\textsl{Bedingung}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{do}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{~}\textsl{Befehle}} \\ |  | ||||||
| \multicolumn{2}{|X|}{\texttt{done}} \\ |  | ||||||
| \end{longtable} |  | ||||||
							
								
								
									
										29
									
								
								todo.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								todo.tex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | % $Id$ | ||||||
|  | \chapter{Routenplanung - Die Zukunft dieses Dokuments} | ||||||
|  |  | ||||||
|  | Ich werde in dieser Version des Dokumentes nicht alles umgesetzt haben, was mir | ||||||
|  | sinnvoll erscheint. An dieser Stelle sammele ich Ideen f<>r eine n<>chste | ||||||
|  | Version. Kommentare dazu nehme ich jederzeit dankend entgegen. | ||||||
|  |  | ||||||
|  | \begin{itemize} | ||||||
|  |  | ||||||
|  | \item \textbf{GNU / Posix:} Bessere Abgrenzung der GNU-Erweiterungen | ||||||
|  | ge\-gen\-<EFBFBD>\-ber dem Posix-Standard, damit die Skripte portabel bleiben und | ||||||
|  | nicht nur auf Linux laufen. | ||||||
|  |  | ||||||
|  | \item \textbf{Performance:} Ein Kapitel mit Hinweisen, wie Skripte nicht | ||||||
|  | unn<EFBFBD>tig langsam werden. | ||||||
|  |  | ||||||
|  | \item \textbf{Interaktive Shell:} Exkurs zur interaktiven Benutzung der Bash. | ||||||
|  | Es gibt da eine Reihe hilfreicher Tastenkombinationen, die l<>ngst nicht jedem | ||||||
|  | bekannt sind. | ||||||
|  |  | ||||||
|  | \item \textbf{HTML-Version:} Ich w<>rde gerne eine HTML-Version zur Verf<72>gung | ||||||
|  | stellen, bin mir aber noch nicht sicher ob das aus den \LaTeX-Quellen geht. Mir | ||||||
|  | liegt dabei die Indizierung der Stichworte am Herzen, die sollte nicht | ||||||
|  | verloren gehen. | ||||||
|  |  | ||||||
|  | \item \textbf{Glossar:} Verzeichnis von Begriffen wie PID, Prompt, GID, UID, | ||||||
|  | Cron, usw. | ||||||
|  |  | ||||||
|  | \end{itemize} | ||||||
| @@ -1,45 +1,126 @@ | |||||||
|  | % $Id$ | ||||||
| \chapter{Was ist die Shell?}\index{Shell} | \chapter{Was ist die Shell?}\index{Shell} | ||||||
|  |  | ||||||
| Die Shell ist ein Programm, mit dessen Hilfe das System die Benutzerbefehle verstehen kann. Aus diesem Grund wird die Shell auch oft als Befehls- oder Kommandointerpreter bezeichnet. | Die Shell ist ein Programm, mit dessen Hilfe das System die Benutzerbefehle | ||||||
|  | verstehen kann. Aus diesem Grund wird die Shell auch oft als Befehls- oder | ||||||
|  | Kommandointerpreter bezeichnet. | ||||||
|  |  | ||||||
| \section{Sinn und Zweck} | \section{Sinn und Zweck} | ||||||
|  |  | ||||||
| In einem klassischen Unix-System (ohne die grafische Oberfl<66>che X) greifen die Benutzer <20>ber Terminals\index{Terminal} auf das System zu. Auf diesen Terminals k<>nnen nur Textzeichen dargestellt werden. Um dem Benutzer die Arbeit mit dem System effektiv m<>glich zu machen, gibt es die Shell. Die Shell wird dabei f<>r drei Hauptaufgaben benutzt: | In einem klassischen Unix-System (ohne die grafische Oberfl<66>che X) greifen die | ||||||
|  | Benutzer <20>ber Terminals\index{Terminal} auf das System zu. Auf diesen Terminals | ||||||
|  | k<EFBFBD>nnen nur Textzeichen dargestellt werden. Um dem Benutzer die Arbeit mit dem | ||||||
|  | System effektiv m<>glich zu machen, gibt es die Shell. Die Shell wird dabei f<>r | ||||||
|  | drei Hauptaufgaben benutzt: | ||||||
| \begin{itemize} | \begin{itemize} | ||||||
| \item Interaktive Anwendung (Dialog) | \item Interaktive Anwendung (Dialog) | ||||||
| \item Anwendungsspezifische Anpassung des Unix-Systemverhaltens (Belegen von Umgebungsvariablen) | \item Anwendungsspezifische Anpassung des Unix-Systemverhaltens (Belegen von Umgebungsvariablen) | ||||||
| \item Programmierung (Shell-Skripting). Zu diesem Zweck stehen einige Mechanismen zur Verf<72>gung, die aus Hochsprachen bekannt sind (Variablen, Datenstr<74>me, Funktionen usw.). | \item Programmierung (Shell-Skripting). Zu diesem Zweck stehen einige Mechanismen zur Verf<72>gung, die aus Hochsprachen bekannt sind (Variablen, Datenstr<74>me, Funktionen usw.). | ||||||
| \end{itemize} | \end{itemize} | ||||||
| Urspr<EFBFBD>nglich handelte es sich dabei um ein relativ einfaches Programm, der Bourne Shell (wird oft auch Standard-Shell genannt). Dies ist praktisch die "`Mutter aller Shells"'. Aus dieser entwickelten sich im Laufe der Zeit mehrere Varianten, die alle ihre eigenen Vor- und Nachteile mit sich bringen. Da es unter Unix kein Problem darstellt den Kommandointerpreter auszutauschen, stehen auf den meisten Systemen mehrere dieser Shells zur Verf<72>gung. Welche Variante ein Benutzer verwenden m<>chte ist reine Geschmackssache. | Urspr<EFBFBD>nglich handelte es sich dabei um ein relativ einfaches Programm, der | ||||||
|  | Bourne Shell (wird oft auch Standard-Shell genannt). Dies ist praktisch die | ||||||
|  | "`Mutter aller Shells"'. Aus dieser entwickelten sich im Laufe der Zeit mehrere | ||||||
|  | Varianten, die alle ihre eigenen Vor- und Nachteile mit sich bringen. Da es | ||||||
|  | unter Unix kein Problem darstellt den Kommandointerpreter auszutauschen, stehen | ||||||
|  | auf den meisten Systemen mehrere dieser Shells zur Verf<72>gung. Welche Variante | ||||||
|  | ein Benutzer verwenden m<>chte ist reine Geschmackssache. | ||||||
|  |  | ||||||
| \section{Die Qual der Wahl} | \section{Die Qual der Wahl} | ||||||
|  |  | ||||||
| Um die Auswahl einer Shell zu erleichtern, werden hier die wichtigsten Varianten kurz vorgestellt. Sie sind aufgeteilt in Einfach- und Komfort-Shells. Die Komfort-Shells zeichnen sich durch komfortablere Funktionen zur interaktiven Bedienung aus, w<>hrend die Einfach-Versionen <20>blicherweise f<>r die Programmierung benutzt werden. | Um die Auswahl einer Shell zu erleichtern, werden hier die wichtigsten | ||||||
|  | Varianten kurz vorgestellt. Sie sind aufgeteilt in Einfach- und Komfort-Shells. | ||||||
|  | Die Komfort-Shells zeichnen sich durch komfortablere Funktionen zur | ||||||
|  | interaktiven Bedienung aus, w<>hrend die Einfach-Versionen <20>blicherweise f<>r die | ||||||
|  | Programmierung benutzt werden. | ||||||
|  |  | ||||||
| \medskip\emph{Einfach-Shells:}\nopagebreak | \medskip\emph{Einfach-Shells:}\nopagebreak | ||||||
|  |  | ||||||
| \begin{itemize} | \begin{itemize} | ||||||
| \item Die Bourne-\index{Bourne-Shell|textbf}\index{Shell>Bourne-|see{Bourne-Shell}} oder Standard-Shell\index{Shell>Standard-|see{Bourne-Shell}}\index{Standard-Shell|see{Bourne-Shell}} (\texttt{sh}\index{sh=\texttt{sh}|see{Bourne-Shell}}) ist die kompakteste und einfachste Form. Sie bietet schon Mechanismen wie die Umlenkung der Ein- oder Ausgaben, Wildcards zur Abk<62>rzung von Dateinamen, Shell-Variablen und einen Satz interner Befehle zum Schreiben von Shell-Prozeduren. Neuere Versionen beherrschen auch das Job-Controlling\index{Job-Controlling}. F<>r die Entwicklung von Shell-Skripten sollte man sich auf diese Shell beschr<68>nken, da sie auf praktisch allen Systemen zur Verf<72>gung steht. So bleiben die Skripte portabel. | \item Die | ||||||
|  | Bourne-\index{Bourne-Shell|textbf}\index{Shell>Bourne-|see{Bourne-Shell}} oder | ||||||
|  | Standard-Shell\index{Shell>Standard-|see{Bourne-Shell}}\index{Standard-Shell|see{Bourne-Shell}} | ||||||
|  | (\texttt{sh}\index{sh=\texttt{sh}|see{Bourne-Shell}}) ist die kompakteste und | ||||||
|  | einfachste Form. Sie bietet schon Mechanismen wie die Umlenkung der Ein- oder | ||||||
|  | Ausgaben, Wildcards zur Abk<62>rzung von Dateinamen, Shell-Variablen und einen | ||||||
|  | Satz interner Befehle zum Schreiben von Shell-Prozeduren. Neuere Versionen | ||||||
|  | beherrschen auch das Job-Controlling\index{Job-Controlling}. | ||||||
|  |  | ||||||
| \item Die Korn-Shell\index{Korn-Shell|textbf}\index{Shell>Korn-|see{Korn-Shell}} (\texttt{ksh}\index{ksh=\texttt{ksh}|see{Korn-Shell}}), eine Weiterentwicklung der Bourne-Shell, erlaubt das editieren in der Befehlszeile. Au<41>erdem gibt es hier History\index{History}-Funktionen\footnote{History-Funktionen erm<72>glichen es dem Benutzer, einfach auf zur<75>ckliegende Befehle zur<75>ckgreifen zu k<>nnen.}, eine Ganzzahl-Arithmetik, verbesserte M<>glichkeiten zur Mustererkennung, Aliase\index{Aliase}\footnote{Ein Alias ist eine Abk<62>rzung f<>r einen Befehl. Beispielsweise kann man das H<>ufig benutzte \texttt{ls -la} einfach durch \texttt{la} ersetzen.} und das Job-Controlling\footnote{Unter Job-Controlling versteht man einen Mechanismus, mit dessen Hilfe der Benutzer die Ausf<73>hrung von Prozessen selektiv stoppen oder fortsetzen kann}\index{Job-Controlling}. Au<41>erdem bietet die Korn-Shell im Gegensatz zu fast allen anderen Shells die M<>glichkeit, Aliase und Shell-Funktionen an Subshells zu vererben. | F<EFBFBD>r die Entwicklung von Shell-Skripten sollte man sich auf diese Shell | ||||||
|  | beschr<EFBFBD>nken, da sie auf praktisch allen Systemen zur Verf<72>gung steht. So | ||||||
|  | bleiben die Skripte mit kleinen Einschr<68>nkungen\footnote{Die verschiedenen | ||||||
|  | Implementierungen weisen kleine Unterschiede, z. B. bei der Behandlung von \$@ | ||||||
|  | oder den Parametern von \texttt{read} (-r) auf.} portabel. | ||||||
|  |  | ||||||
| \item Die C-Shell \index{C-Shell|textbf}\index{Shell>C-|see{C-Shell}} (\texttt{csh}\index{csh=\texttt{csh}|see{C-Shell}}) bietet <20>hnliche Annehmlichkeiten wie die Korn-Shell, lehnt sich aber in der Syntax sehr stark an die Programmiersprache C an. Sie sollte nach M<>glichkeit nicht zur Shell-Programmierung benutzt werden, da sie an vielen Stellen nicht so reagiert, wie man es erwarten sollte. | \item Die | ||||||
|  | Korn-Shell\index{Korn-Shell|textbf}\index{Shell>Korn-|see{Korn-Shell}} | ||||||
|  | (\texttt{ksh}\index{ksh=\texttt{ksh}|see{Korn-Shell}}), eine Weiterentwicklung | ||||||
|  | der Bourne-Shell, erlaubt das Editieren in der Befehlszeile. Au<41>erdem gibt es | ||||||
|  | hier History\index{History}-Funktionen\footnote{History-Funktionen erm<72>glichen | ||||||
|  | es dem Benutzer, einfach auf zur<75>ckliegende Befehle zur<75>ckgreifen zu k<>nnen.}, | ||||||
|  | eine Ganzzahl-Arithmetik, verbesserte M<>glichkeiten zur Mustererkennung, | ||||||
|  | Arrays, Aliase\index{Aliase}\footnote{Ein Alias ist eine Abk<62>rzung f<>r einen | ||||||
|  | Befehl.  Beispielsweise kann man das H<>ufig benutzte \texttt{ls -la} einfach | ||||||
|  | durch \texttt{la} ersetzen.} und das Job-Controlling\footnote{Unter | ||||||
|  | Job-Controlling versteht man einen Mechanismus, mit dessen Hilfe der Benutzer | ||||||
|  | die Ausf<73>hrung von Prozessen selektiv stoppen oder fortsetzen | ||||||
|  | kann}\index{Job-Controlling}.  Au<41>erdem bietet die Korn-Shell im Gegensatz zu | ||||||
|  | fast allen anderen Shells die M<>glichkeit, Aliase und Shell-Funktionen an | ||||||
|  | Subshells zu vererben. | ||||||
|  |  | ||||||
|  | Die Korn-Shell existiert in verschiedenen Implementierungen, sowohl kommerziell | ||||||
|  | (ksh88), kostenlos (ksh93) als auch frei (pdksh). | ||||||
|  |  | ||||||
|  | \item Die C-Shell \index{C-Shell|textbf}\index{Shell>C-|see{C-Shell}} | ||||||
|  | (\texttt{csh}\index{csh=\texttt{csh}|see{C-Shell}}) bietet <20>hnliche | ||||||
|  | Annehmlichkeiten wie die Korn-Shell, lehnt sich aber in der Syntax sehr stark | ||||||
|  | an die Programmiersprache C an. Sie sollte nach M<>glichkeit nicht zur | ||||||
|  | Shell-Programmierung benutzt werden, da sie an vielen Stellen nicht so | ||||||
|  | reagiert, wie man es erwarten sollte. | ||||||
| \end{itemize} | \end{itemize} | ||||||
|  |  | ||||||
| \medskip\emph{Komfort-Shells:}\nopagebreak | \medskip\emph{Komfort-Shells:}\nopagebreak | ||||||
|  |  | ||||||
| \begin{itemize} | \begin{itemize} | ||||||
| \item Die Bourne-Again-Shell\index{Bourne-Again-Shell|textbf}\index{Shell>Bourne-Again-|see{Bourne-Again-Shell}}\index{Shell>Bash|see{Bourne-Again-Shell}} (\texttt{bash}\index{bash=\texttt{bash}|see{Bourne-Again-Shell}}) ist voll abw<62>rtskompatibel zur sh, bietet aber von allen Shells die komfortabelsten Funktionen f<>r das interaktive Arbeiten. Da die Bash ein GNU-Produkt ist, ist sie die Standard-Shell auf allen Linux-Systemen. Sie steht aber auch auf den meisten anderen Unixen zur Verf<72>gung. | \item Die | ||||||
| Die Bash unterst<73>tzt Auto-Completion\index{Auto-Completion|textbf}\footnote{Mit Auto-Completion ist das automatische Vervollst<73>ndigen von Dateinamen\index{Dateinamen} gemeint.}, History-Funktionen, Aliase\index{Aliase}, eine Ganzzahl-Arithmetik und indizierte Arrays\index{Array}. | Bourne-Again-Shell\index{Bourne-Again-Shell|textbf}\index{Shell>Bourne-Again-|see{Bourne-Again-Shell}}\index{Shell>Bash|see{Bourne-Again-Shell}} | ||||||
|  | (\texttt{bash}\index{bash=\texttt{bash}|see{Bourne-Again-Shell}}) ist voll | ||||||
|  | abw<EFBFBD>rtskompatibel zur sh, bietet aber von allen Shells die komfortabelsten | ||||||
|  | Funktionen f<>r das interaktive Arbeiten. Da die Bash ein GNU-Produkt ist, ist | ||||||
|  | sie die Standard-Shell auf allen Linux-Systemen. Sie steht aber auch auf den | ||||||
|  | meisten anderen Unixen zur Verf<72>gung. Die Bash unterst<73>tzt | ||||||
|  | Auto-Completion\index{Auto-Completion|textbf}\footnote{Mit Auto-Completion ist | ||||||
|  | das automatische Vervollst<73>ndigen von Dateinamen\index{Dateinamen} gemeint.}, | ||||||
|  | History-Funktionen, Aliase\index{Aliase}, eine Ganzzahl-Arithmetik und | ||||||
|  | indizierte Arrays\index{Array}. | ||||||
|  |  | ||||||
|  | \item Die | ||||||
|  | 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<72>lt sich zur | ||||||
|  | C-Shell wie die Bourne-Again-Shell zur Standard-Shell. Sie ist voll kompatibel, | ||||||
|  | bietet aber Kom\-fort-Funk\-tio\-nen wie Kom\-man\-do\-zei\-len-Edi\-tie\-rung, | ||||||
|  | programmierbare Auto-Completion\index{Auto-Completion}, | ||||||
|  | Recht\-schreib\-hil\-fen und eine History. | ||||||
|  |  | ||||||
| \item Die 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<72>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. | \item Die Z-Shell\index{Z-Shell|textbf}\index{Shell>Z-|see{Z-Shell}} | ||||||
|  | (\texttt{zsh}\index{zsh=\texttt{zsh}|see{Z-Shell}}) <20>hnelt der Korn-Shell, | ||||||
| \item Die Z-Shell\index{Z-Shell|textbf}\index{Shell>Z-|see{Z-Shell}} (\texttt{zsh}\index{zsh=\texttt{zsh}|see{Z-Shell}}) <20>hnelt der Korn-Shell, enth<74>lt aber viele Erweiterungen. Die Z-Shell unterst<73>tzt Kommandozeilen-Editing, programmierbares Auto-Completion\index{Auto-Completion}, Shell-Funktionen und eine History. Zudem ist eine Rechtschreibpr<70>fung eingebaut. | enth<EFBFBD>lt aber viele Erweiterungen. Die Z-Shell unterst<73>tzt | ||||||
| \end{itemize} | Kom\-mandozeilen-Editing, programmierbares | ||||||
|  | Auto-Completion\index{Auto-Completion}, Shell-Funktionen und eine History. | ||||||
|  | Zudem ist eine Rechtschreibpr<70>fung eingebaut.  \end{itemize} | ||||||
|  |  | ||||||
| \medskip\emph{Exoten:}\medskip\nopagebreak | \medskip\emph{Exoten:}\medskip\nopagebreak | ||||||
|  |  | ||||||
| Desweiteren gibt es noch eine Reihe weiterer Shells, die aber nur selten eingesetzt werden. Dazu geh<65>ren die \texttt{ash}\index{ash|textbf}\index{Shell>ash=\texttt{ash}|see{ash}} (Ein Bourne-Shell-Clone f<>r Rechner mit wenig Speicher.), \texttt{rc}\index{rc|textbf}\index{Shell>rc=\texttt{rc}|see{rc}} (Noch ein Bourne-Shell-Clone, urspr<70>nglich aus AT\&T Plan 9. Klein, schnell  und mit eine C-<2D>hnlichen Syntax.), \texttt{esh}\index{esh|textbf}\index{Shell>esh=\texttt{esh}|see{esh}} (Klein und schnell, bietet eine Lisp-<2D>hnliche Sprache), \texttt{sash}\index{sash|textbf}\index{Shell>sash=\texttt{sash}|see{sash}} (System Administrator's Shell - eine statisch gelinkte Shell mit integrierten Standard-Kommandos.). | Desweiteren gibt es noch eine Reihe weiterer Shells, die aber nur selten | ||||||
|  | eingesetzt werden. Dazu geh<65>ren die | ||||||
|  | \texttt{ash}\index{ash|textbf}\index{Shell>ash=\texttt{ash}|see{ash}} (Ein | ||||||
|  | Bourne-Shell-Clone f<>r Rechner mit wenig Speicher.), | ||||||
|  | \texttt{rc}\index{rc|textbf}\index{Shell>rc=\texttt{rc}|see{rc}} (Noch ein | ||||||
|  | Bourne-Shell-Clone, urspr<70>nglich aus AT\&T Plan 9. Klein, schnell  und mit eine | ||||||
|  | C-<2D>hnlichen Syntax.), | ||||||
|  | \texttt{esh}\index{esh|textbf}\index{Shell>esh=\texttt{esh}|see{esh}} (Klein | ||||||
|  | und schnell, bietet eine Lisp-<2D>hnliche Sprache), | ||||||
|  | \texttt{sash}\index{sash|textbf}\index{Shell>sash=\texttt{sash}|see{sash}} | ||||||
|  | (System Administrator's Shell - eine statisch gelinkte Shell mit integrierten | ||||||
|  | Stan\-dard-Kom\-man\-dos.). | ||||||
|  |  | ||||||
| Diese Liste ist bei weitem nicht vollst<73>ndig. | Diese Liste ist bei weitem nicht vollst<73>ndig. | ||||||
|   | |||||||
							
								
								
									
										1927
									
								
								werkzeugkasten.tex
									
									
									
									
									
								
							
							
						
						
									
										1927
									
								
								werkzeugkasten.tex
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,11 +1,12 @@ | |||||||
|  | % $Id$ | ||||||
| \chapter{Wo sind Unterschiede zu DOS-Batchdateien?}\index{DOS|(textbf}\index{Batchdateien|(textbf} | \chapter{Wo sind Unterschiede zu DOS-Batchdateien?}\index{DOS|(textbf}\index{Batchdateien|(textbf} | ||||||
|  |  | ||||||
| Unter DOS werden Batchdateien oft dazu benutzt, lange Kommandos abzuk<75>rzen um | Unter DOS werden Batchdateien oft dazu benutzt, lange Kommandos abzuk<75>rzen um | ||||||
| die Tipparbeit zu vermindern, oder um sich das Merken von vielen Parametern zu | die Tipparbeit zu vermindern, oder um sich das Merken von vielen Parametern zu | ||||||
| ersparen. Diese Aufgabe <20>berl<72><6C>t man unter Unix am besten den | ersparen. Diese Aufgabe <20>berl<72><6C>t man unter Unix am besten den | ||||||
| Shell-Aliasen\index{Aliase} oder Shell-Funktionen.\bigskip | Shell-Aliasen\index{Aliase} oder Shell-Funktionen. | ||||||
|  |  | ||||||
| Shell-Skripte k<>nnen viel mehr als Batchdateien.\bigskip | Shell-Skripte k<>nnen viel mehr als Batchdateien. | ||||||
|  |  | ||||||
| Wie der Name schon sagt, sind Batchdateien im Wesentlichen nur ein `Stapel' von | Wie der Name schon sagt, sind Batchdateien im Wesentlichen nur ein `Stapel' von | ||||||
| Anweisungen, die nacheinander ausgef<65>hrt werden. Es stehen zwar auch einige | Anweisungen, die nacheinander ausgef<65>hrt werden. Es stehen zwar auch einige | ||||||
| @@ -23,8 +24,8 @@ DOS keine M | |||||||
| erste Kommando vollst<73>ndig ausgef<65>hrt, seine Ausgabe in eine tempor<6F>re Datei | erste Kommando vollst<73>ndig ausgef<65>hrt, seine Ausgabe in eine tempor<6F>re Datei | ||||||
| geschrieben und danach als Eingabe f<>r das zweite Kommando benutzt. Da<44> so ein | geschrieben und danach als Eingabe f<>r das zweite Kommando benutzt. Da<44> so ein | ||||||
| Verhalten unter Umst<73>nden schnell zu einer vollen Festplatte f<>hren kann, sieht | Verhalten unter Umst<73>nden schnell zu einer vollen Festplatte f<>hren kann, sieht | ||||||
| man bei dem Beispiel, in dem eine CD kopiert werden soll (Kapitel \ref{cdrdao}, | man bei dem Beispiel in Abschnitt \ref{cdrdao}, in dem eine CD kopiert werden | ||||||
| Seite \pageref{cdrdao}). | soll. | ||||||
|  |  | ||||||
| Shell-Skripte kann man dagegen eher mit einer `richtigen' Programmiersprache | Shell-Skripte kann man dagegen eher mit einer `richtigen' Programmiersprache | ||||||
| vergleichen. Es stehen alle Konstrukte zur Verf<72>gung, die eine | vergleichen. Es stehen alle Konstrukte zur Verf<72>gung, die eine | ||||||
|   | |||||||
| @@ -1,5 +1,18 @@ | |||||||
|  | % $Id$ | ||||||
| \chapter{Wof<EFBFBD>r Shell-Programmierung?} | \chapter{Wof<EFBFBD>r Shell-Programmierung?} | ||||||
|  |  | ||||||
|  | Nat<EFBFBD>rlich stellt sich die Frage, in welchen Situationen ein Shell-Skript der | ||||||
|  | richtige Weg ist, und wann man vielleicht doch besser zu einer interpretierten | ||||||
|  | oder compilierten Sprache greift. | ||||||
|  |  | ||||||
|  | \section{Wof<EFBFBD>r?} | ||||||
|  |  | ||||||
|  | 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 | ||||||
| @@ -16,3 +29,19 @@ Befehlen ausf | |||||||
| Beispiel eine Audio-CD kopieren soll, sollte das Brennprogramm nur dann | Beispiel eine Audio-CD kopieren soll, sollte das Brennprogramm nur dann | ||||||
| aufrufen, wenn der Einlesevorgang erfolgreich abgeschlossen wurde. | aufrufen, wenn der Einlesevorgang erfolgreich abgeschlossen wurde. | ||||||
|  |  | ||||||
|  | \section{Wof<EFBFBD>r nicht?} | ||||||
|  |  | ||||||
|  | Ein Shell-Skript besteht aus einer Abfolge von System-Tool-Aufrufen. Das hei<65>t, | ||||||
|  | f<EFBFBD>r jeden Schritt in einem Skript wird ein neuer Proze<7A> gestartet. Das kostet | ||||||
|  | eine Menge Systemzeit, die Skripte laufen also vergleichsweise langsam. F<>r | ||||||
|  | komplexe, zeitkritische oder langwierige Aufgaben sollte man also besser zu | ||||||
|  | Perl, Python oder in Extremf<6D>llen zu C / C++ greifen. | ||||||
|  |  | ||||||
|  | Shell-Skripte k<>nnen als imperativ angesehen werden, f<>r viele Aufgaben ist | ||||||
|  | aber ein objektorientierter Ansatz wesentlich geeigneter. Auch hier ist also | ||||||
|  | der Griff zu einer anderen Sprache angeraten. | ||||||
|  |  | ||||||
|  | Es gibt zwar ein paar Tools\footnote{Zum Beispiel dialog im Textmodus, oder | ||||||
|  | xmessage unter X.}, mit denen auch Shell-Skripte eine grafische oder | ||||||
|  | textorientierte Benutzeroberfl<66>che (GUI) bekommen k<>nnen, aber das ist trotzdem | ||||||
|  | nicht das nat<61>rliche Terrain der Shell-Programmierung. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user