/[glms]/glms/server.tex
ViewVC logotype

Diff of /glms/server.tex

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.22 by GuruGeert, Tue Mar 18 16:07:29 2003 UTC revision 1.23 by gazza, Wed Mar 19 14:50:46 2003 UTC
# Line 839  In de praktijk gebruiken we het vooral z Line 839  In de praktijk gebruiken we het vooral z
839  \file{.deb} bestand afgehaald hebben, dat we dan kunnen installeren met  \file{.deb} bestand afgehaald hebben, dat we dan kunnen installeren met
840  \begin{center}\commando{dpkg -i blabla.deb}\end{center}  \begin{center}\commando{dpkg -i blabla.deb}\end{center}
841    
842  \chapter{De shell}  \chapter{DHCP}
843  \label{bash}  \index{DHCP}%
844    DHCP staat voor Dynamic Host Configuration Protocol en zoals de naam al een beetje
845  \citaatnnn{How many Unix hacks does it take to change a light bulb?\\  aangeeft wordt dit protocol gebruikt om computers dynamisch te configureren:
846  Let's see, can you use a shell script for that or does it need a C program?}  de DHCP-clients vragen aan de DHCP-server welke configuratie-instellingen ze moeten
847    gebruiken. We kunnen de DHCP-server bijvoorbeeld IP-adressen en hostnamen laten
848  \section{Inloggen, een shell kiezen}  ``uitdelen'' aan de computers op het netwerk, zodat de configuratie centraal kan gebeuren.
849    Deze aanpak spaart ook een hoop vervelend werk uit bij het configureren van de computers
850  Wanneer een gebruiker op een systeem inlogt (zie \ref{basiscommandos})  op het netwerk: instellingen zoals netmasker, domeinnaam, nameserver,~\ldots hoeven
851  wordt zijn identiteit gecontroleerd door middel van een password.  Na  we nu maar \'e\'en keer te doen (op de DHCP server) in plaats van op elke computer apart.
 het inloggen wordt een proces gestart dat een uitvoerbaar bestand (zie  
 \ref{chmod}) ge\"assoc\"\i eerd met de gebruiker uitvoert.  Het  
 bestand dat uitgevoerd wordt is afhankelijk van het systeem, maar is  
 gebaseerd op de inhoud van \file{/etc/passwd}.  
   
 Een stukje uit \file{/etc/passwd}:  
   
 \input{server/passwd}  
   
 Normaal gezien is dit uitvoerbaar bestand het \begrip{shell} programma  
 dat commando's interactief inleest van de gebruiker en ze uitvoert.  
   
 Merk op dat de shell geen deel uit maakt van het besturingssysteem;  
 het is perfect mogelijk (en dit wordt vaak gedaan) om een ander  
 programma in \file{/etc/passwd} in te vullen.  Bijvoorbeeld, men zou  
 een gebruiker ``date'' kunnen defini\"eren ge\"associ\"eerd met het  
 programma \com{/usr/bin/date}.  Elke keer dat ``date'' inlogt zal het  
 programma \com{/usr/bin/date} gestart worden.  Interessanter is dat we  
 hierdoor een beperkte shell kunnen opgeven aan een gebruiker zoals  
 \com{/bin/false} waardoor een gebruiker niet kan inloggen.  
   
 In dit hoofdstuk geven we een introductie tot een van de meest  
 gebruikte shell programma's: \begrip{Bash} (\begrip{Bourne again  
   shell}\footnote{Bourne is de ontwikkelaar van de oude ``Bourne  
   shell'' \file{/bin/sh} (dat nog veel gebruikt wordt voor shell  
   scripts en beschikbaar is op iedere \unix)})  
   
 Na wat ervaring opgedaan te hebben met bash merken we heel vlug dat  
 het gebruik van de command-line resulteert in een hogere  
 productiviteit dan als we de zogenaamde GUI's zouden gebruiken.  Dit  
 is niet verrassend als men vergelijkt hoeveel moeite er nodig is om  
 iets in te tikken tegenover het voortdurend slepen en klikken met de  
 muis\footnote{Natuurlijk veronderstelt het gebruik van de shell iets  
   meer kennis van het systeem.}.  
   
 \section{Basis bash}  
852    
853  Het gedrag van de shell kan het best begrepen worden met de volgende pseudocode:  \section{Installatie}
854    Installeren van de DHCP daemon gaat simpelweg met
855    \begin{center}\commando{apt-get install dhcp}\end{center}
856    
857  \begin{verbatim}  \section{Configuratie}
858  while(true){  \subsection{Statische configuratie}
859    bool background = false;  De DHCP daemon {\tt dhcpd} wordt geconfigureerd in het bestand \file{/etc/dhcpd.conf},
860    show promt on screen # if interactive  dat er zo zou kunnen uitzien:\\
861    read a command line from input  {\small\tt option domain-name "schrootnet";\qquad\textit{\# Domeinnaam}
862    if (the command line consists of <eof> only)  option domain-name-servers 157.193.53.8;\qquad\textit{\# IP adres van de nameserver(s)}
863      exit  \strut\\\
864    if (the command line ends with '&')  option subnet-mask 255.255.255.0;\qquad\textit{\# subnet masker}\\
865      background = true  option routers 10.1.1.1;\qquad\textit{\# gateway}\\
866    perform substitutions and  default-lease-time 600;\qquad\textit{\# clients krijgen normaal instellingen voor 10~min}\\
867      split command line into words #details later  max-lease-time 7200;\qquad\textit{\# clients kunnen tot 120 minuten instellingen houden}\\
868    find an executable file F that corresponds to  \strut\\
869      the first word (taking \$PATH into account)  subnet 10.1.1.0 netmask 255.255.255.0 \{\qquad\textit{\# instellingen voor subnet 10.1.1.x}\\
870    create a new child process and let it  \strut\qquad server-name "10.1.1.1";\qquad\textit{\# naam van onze DHCP server}\\
871      exec(F, path-of-F, 2nd word, 3rd word, ...)  \strut\qquad option subnet-mask 255.255.255.0;\\
872    if (not background)  \strut \qquad host xterm1 \{\qquad\textit{\# instellingen voor computer "xterm1"}\\
873      wait for the child process to finish  \strut\qquad\qquad hardware ethernet 00:00:a7:13:54:F8;\\
874    \strut\qquad\qquad fixed-address 10.1.1.2;\qquad\textit{\# "xterm1" krijgt altijd dit IP adres}\\
875    \strut\qquad\qquad option host-name "xterm1";\\
876    \strut\qquad \}\\
877    \strut \qquad host pcklas01 \{\qquad\textit{\# instellingen voor computer "pcklas01"}\\
878    \strut\qquad\qquad hardware ethernet 00:00:a4:4d:54:9f;\\
879    \strut\qquad\qquad fixed-address 10.1.1.3;\qquad\textit{\# "pcklas01" krijgt altijd dit IP adres}\\
880    \strut\qquad\qquad option host-name "pcklas01";\\
881    \strut\qquad \}\\
882    \strut\qquad\textit{\# enzovoort, voor elke computer van het netwerk}\\
883    \}\\
884  }  }
 \end{verbatim}  
   
 Zodat ieder commando van de vorm \com{command parameter$_1$ ...  
   parameter$_n$} zal resulteren in een nieuw proces dat \com{command}  
 uitvoert met parameter$_1$ tot parameter$_n$.  Dus, als \com{command}  
 een gecompileerd C programma is zal zijn \com{main} functie  
 aangeroepen worden als \com{main(n+1,argv,envp)} dat dan uitgevoerd zal worden.  
   
 \section{PATH}  
   
 We hebben reeds gezien (\ref{sec:verschdirs}) dat de meeste  
 programma's zich in \file{/usr/} en \file{/bin/} bevinden.  Het zou  
 dus heel ineffici\"ent zijn om telkens het volledige \begrip{PATH} op  
 te geven. B.v. \com{/usr/bin/less /etc/passwd} telkens intikken kost  
 veel tijd.  Gelukkig gebruikt de shell een PATH environment variabele  
 om de volledige padnaam te construeren.  De waarde van PATH is een  
 lijst van directories gescheiden door dubbele punten (:).  Als een  
 ingegeven commando geen volledig of relatief pad bevat wordt er in die  
 directories gekeken naar dat commando.    
   
 Meestal ziet het PATH environment variabele als  
 \com{.:/bin:/usr/bin:/usr/local/bin} uit. Dus \com{less /etc/passwd} heeft  
 hetzelfde als daarjuist.  
   
 Het is interessant in te zien dat als de huidige directory (``.'')  
 zich niet in het PATH bevindt een programma dat zich in de huidige  
 directory bevindt niet zal uitgevoerd worden. We kunnen dan de huidige  
 directory (``.'') aan ons PATH toevoegen of het programma  
 \file{mijnprogramma} uitvoeren met \com{./mijnprogramma}.  
   
 We kunnen het PATH environment variabele bekijken door \com{echo  
   \$PATH} in te tikken.  Eveneens kunnen we het PATH aanpassen door  
 \com{export PATH=/lijst/van:/directories} op te geven.  Wanneer we het  
 ingestelde PATH willen uitbreiden kunnen we \com{export  
   PATH=\$PATH:/lijst/van:/directories} in geven.  
   
 \begin{opgave}  
 Bestudeer je huidige PATH en pas het aan.  
 \end{opgave}  
   
 Merk op dat wanneer we ons PATH zo veranderen deze wijziging geldt  
 voor deze shell sessie.  Loggen we uit en terug in dan is de wijziging  
 verdwenen.  In \ref{startup} zien we hoe we de wijziging vastleggen.  
   
 \section{Achtergrond processen}  
   
 In \ref{bgjobs} hebben we reeds hierover gesproken.  We geven een heel  
 korte samenvatting.  Door een \begrip{\&} na een commando te plaatsen  
 voeren we het commando uit in de achtergrond.  Met \com{fg} plaatsen  
 we het dan terug op de voorgrond.  
   
 \section{History}  
   
 Bash houdt een lijst bij van de reeds ingegeven processen, de  
 \begrip{history}.  
   
 \begin{opgave}  
 Tik de naar boven en naar beneden pijtjes toetsen in.  
 \end{opgave}  
885    
886  De reeds ingegeven commando's kunnen we dan bekijken en opnieuw  Met het commando \commando{/etc/init.d/dhcp restart} herstarten we de DHCP deamon
887  uitvoeren of aanpassen.  zodat die onze gewijzigde instellingen overneemt.
   
 \section{I/O redirection}  
   
 Zoals we in \ref{ioredirection} reeds zagen kunnen we de uitvoer van  
 en de invoer naar een programma omleiden.  We introduceren nog extra  
 begrip: \begrip{/dev/null}.  
   
 \file{/dev/null} kan als de vergeetput aanzien worden.  Alles wat we  
 naar \file{/dev/null} omleiden zien we nooit meer terug.  Tikken we  
 \com{cat /etc/passwd $>$ /dev/null} in dan zien we geen output.  Voor  
 zulke toepassingen is dit niet zo interessant, maar wat als we een  
 proces hebben dat foutmeldingen geeft waar we niet ge\"\i nteresseerd  
 in zijn?  
   
 We kunnen dan \begrip{2$>$} gebruiken: \com{programma 2$>$/dev/null}  
 stuurt alle foutmeldingen dat \file{programma} op het scherm zet naar  
 \file{/dev/null}.  
   
 \section{Bash opstart bestanden}  
 \label{startup}  
 Elke shell heeft een aantal initialisatie-bestanden. Dit wil zeggen,  
 bestanden met shell-bevelen die altijd uitgevoerd worden wanneer de  
 gebruiker een nieuwe shell start. Typisch zijn de namen van die  
 initialisatie-bestanden gevormd uit de naam van de shell met  
 daarachter ``\file{rc}'' (wat oorspronkelijk stond voor ``resource  
 configuration''). Zo heeft een typische \gl-installatie voor de bash  
 shell de bestanden \file{/etc/bash.bashrc} (voor ``system wide''  
 initialisatie) en een verborgen bestand \file{.bashrc} in de home  
 directory van elke gebruiker. Het system wide initialisatie-bestand  
 wordt eerst uitgevoerd, en daarna de \file{.bashrc} van de gebruiker.  
   
 \section{Aliases}\label{sec:alias}  
   
 Gebruikers kunnen (reeksen van) bevelen die ze vaak gebruiken afkorten  
 met het \begrip{alias} bevel. (En opslaan in hun \file{.bashrc}.)  Een  
 voorbeeld is \com{alias ll=''ls -l''}.  Als dit bevel is uitgevoerd  
 levert \com{ll} hetzelfde resultaat als \com{ls -l} voordien.  
   
 Om het aantal alias-definities in het bestand \file{.login} te tellen  
 kunnen we het volgende bevel uitvoeren: \com{cat .login $\mid$ grep  
   alias $\mid$ wc -l}.  Het eerste bevel toont het bestand met  
 omgevingsvariabelen.  Op dit resultaat wordt dan het \com{grep} bevel  
 toegepast.  Dit bevel weerhoudt alleen de lijnen waarin het woord  
 ``alias'' voorkomt.  Tenslotte telt \com{wc} (word count) het aantal  
 lijnen (dankzij de optie -l).  Het resultaat van de hele regel is dus  
 het aantal aliases dat in .login is gedefini\"eerd.  Als we met bash  
 werken moeten we het bestand \file{.bashrc} doorzoeken in plaats van  
 \file{.login}.  
   
 In dit bestand kunnen we ook onze PATH plaatsen.  Wat volgt is een  
 voorbeeld \file{.bashrc} bestand.  
   
 \begin{verbatim}  
 # ~/.bashrc: executed by bash(1) for non-login shells.  
 # see /usr/share/doc/bash/examples/startup-files for examples  
   
 # If running interactively, then:  
 if [ "$PS1" ]; then  
   
     # enable color support of ls and also add handy aliases  
   
     eval `dircolors`  
     alias ls='ls --color=auto '  
     alias ll='ls -l'  
     alias la='ls -A'  
     alias l='ls -CF'  
     alias dir='ls --color=auto --format=vertical'  
     alias vdir='ls --color=auto --format=long'  
   
 fi  
 mesg y  
 export TERM=linux  
 export EDITOR=emacs  
 export RTF2LATEX2E_DIR=/usr/local/rtf2latex2e  
 alias eduserv='ssh rgevaert@eduserv1.rug.ac.be'  
 alias lugwv='/usr/bin/BitchX -c \#lugwv webworm irc.chat.be'  
 alias tinnr='tin -nr'  
 alias tin='tin -r'  
 IRCNICK=webworm  
 IRCUSER=riper  
 IRCNAME="http://www.webworm.org"  
 IRCSERVER=irc.chat.be  
 export IRCNICK IRCUSER IRCNAME IRCSERVER  
 alias afsluiten='sudo /sbin/shutdown -h now'  
 #fetchmail -d 200 2> /dev/null  
 PATH=$PATH:$HOME/bin:.:/usr/local/jdk1.3.1/bin  
 \end{verbatim}  
   
 \section{Programmeren in de shell}  
   
 De shell geeft niet alleen bevelen door aan het besturingssysteem,  
 maar kan ook \begrip{shell scripts} interpreteren en uitvoeren.  Een  
 shell script is een bestand dat een aantal shell bevelen bevat.  Het  
 bestand is uitvoerbaar gemaakt (zie \ref{chmod}), en zijn eerste regel  
 geeft aan welke shell het bestand moet interpreteren.    
   
 Deze eerste regel is eigenlijk een commentaar-lijn, en begint met het  
 commentaar-teken (\#), gevolgd door een uitroepteken, en het volledige  
 pad van het shell-programma.  Bijvoorbeeld: \verb~#!/bin/sh~ is de  
 eerste lijn van alle voorbeelden en oefeningen van deze cursus, en ze  
 zegt dat de Bourne shell de interpreter is van het script.  
   
 Dit tekstbestand kan op twee manieren worden uitgevoerd:  
 \begin{enumerate}  
 \item Duid expliciet de interpreter van het bestand aan: \com{/bin/sh  
     scriptname}.  
 \item Laat het bestand interpreteren door de huidige shell: \file{  
     ./scriptname}.  Hiervoor moet het script eerst uitvoerbaar gemaakt  
   worden met behulp van \com{chmod}.  
 \end{enumerate}  
   
 \section{Variabelen}  
   
 Zoals de meeste talen kent ook shell scripting variabelen.  En zoals  
 in de meeste ge\"{\i}nterpreteerde talen hebben shell variabelen geen  
 expliciet aangegeven type.  Een nieuwe variabele wordt aangemaakt door  
 een nieuwe naam te gebruiken.  Daarom is het bij scripting zeer  
 belangrijk om het script op fouten te controleren.  
 Enkele voorbeelden zijn.\\  
 \hspace{3cm} \texttt{aantal=5}\\  
 \hspace{3cm} \texttt{voornaam=Rudy}\\  
 \hspace{3cm} \texttt{achternaam=Gevaert}\\  
 Het is zeer belangrijk dat er voor en na = geen spaties worden  
 geplaatst, anders weet de shell niet hoe het commando moet worden  
 ge\"{i}nterpreteerd. De waarde van een variabele wordt opgevraagd  
 door er een dollarteken (\$) voor te plaatsen.  Vb:\\  
 \begin{verbatim}  
 naam="$voornaam $achternaam"  
 \end{verbatim}  
 ~\\  
 Het \com{echo} bevel schrijft de waarde op het scherm. Ook hier  
 gebruiken we het dollarteken:\\  
 \begin{tabbing}  
 \com{echo naam}\hspace{3cm}\=  resultaat: {\tt naam}\\  
 \com{echo \$naam}\> resultaat: {\tt Rudy Gevaert}\\  
 \end{tabbing}  
 ~\\  
   
 Anderzijds leest het \com{read} bevel een waarde in, zie het voorbeeld  
 in \ref{readvar}.  
   
 \begin{figure}  
 \begin{verbatim}  
 #!/bin/sh  
 eentekst="Shell programmeren is fijn"  
 echo $eentekst  
 echo "Typ nu zelf een regel in"  
 read eentekst  
 echo $eentekst  
 \end{verbatim}  
 \caption{}  
 \label{readvar}  
 \end{figure}  
   
 Dit voorbeeldje laat zien hoe de variabele \com {eentekst} eerst een  
 initi\"ele waarde krijgt, en hoe die in de volgende stap uitgeschreven  
 wordt. Daarna wordt er gevraagd om zelf een regel in te typen; die  
 wordt ingelezen in de variabele \file{eentekst} en daarna  
 uitgeschreven. Een ander voorbeeldje vinden we in \ref{readvar2}  
   
 \begin{figure}  
 \begin{verbatim}  
 #!/bin/sh  
 echo "geef je voor- en achternaam, gevolgd door je universiteit,"  
 echo "je richting en je hobbies"  
 read voornaam achternaam universiteit richting hobbies  
 echo "voornaam: $voornaam"  
 echo "achternaam: $achternaam"  
 echo "universiteit: $universiteit"  
 echo "richting: $richting"  
 echo "hobbies: $hobbies"  
 \end{verbatim}  
 \caption{}  
 \label{readvar2}  
 \end{figure}  
   
 Als we bij het programma voorgesteld in \ref{readvar2} de invoer  
 ``\com{Rudy Gevaert RUG informatica Savannah moderator}'' intypen  
 zullen we de volgende uitvoer bekomen:  
   
 \begin{verbatim}  
 voornaam: Rudy  
 achternaam: Gevaert  
 universiteit: RUG  
 richting: informatica  
 hobbies: Savannah moderator  
 \end{verbatim}  
   
   
 De \gl\ shells kennen ook een reeks ingebouwde variabelen,  
 waarvan de waarde kan worden opgevraagd.\\  
   
 \begin{tabbing}  
 \texttt{\$\#}\hspace{1cm} \= Het aantal argumenten dat aan het script is meegegeven.\\  
 \texttt{\$?} \> De exit waarde van het commando dat het laatste is uitgevoerd.\\  
 \texttt{\$0} \> De naam van het shell script (dit is impliciet het eerste argument).\\  
 \texttt{\$*} \> De positionele parameters \$1, \$2,\ldots die de parameters bevatten.\\  
              \> Vervang * door het gewenste parameter nummer.\\  
 \texttt{\$@} \> De volledige lijst van parameters (een ``array'' van alle argumenten).\\  
 \texttt{\$\$} \> Het ID van het huidige proces.\\  
 % \texttt{\$LOGNAME}\>De login naam van de huidige gebruiker.\\  
 \end{tabbing}  
   
 Deze ingebouwde variabelen kunnen gebruikt worden in shell scripts,  
 zoals getoond in figuur \ref{ingebvar}.  
   
 \begin{figure}  
 \begin{verbatim}  
 #!/bin/sh  
 echo the name for this script is $0 and it has $# arguments  
 echo the first argument of this script is $1  
 echo the fifth argument of this script is $5  
 \end{verbatim}  
 \caption{}  
 \label{ingebvar}  
 \end{figure}  
   
 Nu kunnen we desgewenst ook argumenten meegeven als we shell scripts  
 gaan schrijven.  
   
 \section{Speciale karakters}  
   
 Elke shell heeft een reeks van speciale karakters.  Deze paragraaf  
 bespreekt er vier belangrijke: double quotes ("), single quotes  
 (\com{''}), back slash (\textbackslash) en back tick (\com{`}).  
   
 Double quotes worden gebruikt om een string die spaties bevat uit te  
 schrijven of toe te kennen aan een variabele.  Als de double quotes  
 worden weggelaten, interpreteert de shell ieder woord als een nieuw  
 bevel.  Hierdoor zouden ernstige fouten kunnen ontstaan bij de  
 uitvoering van het script.  De waarden van variabelen worden nog  
 steeds ingevuld.  
   
 Single quotes zijn sterker dan double quotes.  Een string die tussen  
 single quotes staat wordt letterlijk ge\"{i}nterpreteerd.  Indien  
 slechts een gedeelte van een expressie letterlijk moet worden genomen,  
 dan kan men best double quotes gebruiken in combinatie met de back  
 slash.  Dit teken zorgt er namelijk voor dat het volgend teken  
 letterlijk wordt genomen.  
 Vb.:\\  
 \begin{tabbing}  
 \com{echo Hello \$LOGNAME}\hspace{3cm}\=resultaat: {\tt Hello craymaek}\\  
 \com{echo 'Hello \$LOGNAME'}\>resultaat: {\tt Hello \$LOGNAME}\\  
 \com{echo Hello \textbackslash\$LOGNAME}\>resultaat: {\tt Hello \$LOGNAME}\\  
 \end{tabbing}  
   
 Met behulp van de back tick (\com{`}) en het \com{expr} commando kan  
 het resultaat van een bewerking aan een variabele worden toegekend.  
 Dit wordt getoond in \ref{toekvar}.  
   
 \begin{figure}  
 \begin{verbatim}  
 een=1  
 twee=`expr $een + 1`  
 echo $twee  
 datum=`date`  
 echo $datum  
 \end{verbatim}  
 \caption{Variabelen en expressies}  
 \label{toekvar}  
 \end{figure}  
   
 De back tick wordt ook gebruikt om een string \Begrip{uit te voeren},  
 d.w.z., de shell interpreteert de string als een shell bevel.  
 Bijvoorbeeld, het bevel \com{info=`ls`} stelt de variabele info niet  
 gelijk aan ``ls'', maar aan de inhoud van de huidige directory.  
   
 \section{Vergelijken van expressies}  
   
 Het commando om een logische expressie te evalueren is \com{test}.  De  
 syntax is \com{test expressie}. Vaak worden vierkante haakjes gebruikt  
 in plaats van het test commando: \com{[ expressie ]}.  Het resultaat  
 is in beide gevallen hetzelfde. Tabellen \ref{tab:intexpr},  
 \ref{tab:strexpr}, \ref{tab:bestexpr} en \ref{tab:logexpr}  
 geven de verschillende expressie weer.  Enkele voorbeelden van  
 expressies zijn:  
   
 \begin{itemize}  
         \item \com{[ 5 -eq 6 ]} geeft vals  
         \item \com{[ -n lala ]} geeft waar  
         \item \com{[ -d /dev ]} geeft waar  
         \item \com{[ -f /home ]} geeft vals  
 \end{itemize}  
   
 Deze expressies komen pas helemaal tot hun recht bij conditionele expressies  
 en condities voor het uitvoeren van herhalingslussen. Dit wordt besproken  
 in de volgende secties.  
   
 \begin{table} %START 1  
 \begin{center}  
 \begin{tabular}{|l|c|}\hline  
 \textsf{Operator} & \textsf{Betekenis}\\ \hline  
 int1 -eq int2 & int1 $=$\ int2 (equal)\\ \hline  
 int1 -ge int2 & int1 $\ge$\ int2 (greater than or equal)\\ \hline  
 int1 -gt int2 & int $>$\ int2 (greater than)\\ \hline  
 int1 -le int2 & int1 $\le$\ int2 (less than or equal)\\ \hline  
 int1 -lt int2 & int1 $<$\ int2 (less than)\\ \hline  
 int1 -ne int2 & int1 $\ne$\ int2 (not equal)\\ \hline  
 \end{tabular}  
 \caption{Integer expressies}\label{tab:intexpr}  
 \end{center}  
 \end{table} % END 1  
   
 \begin{table} % START 2  
 \begin{center}  
 \begin{tabular}{|l|c|}\hline  
 \textsf{Operator} & \textsf{Betekenis}\\ \hline  
 str1 = str2 & str1 $=$\ str2 (equal)\\ \hline  
 str1 != str2 & str1 $\ne$\ str2 (not equal)\\ \hline  
 str1 & str1 is niet null\\ \hline  
 -n str1 & de lengte van str1 is groter dan 0\\ \hline  
 -z str1 & de lengte van str1 is 0\\ \hline  
 \end{tabular}  
 \caption{String expressies}\label{tab:strexpr}  
 \end{center}  
 \end{table} % END 2  
   
 \begin{table} % START 3  
 \begin{minipage}{\textwidth}  
 \begin{center}  
 \begin{tabular}{|l|c|}\hline  
 \textsf{Operator} & \textsf{Betekenis}\\ \hline  
 -d \sl{bestandsnaam} & bestand (\sl{bestandsnaam})is een directory  
 \footnote{in UNIX is een directory in weze ook een bestand} \\ \hline  
 -f \sl{bestandsnaam} & bestand is een gewone file\\ \hline  
 -r \sl{bestandsnaam} & bestand kan worden gelezen door het proces\\ \hline  
 -s \sl{bestandsnaam} & bestand heeft een lengte groter dan 0\\ \hline  
 -w \sl{bestandsnaam} & bestand kan worden beschreven door het proces\\ \hline  
 -x \sl{bestandsnaam} & bestand kan worden uitgevoerd door het proces\\ \hline  
 -e \sl{bestandsnaam} & bestand bestaat\\ \hline  
 \end{tabular}  
 \end{center}  
 \end{minipage}  
 \caption{Bestand expressies}\label{tab:bestexpr}  
 \end{table} % END 3  
   
 \begin{table} % START 4  
 \begin{center}  
 \begin{tabular}{|l|c|}\hline  
 \textsf{Operator} & \textsf{Betekenis}\\ \hline  
 ! expr1 & Negatie van expr1\\ \hline  
 expr1 -a expr2 & expr1 en expr2\\ \hline  
 expr1 -o expr2 & expr1 of expr2\\ \hline  
 \end{tabular}  
 \caption{Logische expressies}\label{tab:logexpr}  
 \end{center}  
 \end{table} %END 4  
   
 \section{Conditionele expressies}  
 De Bourne shell kent twee conditionele expressies: \com{if} en  
 \com{case}.  De syntax van de if expressie is:  
   
 \begin{verbatim}  
 if [ expressie ]  
 then  
         statements  
 elif [ expressie ]  
 then  
         statements  
 else  
         statements  
 fi  
 \end{verbatim}  
 \bigskip  
   
 Een voorbeeldje van het gebruik van een if-statement in een shell  
 script vinden we in \ref{lst:ifvb}.  
   
 \begin{figure}  
 \begin{verbatim}  
 if [ $var = "Yes" ]  
 then  
         echo "Value is Yes"  
 elif [ $var  = "No" ]  
 then  
         echo "Value is No"  
 else  
         echo "Invalid value"  
 fi  
 \end{verbatim}  
 \caption{Conditionele expressies}  
 \label{lst:ifvb}  
 \end{figure}  
   
 \bigskip  
 \bigskip  
   
 De case expressie is vergelijkbaar met het switch bevel van C.  De  
 syntax is beschreven in \ref{lst:casesyntax}.  
   
 \begin{figure}  
 \begin{verbatim}  
 case word in  
         str1)  
                 statements;;  
         str2 | str3)  
                 statements;;  
         *)  
                 statements;;  
 esac  
 \end{verbatim}  
 \caption{De syntax van case}  
 \label{lst:casesyntax}  
 \end{figure}  
   
 \bigskip  
   
 Een voorbeeldje van het gebruik van een case-expressie in een shell  
 script vinden we in \ref{lst:casevb}.  
   
 \begin{figure}  
 \begin{verbatim}  
 case $1 in  
         01 | 1) echo "Month is January";;  
         02 | 2) echo "Month is February";;  
         03 | 3) echo "Month is March";;  
         04 | 4) echo "Month is April";;  
         05 | 5) echo "Month is May";;  
         06 | 6) echo "Month is June";;  
         07 | 7) echo "Month is July";;  
         08 | 8) echo "Month is August";  
         09 | 9) echo "Month is September";;  
         10) echo "Month is October";;  
         11) echo "Month is November";;  
         12) echo "Month is December";;  
         *) echo "Invalid Parameter";;  
 esac  
 \end{verbatim}  
 \caption{Case aan het werk}  
 \label{lst:casevb}  
 \end{figure}  
   
 \bigskip  
 \bigskip  
   
 \section{Iteraties}  
   
 Een iteratie in een shell script kan op drie verschillende manieren  
 worden ge\"{i}mplementeerd: for, while en until.  
   
 \subsection{for}  
 De syntax van de for expressie is:  
   
 \begin{verbatim}  
 for var in list  
 do  
         statements  
 done  
 \end{verbatim}  
   
 \bigskip  
   
 Een voorbeeldje van het gebruik van een for expressie in een shell  
 script vinden we in \ref{lst:forvb}.  Het script in  
 \ref{lst:forvb} schrijft de huidige directory uit.  
   
 \begin{figure}  
 \begin{verbatim}  
 #!/bin/sh  
 dirlist=`ls`  
 for file in $dirlist  
 do  
         echo $file  
 done  
 \end{verbatim}  
 \caption{Klussen met for lussen}  
 \label{lst:forvb}  
 \end{figure}  
 \bigskip  
   
 Stel dat we in een directory heel wat tar.gz files staan hebben die we  
 allemaal willen decomprimeren en uitpakken, dan kunnen we daarvoor een  
 soortgelijk script schrijven. Een voorbeeldje hiervan zien we in  
 \ref{lst:forutargz}.  
   
 \begin{figure}  
 \begin{verbatim}  
 #!/bin/sh  
 for file in `ls *tar.gz`  
 do  
         tar -xvzf $file  
 done  
 \end{verbatim}  
 \caption{Eenvoudig uitpakken}  
 \label{lst:forutargz}  
 \end{figure}  
888    
889  Merk op dat \com{`ls *tar.gz`} een verzameling bestanden teruggeeft  Als alles goed is verlopen, moet de DHCP daemon draaien, hetgeen we kunnen controleren
890  waarover ge\"{i}tereerd wordt.  We kunnen in plaats van het \com{ls} bevel uit  door \commando{ps aux|grep dhcpd} te typen en te zien of er een lijn
891  te voeren, het te expanden patroon meegeven: \com{for file in  {\small\begin{verbatim}
892    *tar.gz}.  De shell zal dit dan eerst expanden tot all tar.gz files  root     29942  0.0  4.5  2172  836 ?        S    11:56   0:00 /usr/sbin/dhcpd-2.2.x -q
893  in de huidige directory.  \bigskip In feite hoeft dit helemaal niet in  \end{verbatim}}
894  een bestand gezet te worden. We zouden ook het script kunnen intypen  tussen staat.
 achter de shell prompt, waarbij we de enters vervangen door \com{;}.  
 Zo zouden we in plaats van \ref{lst:forutargz} in een bestand te plaatsen  
 ook kunnen intypen:  
895    
896  \begin{figure}  Als we twee netwerkkaarten in onze server hebben, kan het gebeuren dat we in plaats daarvan
897    de volgende foutmelding zien in \file{/var/log/daemon.log}:
898  \begin{verbatim}  \begin{verbatim}
899  for file in `ls *tar.gz`; do tar -xvzf $file ; done  No subnet declaration for eth0 (157.193.53.222).
900    Please write a subnet declaration in your dhcpd.conf file for the
901    network segment to which interface eth0 is attached.
902    exiting.
903  \end{verbatim}  \end{verbatim}
904  \end{figure}  We hebben wel informatie gegeven over wat de DHCP deamon moet doen met aanvragen
905  Dit heeft hetzelfde effect.  van de ene netwerkkaart (die op subnet 10.1.1.x) maar er hangt ook nog een andere
906    netwerkkaart (eth0, op subnet 157.193.53.x) aan onze computer. We moeten dus nog iets
907  \bigskip  toevoegen aan ons configuratiebestand:
   
 \subsection{while}  
   
 De syntax van de while expressie is:  
   
908  \begin{verbatim}  \begin{verbatim}
909  while expressie  subnet 157.193.53.222 netmask 255.255.255.0 {
910  do          not authoritative;
911          statements  }
 done  
912  \end{verbatim}  \end{verbatim}
913    Normaal gezien geeft de DHCP server aan onbekende clients een foutmelding terug
914    (``er is geen configuratie-info voor jou beschikbaar''). Maar omdat we op
915    het subnet 157.193.53.x, waar we onze internettoegang vandaan halen, helemaal niets
916    te zeggen hebben, schrijven we \texttt{not authoritative}, zodat de DHCP server
917    niets zal doen als hij ziet dat een client om informatie vraagt. Het is immers goed
918    mogelijk dat op het subnet van onze provider al een DHCP server draait, en zou het goed
919    kunnen dat onze DHCP server anders tegen andere klanten van de provider
920    zou zeggen ``er is geen configuratie voor jou beschikbaar'' en dat zal die provider niet
921    echt leuk vinden~\ldots
922    
923  \bigskip  We hebben een \texttt{default-lease-time} van 600 seconden ingesteld, zodat alle
924    computers van het netwerk om de tien minuten opnieuw hun configuratie zullen
925  Een voorbeeldje van het gebruik van een while expressie in een shell  opvragen. Als je netwerk redelijk statisch is en er niet direkt elke tien minuten computers
926  script vinden we in \ref{lst:whilevb}.  van configuratie veranderen, kan je gerust waarden als 86400 (een dag) of hoger invullen.
927    
928  \begin{figure}  \subsection{Dynamische configuratie}
929    Het is ook mogelijk dynamisch IP adressen uit te delen. Met
930  \begin{verbatim}  \begin{verbatim}
931  #!/bin/sh  range 10.1.1.100 10.1.1.200;
 i=1  
 while [ $i -le 10 ]  
 do  
         echo $i  
         i=`expr $i + 1`  
 done  
932  \end{verbatim}  \end{verbatim}
933  \caption{Voorbeeld van een while expressie}  in plaats van of tussen de \texttt{host} regels, zorg je ervoor dat voor de computers
934  \label{lst:whilevb}  die niet gekend zijn met zulke \texttt{host} regels, dynamisch IP adressen van
935  \end{figure}  10.1.1.100 tot en met 10.1.1.200 worden uitgedeeld. De DHCP server zorgt ervoor
936    dat geen twee computers hetzelfde IP krijgen. Bij dynamische IP's kan het handig zijn
937  Het script in \ref{lst:whilevb} telt tot 10 en schrijft de getallen uit.  de \texttt{default-lease-time} kort te houden (10 minuten bijvoorbeeld) zodat
938  \bigskip  IP's snel vrijkomen als een computer wordt uitgeschakeld.
 \bigskip  
   
 \section{Functies}  
   
 Scripts voor de Bourne shell kunnen ook functies bevatten. De syntax  
 is voorgesteld in \ref{lst:funcsyntax}.  
   
 \begin{figure}  
 \begin{verbatim}  
 functienaam () {  
         statements  
 }  
 \end{verbatim}{}  
 \caption{}  
 \label{lst:funcsyntax}  
 \end{figure}  
939    
940  De functie kan worden opgeroepen met de functienaam.  Ook kunnen er  Je kan statische en dynamische configuratie mengen zoals je wil, of enkel \'e\'en van de
941  parameters worden doorgegeven: \com{functienaam param1 param2 \ldots}.  twee systemen gebruiken. Een praktijkvoorbeeld van een gemengde configuratie
942  Deze parameters kunnen dan in de functie worden aangeroepen door  is alle vaste computers statisch configureren en een aantal adressen dynamisch uitdelen
943  middel van de positionele parameters (\$1, \$2, \ldots).  Een  aan laptops. Iemand die zijn laptop meebrengt krijgt dan vanzelf een eigen IP adres,
944  voorbeeldje van een functie die argument1 argument2-keer met zichzelf  terwijl de vaste computers een gekend IP adres hebben (hetgeen in geval van problemen
945  optelt (zoals een gewone vermenigvuldiging dus) vinden we in  te verkiezen kan zijn boven dynamisch uitgedeelde adressen).
 \ref{lst:funcvb}. Merk op dat de functie voor de aanroep moet  
 gedefinieerd worden.  
946    
947  \begin{figure}  \section{Configuratie van de client}
948    Tijdens het installeren van Debian werd ons al gevraagd of we automatische netwerkconfiguratie
949    wouden; hebben we hier bevestigend op geantwoord, dan is alles in orde. Zoniet
950    kunnen we ons later bedenken door in \file{/etc/network/interfaces} het stukje
951    over \texttt{eth0} te vervangen door
952  \begin{verbatim}  \begin{verbatim}
953  #!/bin/sh  iface eth0 inet dhcp
 telkeerop(){  
  result=$1  
  teller=$2  
  until [ $teller -eq  1 ]  
  do  
    result=`expr $result + $1`  
    teller=`expr $teller - 1`  
  done  
  echo $result  
 }  
   
 telkeerop 5 7  
954  \end{verbatim}  \end{verbatim}
955  \caption{Functies in een shell script}  Als de netwerkkaart voordien geen DHCP gebruikte, dan waren er waarschijnlijk een
956  \label{lst:funcvb}  aantal extra regels met netwerkinstellingen aanwezig (\texttt{address}, \texttt{netmask},~\dots)
957  \end{figure}  die je gerust mag verwijderen.
   
 \section{Scripts onderbreken}  
 Een iteratie (for, while en until) kan worden onderbroken door middel  
 van het bevel \com{break}.  Het hele script kan be\"{e}indigd worden  
 met het bevel \com{exit}.  
   
 \section{Opgaves}\label{sec:shelloef}  
   
 \begin{opgave}  
   Schrijf een script dat een reeks van bestanden aanvaardt en naar een  
   back-up directory copi\"{e}ert.  Zorg ervoor dat de copies read-only  
   zijn en maak een gezipt archive van de back-up directory.  Vergeet  
   niet om alle tijdelijke bestanden en directories op te ruimen.  
 \end{opgave}  
   
 \begin{opgave}  
   Maak een script dat een reeks van bestanden aanvaardt en voor ieder  
   bestand een functie aanroept.  Deze functie schrijft de gegevens van  
   het bestand (ls -l) en de inhoud uit.  
 \end{opgave}  
   
 \begin{opgave}  
   Schrijf een script dat een directory als parameter krijgt en de  
   inhoud per email naar de gebruiker stuurt.  Tip: bekijk de man pages  
   van \com{mail}.  
 \end{opgave}  
   
 \begin{opgave}  
   Maak een script dat een lijst van email-adressen meekrijgt en als  
   laatste argument een tekst.  Zorg ervoor dat deze tekst doorgestuurd  
   wordt naar alle email-adressen.  
 \end{opgave}  
   
 \begin{opgave}  
   Maak een script dat als argument de login van een gebruiker  
   meekrijgt en een melding op het scherm geeft wanneer dat die  
   gebruiker inlogt. Dit wil zeggen dat het script moet blijven werken  
   totdat de gebruiker inlogt, waarna het een melding geeft en dan  
   stopt. Tip: u kan hiervoor het \com{sleep} en het \com{grep}  
   commando gebruiken.  
 \end{opgave}  
   
 \begin{opgave}  
  Breid het vorige programma uit zodat je een lijst van loginnamen  
   kan meegeven om te melden.  Het script is dan bedoeld om vanaf het  
   starten ervan altijd te blijven lopen.  
 \end{opgave}  
958    
 \begin{opgave}  
   Maak een script dat als invoer shell-commando's krijgt en deze zelf  
   uitvoert, waarbij er een minimale boekhouding gedaan wordt.  Schrijf  
   de naam van het process, uitvoeringstijd en starttijd in een  
   bestand, samen met de gebruiker die het process opgestart heeft.  
   Dit programma moet altijd blijven werken. Gebruik {\tt read} voor de  
   invoer.  Zorg ervoor dat je het script kan be\"eindigen door quit in  
   te typen.  
 \end{opgave}  
959    
960  \chapter{File server}  \chapter{File server}
961  Er zijn twee populaire manieren van bestanden aanbieden via het netwerk:  Er zijn twee populaire manieren van bestanden aanbieden via het netwerk:
# Line 1722  in de directory \file{/opt/export/softwa Line 1070  in de directory \file{/opt/export/softwa
1070  Meer informatie: zie \url{http://www.samba.org/} en  Meer informatie: zie \url{http://www.samba.org/} en
1071  \url{http://www.riverdale.k12.or.us/linux/netadmin/samba.html}.  \url{http://www.riverdale.k12.or.us/linux/netadmin/samba.html}.
1072    
 \chapter{Firewall/gedeeld internet}  
 \section{Linux als gateway}  
 Internet is opgebouwd uit een groot aantal onderling verbonden kleine netwerkjes.  
 In dit voorbeeld heeft ons lokaal netwerkje IP adressen van de vorm 157.193.53.x.  
 Als we een verbinding willen leggen tussen twee lokale computers, kunnen we dat  
 rechtstreeks doen: computers in hetzelfde netwerk ``zien'' elkaar rechtstreeks.  
 Maar als we verbinding willen leggen met een computer buiten ons lokaal netwerk,  
 moeten we dat via een tussenliggende computer doen, die verbonden is met ons netwerk  
 en met het andere netwerk in kwestie. Die computer wordt \begrip{gateway} genoemd  
 en heeft dus minstens twee netwerkkaarten aan boord: \'e\'en voor ons lokaal netwerk  
 en \'e\'en voor het andere netwerk. Er kunnen ook meerdere tussenstappen nodig zijn  
 om van het ene netwerk naar het andere te gaan, zodat de pakkettjes van gateway naar  
 gateway reizen eer ze op hun bestemming aankomen. Met het \commando{traceroute}  
 commando kunnen we een beeld krijgen van dit proces:  
 {\small\begin{verbatim}  
 $ /usr/sbin/traceroute www.linux.org  
 traceroute to www.linux.org (198.182.196.56), 30 hops max, 38 byte packets  
  1  router (157.193.53.254)  2.372 ms  1.970 ms  1.011 ms  
  2  ge.m20.access.gent.giga.belnet.net (193.191.7.9)  0.991 ms  0.983 ms  0.946 ms  
  3  oc48.m160.core.science.giga.belnet.net (193.191.1.137)  1.782 ms  1.731 ms  1.759 ms  
  4  oc192.m160.ext.science.giga.belnet.net (193.191.1.2)  1.698 ms  1.777 ms  1.836 ms  
  5  gigabitethernet4-0-139.ipcolo1.Brussels1.Level3.net (212.3.234.129)  1.921 ms  1.736 ms  1.735 ms  
  6  ae0-12.mp2.Brussels1.Level3.net (212.3.239.34)  2.337 ms  2.271 ms  2.229 ms  
  7  so-3-0-0.mp2.London1.Level3.net (212.187.128.57)  6.837 ms  6.899 ms  6.864 ms  
  8  so-1-0-0.mp2.NewYork1.Level3.net (212.187.128.153)  74.793 ms  72.462 ms  74.133 ms  
  9  so-7-0-0.gar2.NewYork1.Level3.net (64.159.1.186)  73.693 ms  74.103 ms  75.606 ms  
 10  so-4-2-0.edge1.NewYork1.Level3.net (209.244.17.82)  74.372 ms  73.531 ms  73.104 ms  
 11  uunet-level3-oc48.NewYork1.Level3.net (209.244.160.182)  72.674 ms  77.773 ms  81.170 ms  
 12  0.so-6-0-0.XL1.NYC4.ALTER.NET (152.63.21.78)  73.277 ms  74.863 ms  81.496 ms  
 13  0.so-2-0-0.TL1.NYC8.ALTER.NET (152.63.0.153)  73.672 ms  74.631 ms  77.929 ms  
 14  0.so-3-0-0.TL1.TOR2.ALTER.NET (152.63.2.85)  94.344 ms  94.306 ms  94.291 ms  
 15  POS1-0.XR1.TOR2.ALTER.NET (152.63.2.110)  94.233 ms  94.195 ms  94.267 ms  
 16  POS6-0.GW4.TOR2.ALTER.NET (152.63.131.137)  94.754 ms  94.131 ms  94.077 ms  
 17  208.217.112.78 (208.217.112.78)  94.259 ms  94.395 ms  94.510 ms  
 18  srp0-0.core1-tor.bb.attcanada.ca (216.191.65.241)  105.221 ms  105.120 ms  105.135 ms  
 19  pos8-0.core1-ott.bb.attcanada.ca (216.191.65.178)  109.517 ms  109.483 ms  109.402 ms  
 20  pos5-0-0.hcap1-ott.bb.attcanada.ca (216.191.225.2)  110.210 ms  110.037 ms  110.215 ms  
 21  invlogic2.p2p.attcanada.ca (216.191.132.150)  121.681 ms  118.644 ms  115.341 ms  
 22  router.invlogic.com (207.245.34.122)  113.408 ms  114.595 ms  122.460 ms  
 23  www.linux.org (198.182.196.56)  115.316 ms  116.106 ms  116.484 ms  
 \end{verbatim}  
 }  
 Pakketjes van onze lokale computer passeren dus eerst langs de gateway ``router''  
 met IP adres 157.193.53.254. Deze gateway bevindt zich dus inderdaad op ons lokale  
 subnet. Die stuurt alles door naar ge.m20.access.gent.giga.belnet.net, die het  
 weer doorstuurt,~\ldots tot we bij de 23ste stap eindelijk bij \url{www.linux.org}  
 aankomen. De drie tijden in milliseconden geven aan hoe lang een testpakketje  
 erover deed om van onze computer naar de gateway in kwestie en weer terug te reizen;  
 \commando{traceroute} zendt drie pakketjes per gateway zodat er ook drie tijden te zien zijn.  
   
 Belangrijk is dat onze lokale computer enkel maar moet weten  
 \begin{itemize}  
 \item dat pakketten voor computers op het lokale subnet (dus naar computers met IP's van de vorm 157.193.53.x)  
         rechtstreeks naar die computer in kwestie mogen gestuurd worden  
 \item dat pakketten voor andere computers naar computer 157.193.53.254 moeten gestuurd worden.  
 \end{itemize}  
 De gateway 157.193.53.254 zoekt dan zelf wel verder uit naar waar het pakket verder moet gestuurd worden.  
   
 We zullen nu uitzoeken hoe we zelf een gateway kunnen opzetten voor ons eigen subnetje,  
 waar we de IP adressen 10.1.1.x voor zullen gebruiken. De gateway heeft zoals gezegd  
 twee netwerkkaarten en dus ook twee IP adressen: \'e\'en op ons eigen subnetje  
 10.1.1.1 en \'e\'en op het netwerk waar we internet verbinding van krijgen  
 (typisch onze internetprovider) 157.193.53.222.  
 IP adressen van de vorm 10.x.x.x  
 mogen niet op het internet gebruikt worden. Onze gateway zal de pakketten dus niet alleen  
 versturen naar de juiste bestemming, maar ook nog eens het IP adres wijzigen zodat  
 het lijkt alsof alle pakketten van 157.193.53.222 zelf afkomstig zijn. Omgekeerd  
 zal de gateway de antwoordpakketten (die dus aan 157.193.53.222 geadresseerd zijn)  
 terug vertalen en naar de juiste bestemming binnen ons eigen subnet 10.1.1.x sturen.  
 Dit hele gegoochel met doel- en bron-IP adressen wordt \begrip{IP masquerading}  
 genoemd. Zie figuur~\ref{gatewayfig}.  
   
 \begin{figure}[!h]  
 \begin{center}  
 \includegraphics[angle=-90,width=0.8\textwidth]{server/gateway.pdf}  
 \caption{Onze netwerktopologie}  
 \label{gatewayfig}  
 \end{center}  
 \end{figure}  
   
 \subsection{Masquerading gateway onder Linux 2.2.x}  
 De volgende regels zorgen ervoor dat onze computer pakketten van het subnet 10.1.1.x  
 aanvaardt en ze doorstuurt naar de gepaste gateway.  
 \begin{verbatim}  
 IPMASQ=10.1.1.0  
 echo "1" >/proc/sys/net/ipv4/ip_forward  
 /sbin/modprobe ip_masq_ftp  
 /sbin/modprobe ip_masq_raudio  
 /sbin/modprobe ip_masq_irc  
 /sbin/ipchains -P forward DENY  
 /sbin/ipchains -A forward -s ${IPMASQ}/24 -j MASQ  
 \end{verbatim}  
 De verschillende \commando{modprobe} commando's zorgen er ook voor dat  
 speciale maatregelen genomen worden om de FTP, real audio en IRC protocollen  
 te ondersteunen. Deze maatregelen zijn nodig omdat die protocollen in de war  
 kunnen raken doordat de masquerading gateway ``achter hun rug'' IP adressen  
 zit te veranderen.  
   
 Ipchains kan nog veel meer: je kan bepaalde trafiek blokkeren, bepaalde pakketten  
 meer prioriteit geven (``Type Of Service (TOS)''),~\ldots, te veel om hier te bespreken.  
 Als je ooit ipchains instellingen volledig om zeep helpt, kan je in geval van nood  
 \begin{verbatim}  
 echo 0 > /proc/sys/net/ipv4/ip_forward  
 ipchains -F  
 ipchains -X  
 ipchains -P input ACCEPT  
 ipchains -P output ACCEPT  
 ipchains -P forward ACCEPT  
 \end{verbatim}  
 doen, waardoor elke vorm van firewalling en masquerading uitgeschakeld wordt.  
   
 Een voorbeeld: we blokkeren alle WWW-trafiek van ons lokaal netwerkje dat op 10.1.1.x  
 zit naar buiten:  
 \begin{verbatim}  
 ipchains -A input -j REJECT -p tcp -s 10.1.1.0/24 -d 0.0.0.0/0 80  
 \end{verbatim}  
 We weigeren hier binnenkomende (\texttt{input}) pakketten die komen van  
 \texttt{10.1.1.0/24} en die als doel gelijk welk adres hebben (\texttt{0.0.0.0/0}) maar  
 gericht zijn naar poort \texttt{80}, hetgeen de poort is die voor WWW-trafiek gebruikt wordt.  
 We hadden ook een poortnummer kunnen opgeven bij het bronadres (we schreven enkel  
 \texttt{10.1.1.0/24}, zonder poortnummer erachter); in dit geval zou dat niet zo verstandig  
 zijn omdat poortnummers van de webbrowser geen vast nummer gebruiken.  
   
 Met \commando{ipchains -L} krijgen we een lijst van alle instellingen die we gemaakt hebben.  
 \begin{verbatim}  
 Chain input (policy ACCEPT):  
 target     prot opt     source                destination           ports  
 REJECT     tcp  ------  10.1.1.0/24          anywhere              www ->   any  
 Chain forward (policy DENY):  
 target     prot opt     source                destination           ports  
 MASQ       all  ------  10.1.1.0/24          anywhere              n/a  
 Chain output (policy ACCEPT):  
 \end{verbatim}  
 We zien dat we binnenkomende pakketten filteren op WWW-pakketten, die we weigeren  
 (\texttt{REJECT}), we doen aan \texttt{MASQ}erading, en bij het verlaten van  
 de computer (\texttt{output}) filteren we niets speciaals.  
   
 \subsection{Masquerading gateway onder Linux 2.4.x}  
 Voor wie de 2.4 kernel zou ge\"\i nstalleerd hebben, is alles hetzelfde maar net iets anders:  
 het \commando{ipchains} is hier vervangen door \commando{iptables}.  
 %%%[[[ PENDING: hoe 2.4 installeren ]]]  
 \begin{verbatim}  
 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  
 echo "1" >/proc/sys/net/ipv4/ip_forward  
 modprobe ip_nat_ftp  
 modprobe ip_conntrack_ftp  
 \end{verbatim}  
 waarbij eth0 de netwerkkaart is naar waar de pakketten van ons intern net gestuurd  
 moeten worden (in ons geval dus de kaart die aan 157.193.53.x hangt).  
   
 Ook hier dienen de \commando{modprobe} commando's om het FTP protocol  
 beter te ondersteunen.  
   
 %%%[[[ hoe gewone gateway maken zonder masquerading? ]]]  
   
 %%%\section{Linux als firewall}  
 %%% [[[ PENDING ]]]  
   
1073  \chapter{Printserver}  \chapter{Printserver}
1074  Er zijn twee manieren om met printers te werken onder Unix: het traditionele  Er zijn twee manieren om met printers te werken onder Unix: het traditionele
1075  lpr en het recentere cups.  lpr en het recentere cups.
# Line 2053  Om printjobs te aanvaarden van LPR clien Line 1243  Om printjobs te aanvaarden van LPR clien
1243  installeren. Tijdens de installatie wordt gevraagd of we de LPR-compatibele  installeren. Tijdens de installatie wordt gevraagd of we de LPR-compatibele
1244  daemon willen opstarten, wat we uiteraard positief beantwoorden.  daemon willen opstarten, wat we uiteraard positief beantwoorden.
1245    
1246  \chapter{Regelmatig terugkerende taken}  \chapter{Mailserver}
1247  \section{Taken uitvoeren bij het opstarten}  We zullen als mailserver \commando{postfix} installeren. Andere mogelijkheden
1248  \subsection{Eigen scripts}  zijn \commando{sendmail} (populair maar soms nogal ingewikkeld om te configureren),
1249  \index{/etc/rc.boot}\label{etc_rcboot}%  \commando{exim} (standaard bij Debian geleverd),~\ldots
 Als je een bepaalde actie, laten we zeggen het uitkuisen van de \file{/tmp}  
 directory bij het opstarten met \commando{rm -rf /tmp}, bij elke herstart van  
 de computer wil laten uitvoeren, volstaat het een scriptbestandje te maken  
 en dat in \file{/etc/rc.boot/} te plaatsen. De eerste lijn moet van de vorm  
 \verb|#!/bin/shellnaam| zijn en het bestand moet uitvoerbaar zijn. We kunnen dus  
 een bestand maken \file{/etc/rc.boot/kuisTmp} met inhoud  
 \begin{verbatim}  
 #!/bin/sh  
 rm -rf /tmp/*  
 \end{verbatim}  
 en natuurlijk niet vergeten \commando{chmod a+x /etc/rc.boot/kuisTmp} te doen.  
   
 \subsection{Systeemdiensten}  
 Er worden bij het opstarten ook een aantal diensten opgestart.  
 Diensten staan beschreven in scripts in \file{/etc/init.d/}: de dienst \file{keymap.sh}  
 zorgt voor het instellen van het toetsenbord, \file{networking} is in staat het netwerk  
 te starten of te stoppen, enzovoort. Al deze scripts hebben als mogelijke opties  
 op zijn minst \file{stop} en \file{start} als opties, dus je kunt manueel het netwerk  
 stoppen met  
 \begin{center}\commando{/etc/init.d/networking stop}\end{center}  
 In de directory \file{etc/rcS.d/} staan alle diensten beschreven die moeten gestart  
 worden wanneer de computer opgestart wordt. Het zijn allemaal symbolische links  
 naar scripts in de \file{/etc/init.d} directory, met een speciale naamgeving: de eerste  
 letter is een \texttt{S} (om aan te geven dat een dienst gestart moet worden;  
 \texttt{K} kan in principe ook om een dienst te stoppen (\texttt{K}ill) maar is nogal  
 onzinnig bij het opstartproces), gevolgd door twee cijfers, gevolgd door de naam van de dienst.  
 De twee cijfers geven aan wanneer de dienst moet gestart worden: diensten met het laagste  
 getal worden het eerst opgestart.  
   
 \section{Taken regelmatig uitvoeren: cron}  
 Elke gebruiker kan een tabel aanmaken van taken die hij regelmatig uitgevoerd wil zien.  
 Deze tabel kan je bewerken met het commando \commando{crontab -e}.  
 Elke regel bevat een aantal velden: minuut, uur, dag van de maand, maand, dag  
 van de week (1 is maandag, 7 zondag) en uit te voeren commando. Bijvoorbeeld,  
 om de \file{/tmp} directory elke zondag te wissen om 23 uur 59 voegen we een lijn  
 \begin{verbatim}  
 59 23 * * 7     rm -rf /tmp/*  
 \end{verbatim}  
 toe. De velden die er niet toe doen worden opgevuld met sterretjes. Je kan ook  
 een bereik aangeven:  
 \begin{verbatim}  
 0 10-12 * * 1-5 echo Koffiepauze | lpr  
 \end{verbatim}  
 zal om 10u00, 11u00 en 12u00 tijdens weekdagen een blad afprinten met ``Koffiepauze'' erop.  
 Je kan ook ``om de zoveel'' tijd iets laten gebeuren met `/':  
 \begin{verbatim}  
 0 8-17/2 * * 1-5        echo Koffiepauze | lpr  
 \end{verbatim}  
 zal om 8u00, 10u00,~\dots, 16u00 een blad afprinten: \texttt{8-17/2} betekent  
 ``van 8 tot 17 uur, om de twee uur''. Je zou net zo goed  
 \begin{verbatim}  
 0 8,10,12,14,16 * * 1-5 echo Koffiepauze | lpr  
 \end{verbatim}  
 mogen geschreven hebben: met de komma kan je een lijst van tijdstippen opgeven.  
 Combinaties van dit alles zijn ook mogelijk: om elke vijf minuten iets te doen kan je  
 \begin{verbatim}  
 */5 * * * *     iets  
 \end{verbatim}  
 doen.  
   
 Wil je een taak een keer per dag, week of maand uitvoeren, dan kan je er ook voor kiezen  
 een bestand bij te plaatsen in \file{/etc/cron.daily}, \file{/etc/cron.weekly}  
 of \file{/etc/cron.monthly}. Het formaat is hetzelfde als in \file{etc/rc.boot}  
 (zie~\S\ref{etc_rcboot}): de eerste lijn moet van de vorm  
 \verb|#!/bin/shellnaam| zijn en het bestand moet uitvoerbaar zijn.  
   
 \chapter{DHCP}  
 \index{DHCP}%  
 DHCP staat voor Dynamic Host Configuration Protocol en zoals de naam al een beetje  
 aangeeft wordt dit protocol gebruikt om computers dynamisch te configureren:  
 de DHCP-clients vragen aan de DHCP-server welke configuratie-instellingen ze moeten  
 gebruiken. We kunnen de DHCP-server bijvoorbeeld IP-adressen en hostnamen laten  
 ``uitdelen'' aan de computers op het netwerk, zodat de configuratie centraal kan gebeuren.  
 Deze aanpak spaart ook een hoop vervelend werk uit bij het configureren van de computers  
 op het netwerk: instellingen zoals netmasker, domeinnaam, nameserver,~\ldots hoeven  
 we nu maar \'e\'en keer te doen (op de DHCP server) in plaats van op elke computer apart.  
1250    
1251  \section{Installatie}  \section{Installatie}
1252  Installeren van de DHCP daemon gaat simpelweg met  We tikken dus \commando{apt-get install postfix} dat de mailserver installeert en
1253  \begin{center}\commando{apt-get install dhcp}\end{center}  ons enkele vragen stelt (die we desgewenst opnieuw kunnen beantwoorden met
1254    \commando{dpkg -reconfigure -{}-priority=low postfix}. Eerst wordt het
1255  \section{Configuratie}  \textit{general type of configuration} gevraagd, waarop we ``Internet Site''
1256  \subsection{Statische configuratie}  antwoorden; verder wordt de \textit{mail name} gevraagd. Mail verstuurd vanop onze server
1257  De DHCP daemon {\tt dhcpd} wordt geconfigureerd in het bestand \file{/etc/dhcpd.conf},  zal aan de ontvanger getoond worden als komende van ``gebruikersnaam@\textit{mailname}'',
1258  dat er zo zou kunnen uitzien:\\  dus we vullen hier de volledige naam van onze computer in (iets in de trant van
1259  {\small\tt option domain-name "schrootnet";\qquad\textit{\# Domeinnaam}  \textit{mijnserver.domein.be}). Verder wordt gevraagd \textit{append .domain to simple
1260  option domain-name-servers 157.193.53.8;\qquad\textit{\# IP adres van de nameserver(s)}  addresses} en \textit{final destinations} waarop de het standaard voorgestelde antwoorden
1261  \strut\\\  geven. De installer gaat dan aan het werk en vraagt na een tijdje tenslotte
1262  option subnet-mask 255.255.255.0;\qquad\textit{\# subnet masker}\\  \textit{where should mail for root go}. Hier vullen we de naam van de gebruiker in die
1263  option routers 10.1.1.1;\qquad\textit{\# gateway}\\  de mail zal ontvangen die aan \textit{root} geadresseerd is. Veel automatische
1264  default-lease-time 600;\qquad\textit{\# clients krijgen normaal instellingen voor 10~min}\\  processen sturen immers mail naar \textit{root} als er een of andere fout optreedt
1265  max-lease-time 7200;\qquad\textit{\# clients kunnen tot 120 minuten instellingen houden}\\  (bijvoorbeeld de printserver die een probleem vaststelt), maar het is aan te raden zo
1266  \strut\\  weinig mogelijk als \textit{root} in te loggen, laat staan mail te lezen, zodat we mail
1267  subnet 10.1.1.0 netmask 255.255.255.0 \{\qquad\textit{\# instellingen voor subnet 10.1.1.x}\\  voor \textit{root} het best naar een gewone gebruiker omleiden.
 \strut\qquad server-name "10.1.1.1";\qquad\textit{\# naam van onze DHCP server}\\  
 \strut\qquad option subnet-mask 255.255.255.0;\\  
 \strut \qquad host xterm1 \{\qquad\textit{\# instellingen voor computer "xterm1"}\\  
 \strut\qquad\qquad hardware ethernet 00:00:a7:13:54:F8;\\  
 \strut\qquad\qquad fixed-address 10.1.1.2;\qquad\textit{\# "xterm1" krijgt altijd dit IP adres}\\  
 \strut\qquad\qquad option host-name "xterm1";\\  
 \strut\qquad \}\\  
 \strut \qquad host pcklas01 \{\qquad\textit{\# instellingen voor computer "pcklas01"}\\  
 \strut\qquad\qquad hardware ethernet 00:00:a4:4d:54:9f;\\  
 \strut\qquad\qquad fixed-address 10.1.1.3;\qquad\textit{\# "pcklas01" krijgt altijd dit IP adres}\\  
 \strut\qquad\qquad option host-name "pcklas01";\\  
 \strut\qquad \}\\  
 \strut\qquad\textit{\# enzovoort, voor elke computer van het netwerk}\\  
 \}\\  
 }  
1268    
1269  Met het commando \commando{/etc/init.d/dhcp restart} herstarten we de DHCP deamon  \subsection{De installatie testen}
1270  zodat die onze gewijzigde instellingen overneemt.  We kunnen testen of het werkt door een mail te versturen met het programma \commando{mail}.
1271    We tikken \commando{mail een.of.ander@werkend.email.adres} in, waarna
1272    ons een \textit{Subject} gevraagd wordt, waarna we de boodschap kunnen intikken.
1273    Eindig met een regel waar enkel een punt in staat; tenslotte wordt om een \textit{Cc}
1274    gevraagd, dat we leeg laten. Als het goed is krijgt \textit{een.of.ander@werkend.email.adres}
1275    een e-mailtje. We kunnen ook omgekeerd van ergens anders een mail naar onze server
1276    sturen en dan met \commando{mail} (zonder verdere argumenten deze keer) kijken
1277    welke mails er toegekomen zijn. Eventueel kunnen we ernaar kijken door \textit{print}
1278    te tikken; \commando{mail} verlaten gaat met \textit{q}.
1279    
1280  Als alles goed is verlopen, moet de DHCP daemon draaien, hetgeen we kunnen controleren  \subsection{IMAP installeren}
1281  door \commando{ps aux|grep dhcpd} te typen en te zien of er een lijn  Over het algemeen zullen onze gebruikers hun mail niet lezen door in te loggen op
1282  {\small\begin{verbatim}  de server en dan een of ander mailprogramma (zoals \commando{mail}) te starten.
1283  root     29942  0.0  4.5  2172  836 ?        S    11:56   0:00 /usr/sbin/dhcpd-2.2.x -q  Tegenwoordig draaien de gebruikers meestal e-mail programma's (Netscape, Outlook,~\dots)
1284  \end{verbatim}}  op hun eigen computer, die dan verbinding legt met de mailserver.
1285  tussen staat.  Om deze werkwijze te ondersteunen is het nodig een POP- of IMAP-server te installeren.
1286    We kiezen IMAP omdat het POP protocol onveilig is (het stuurt wachtwoorden
1287    ongecodeerd over het netwerk). Met
1288    \begin{center}\commando{apt-get install uw-imapd}\end{center}
1289    installeren we een IMAP daemon.
1290    
1291  Als we twee netwerkkaarten in onze server hebben, kan het gebeuren dat we in plaats daarvan  \section{E-mail aliassen}
1292  de volgende foutmelding zien in \file{/var/log/daemon.log}:  We kunnen ook \Begrip{e-mail aliassen}\index{e-mail alias} aanmaken
1293    door het bestand \file{/etc/aliases} aan te passen:
1294  \begin{verbatim}  \begin{verbatim}
1295  No subnet declaration for eth0 (157.193.53.222).  postmaster:    root
1296  Please write a subnet declaration in your dhcpd.conf file for the  root:   geert
 network segment to which interface eth0 is attached.  
 exiting.  
1297  \end{verbatim}  \end{verbatim}
1298  We hebben wel informatie gegeven over wat de DHCP deamon moet doen met aanvragen  Hier wordt alle mail naar \textit{postmaster@onze.mailserver} gestuurd naar
1299  van de ene netwerkkaart (die op subnet 10.1.1.x) maar er hangt ook nog een andere  gebruiker \textit{root@onze.mailserver}, en die mail wordt dan weer doorgestuurd
1300  netwerkkaart (eth0, op subnet 157.193.53.x) aan onze computer. We moeten dus nog iets  naar \textit{geert@onze.mailserver} (we gaven hier ``geert'' op bij de installatie van Postfix
1301  toevoegen aan ons configuratiebestand:  als de gebruiker die mail van de root moest ontvangen).
1302    We kunnen dit mechanisme ook gebruiken om aliassen te maken voor een groep personen,
1303    bijvoorbeeld:
1304  \begin{verbatim}  \begin{verbatim}
1305  subnet 157.193.53.222 netmask 255.255.255.0 {  postmaster:    root
1306          not authoritative;  root:   geert, jan
1307  }  directie: rudy, tom, els
1308    secretariaat: joris, eva
1309    personeel: hans, geert, jan, jef
1310    alumni: bart@ergensanders.be, bert@nogergensanders.us
1311    iedereen: directie, secretariaat, personeel
1312  \end{verbatim}  \end{verbatim}
1313  Normaal gezien geeft de DHCP server aan onbekende clients een foutmelding terug  Als we bijvoorbeeld mail sturen naar \textit{secretariaat@onze.mailserver},
1314  (``er is geen configuratie-info voor jou beschikbaar''). Maar omdat we op  dan krijgen zowel \textit{joris@onze.mailserver} als \textit{eva@onze.mailserver}
1315  het subnet 157.193.53.x, waar we onze internettoegang vandaan halen, helemaal niets  die mail. Zoals we zien in de alias \textit{alumni} mogen de doeladressen van een alias
1316  te zeggen hebben, schrijven we \texttt{not authoritative}, zodat de DHCP server  gerust adressen op een andere mailserver zijn. We kunnen ook aliassen gebruiken die
1317  niets zal doen als hij ziet dat een client om informatie vraagt. Het is immers goed  zelf weer andere aliassen oproepen: sturen we iets naar \textit{iedereen@onze.mailserver}
1318  mogelijk dat op het subnet van onze provider al een DHCP server draait, en zou het goed  dan krijgen in totaal 9 mensen een mail (alleen de arme \textit{alumni} niet).
1319  kunnen dat onze DHCP server anders tegen andere klanten van de provider  Na het aanpassen van \file{/etc/aliases} is het nodig de instellingen te activeren
1320  zou zeggen ``er is geen configuratie voor jou beschikbaar'' en dat zal die provider niet  met het commando \commando{newaliases}.
 echt leuk vinden~\ldots  
   
 We hebben een \texttt{default-lease-time} van 600 seconden ingesteld, zodat alle  
 computers van het netwerk om de tien minuten opnieuw hun configuratie zullen  
 opvragen. Als je netwerk redelijk statisch is en er niet direkt elke tien minuten computers  
 van configuratie veranderen, kan je gerust waarden als 86400 (een dag) of hoger invullen.  
1321    
1322  \subsection{Dynamische configuratie}  \section{Verdere configuratie}
1323  Het is ook mogelijk dynamisch IP adressen uit te delen. Met  Verdere fijnregeling van Postfix is mogelijk door \file{/etc/postfix/mail.cf} aan te passen,
1324    of door het commando \commando{postconf} te gebruiken. Om bijvoorbeeld in
1325    te stellen dat de inbox van gebruikers maximaal 10 megabyte mag zijn, passen we de regel
1326  \begin{verbatim}  \begin{verbatim}
1327  range 10.1.1.100 10.1.1.200;  mailbox_size_limit = 0
1328  \end{verbatim}  \end{verbatim}
1329  in plaats van of tussen de \texttt{host} regels, zorg je ervoor dat voor de computers  aan tot
 die niet gekend zijn met zulke \texttt{host} regels, dynamisch IP adressen van  
 10.1.1.100 tot en met 10.1.1.200 worden uitgedeeld. De DHCP server zorgt ervoor  
 dat geen twee computers hetzelfde IP krijgen. Bij dynamische IP's kan het handig zijn  
 de \texttt{default-lease-time} kort te houden (10 minuten bijvoorbeeld) zodat  
 IP's snel vrijkomen als een computer wordt uitgeschakeld.  
   
 Je kan statische en dynamische configuratie mengen zoals je wil, of enkel \'e\'en van de  
 twee systemen gebruiken. Een praktijkvoorbeeld van een gemengde configuratie  
 is alle vaste computers statisch configureren en een aantal adressen dynamisch uitdelen  
 aan laptops. Iemand die zijn laptop meebrengt krijgt dan vanzelf een eigen IP adres,  
 terwijl de vaste computers een gekend IP adres hebben (hetgeen in geval van problemen  
 te verkiezen kan zijn boven dynamisch uitgedeelde adressen).  
   
 \section{Configuratie van de client}  
 Tijdens het installeren van Debian werd ons al gevraagd of we automatische netwerkconfiguratie  
 wouden; hebben we hier bevestigend op geantwoord, dan is alles in orde. Zoniet  
 kunnen we ons later bedenken door in \file{/etc/network/interfaces} het stukje  
 over \texttt{eth0} te vervangen door  
1330  \begin{verbatim}  \begin{verbatim}
1331  iface eth0 inet dhcp  mailbox_size_limit = 10000000
1332  \end{verbatim}  \end{verbatim}
1333  Als de netwerkkaart voordien geen DHCP gebruikte, dan waren er waarschijnlijk een  of tikken we simpelweg
1334  aantal extra regels met netwerkinstellingen aanwezig (\texttt{address}, \texttt{netmask},~\dots)  \begin{center}\commando{postconf -e mailbox\_size\_limit=10000000}\end{center}
 die je gerust mag verwijderen.  
1335    
1336  \chapter{Een 486 als X-terminal}  \chapter{Een 486 als X-terminal}
1337  Het is de bedoeling dat een oude computer (bijvoorbeeld een 486)  Het is de bedoeling dat een oude computer (bijvoorbeeld een 486)
# Line 2391  erop neer dat we Line 1484  erop neer dat we
1484  een opstartdiskette maken die automatisch via een NFS server X-windows opstart.  een opstartdiskette maken die automatisch via een NFS server X-windows opstart.
1485    
1486    
 \chapter{Mailserver}  
 We zullen als mailserver \commando{postfix} installeren. Andere mogelijkheden  
 zijn \commando{sendmail} (populair maar soms nogal ingewikkeld om te configureren),  
 \commando{exim} (standaard bij Debian geleverd),~\ldots  
1487    
1488  \section{Installatie}  \chapter{Firewall/gedeeld internet}
1489  We tikken dus \commando{apt-get install postfix} dat de mailserver installeert en  \section{Linux als gateway}
1490  ons enkele vragen stelt (die we desgewenst opnieuw kunnen beantwoorden met  Internet is opgebouwd uit een groot aantal onderling verbonden kleine netwerkjes.
1491  \commando{dpkg -reconfigure -{}-priority=low postfix}. Eerst wordt het  In dit voorbeeld heeft ons lokaal netwerkje IP adressen van de vorm 157.193.53.x.
1492  \textit{general type of configuration} gevraagd, waarop we ``Internet Site''  Als we een verbinding willen leggen tussen twee lokale computers, kunnen we dat
1493  antwoorden; verder wordt de \textit{mail name} gevraagd. Mail verstuurd vanop onze server  rechtstreeks doen: computers in hetzelfde netwerk ``zien'' elkaar rechtstreeks.
1494  zal aan de ontvanger getoond worden als komende van ``gebruikersnaam@\textit{mailname}'',  Maar als we verbinding willen leggen met een computer buiten ons lokaal netwerk,
1495  dus we vullen hier de volledige naam van onze computer in (iets in de trant van  moeten we dat via een tussenliggende computer doen, die verbonden is met ons netwerk
1496  \textit{mijnserver.domein.be}). Verder wordt gevraagd \textit{append .domain to simple  en met het andere netwerk in kwestie. Die computer wordt \begrip{gateway} genoemd
1497  addresses} en \textit{final destinations} waarop de het standaard voorgestelde antwoorden  en heeft dus minstens twee netwerkkaarten aan boord: \'e\'en voor ons lokaal netwerk
1498  geven. De installer gaat dan aan het werk en vraagt na een tijdje tenslotte  en \'e\'en voor het andere netwerk. Er kunnen ook meerdere tussenstappen nodig zijn
1499  \textit{where should mail for root go}. Hier vullen we de naam van de gebruiker in die  om van het ene netwerk naar het andere te gaan, zodat de pakkettjes van gateway naar
1500  de mail zal ontvangen die aan \textit{root} geadresseerd is. Veel automatische  gateway reizen eer ze op hun bestemming aankomen. Met het \commando{traceroute}
1501  processen sturen immers mail naar \textit{root} als er een of andere fout optreedt  commando kunnen we een beeld krijgen van dit proces:
1502  (bijvoorbeeld de printserver die een probleem vaststelt), maar het is aan te raden zo  {\small\begin{verbatim}
1503  weinig mogelijk als \textit{root} in te loggen, laat staan mail te lezen, zodat we mail  $ /usr/sbin/traceroute www.linux.org
1504  voor \textit{root} het best naar een gewone gebruiker omleiden.  traceroute to www.linux.org (198.182.196.56), 30 hops max, 38 byte packets
1505     1  router (157.193.53.254)  2.372 ms  1.970 ms  1.011 ms
1506     2  ge.m20.access.gent.giga.belnet.net (193.191.7.9)  0.991 ms  0.983 ms  0.946 ms
1507     3  oc48.m160.core.science.giga.belnet.net (193.191.1.137)  1.782 ms  1.731 ms  1.759 ms
1508     4  oc192.m160.ext.science.giga.belnet.net (193.191.1.2)  1.698 ms  1.777 ms  1.836 ms
1509     5  gigabitethernet4-0-139.ipcolo1.Brussels1.Level3.net (212.3.234.129)  1.921 ms  1.736 ms  1.735 ms
1510     6  ae0-12.mp2.Brussels1.Level3.net (212.3.239.34)  2.337 ms  2.271 ms  2.229 ms
1511     7  so-3-0-0.mp2.London1.Level3.net (212.187.128.57)  6.837 ms  6.899 ms  6.864 ms
1512     8  so-1-0-0.mp2.NewYork1.Level3.net (212.187.128.153)  74.793 ms  72.462 ms  74.133 ms
1513     9  so-7-0-0.gar2.NewYork1.Level3.net (64.159.1.186)  73.693 ms  74.103 ms  75.606 ms
1514    10  so-4-2-0.edge1.NewYork1.Level3.net (209.244.17.82)  74.372 ms  73.531 ms  73.104 ms
1515    11  uunet-level3-oc48.NewYork1.Level3.net (209.244.160.182)  72.674 ms  77.773 ms  81.170 ms
1516    12  0.so-6-0-0.XL1.NYC4.ALTER.NET (152.63.21.78)  73.277 ms  74.863 ms  81.496 ms
1517    13  0.so-2-0-0.TL1.NYC8.ALTER.NET (152.63.0.153)  73.672 ms  74.631 ms  77.929 ms
1518    14  0.so-3-0-0.TL1.TOR2.ALTER.NET (152.63.2.85)  94.344 ms  94.306 ms  94.291 ms
1519    15  POS1-0.XR1.TOR2.ALTER.NET (152.63.2.110)  94.233 ms  94.195 ms  94.267 ms
1520    16  POS6-0.GW4.TOR2.ALTER.NET (152.63.131.137)  94.754 ms  94.131 ms  94.077 ms
1521    17  208.217.112.78 (208.217.112.78)  94.259 ms  94.395 ms  94.510 ms
1522    18  srp0-0.core1-tor.bb.attcanada.ca (216.191.65.241)  105.221 ms  105.120 ms  105.135 ms
1523    19  pos8-0.core1-ott.bb.attcanada.ca (216.191.65.178)  109.517 ms  109.483 ms  109.402 ms
1524    20  pos5-0-0.hcap1-ott.bb.attcanada.ca (216.191.225.2)  110.210 ms  110.037 ms  110.215 ms
1525    21  invlogic2.p2p.attcanada.ca (216.191.132.150)  121.681 ms  118.644 ms  115.341 ms
1526    22  router.invlogic.com (207.245.34.122)  113.408 ms  114.595 ms  122.460 ms
1527    23  www.linux.org (198.182.196.56)  115.316 ms  116.106 ms  116.484 ms
1528    \end{verbatim}
1529    }
1530    Pakketjes van onze lokale computer passeren dus eerst langs de gateway ``router''
1531    met IP adres 157.193.53.254. Deze gateway bevindt zich dus inderdaad op ons lokale
1532    subnet. Die stuurt alles door naar ge.m20.access.gent.giga.belnet.net, die het
1533    weer doorstuurt,~\ldots tot we bij de 23ste stap eindelijk bij \url{www.linux.org}
1534    aankomen. De drie tijden in milliseconden geven aan hoe lang een testpakketje
1535    erover deed om van onze computer naar de gateway in kwestie en weer terug te reizen;
1536    \commando{traceroute} zendt drie pakketjes per gateway zodat er ook drie tijden te zien zijn.
1537    
1538  \subsection{De installatie testen}  Belangrijk is dat onze lokale computer enkel maar moet weten
1539  We kunnen testen of het werkt door een mail te versturen met het programma \commando{mail}.  \begin{itemize}
1540  We tikken \commando{mail een.of.ander@werkend.email.adres} in, waarna  \item dat pakketten voor computers op het lokale subnet (dus naar computers met IP's van de vorm 157.193.53.x)
1541  ons een \textit{Subject} gevraagd wordt, waarna we de boodschap kunnen intikken.          rechtstreeks naar die computer in kwestie mogen gestuurd worden
1542  Eindig met een regel waar enkel een punt in staat; tenslotte wordt om een \textit{Cc}  \item dat pakketten voor andere computers naar computer 157.193.53.254 moeten gestuurd worden.
1543  gevraagd, dat we leeg laten. Als het goed is krijgt \textit{een.of.ander@werkend.email.adres}  \end{itemize}
1544  een e-mailtje. We kunnen ook omgekeerd van ergens anders een mail naar onze server  De gateway 157.193.53.254 zoekt dan zelf wel verder uit naar waar het pakket verder moet gestuurd worden.
 sturen en dan met \commando{mail} (zonder verdere argumenten deze keer) kijken  
 welke mails er toegekomen zijn. Eventueel kunnen we ernaar kijken door \textit{print}  
 te tikken; \commando{mail} verlaten gaat met \textit{q}.  
1545    
1546  \subsection{IMAP installeren}  We zullen nu uitzoeken hoe we zelf een gateway kunnen opzetten voor ons eigen subnetje,
1547  Over het algemeen zullen onze gebruikers hun mail niet lezen door in te loggen op  waar we de IP adressen 10.1.1.x voor zullen gebruiken. De gateway heeft zoals gezegd
1548  de server en dan een of ander mailprogramma (zoals \commando{mail}) te starten.  twee netwerkkaarten en dus ook twee IP adressen: \'e\'en op ons eigen subnetje
1549  Tegenwoordig draaien de gebruikers meestal e-mail programma's (Netscape, Outlook,~\dots)  10.1.1.1 en \'e\'en op het netwerk waar we internet verbinding van krijgen
1550  op hun eigen computer, die dan verbinding legt met de mailserver.  (typisch onze internetprovider) 157.193.53.222.
1551  Om deze werkwijze te ondersteunen is het nodig een POP- of IMAP-server te installeren.  IP adressen van de vorm 10.x.x.x
1552  We kiezen IMAP omdat het POP protocol onveilig is (het stuurt wachtwoorden  mogen niet op het internet gebruikt worden. Onze gateway zal de pakketten dus niet alleen
1553  ongecodeerd over het netwerk). Met  versturen naar de juiste bestemming, maar ook nog eens het IP adres wijzigen zodat
1554  \begin{center}\commando{apt-get install uw-imapd}\end{center}  het lijkt alsof alle pakketten van 157.193.53.222 zelf afkomstig zijn. Omgekeerd
1555  installeren we een IMAP daemon.  zal de gateway de antwoordpakketten (die dus aan 157.193.53.222 geadresseerd zijn)
1556    terug vertalen en naar de juiste bestemming binnen ons eigen subnet 10.1.1.x sturen.
1557    Dit hele gegoochel met doel- en bron-IP adressen wordt \begrip{IP masquerading}
1558    genoemd. Zie figuur~\ref{gatewayfig}.
1559    
1560  \section{E-mail aliassen}  \begin{figure}[!h]
1561  We kunnen ook \Begrip{e-mail aliassen}\index{e-mail alias} aanmaken  \begin{center}
1562  door het bestand \file{/etc/aliases} aan te passen:  \includegraphics[angle=-90,width=0.8\textwidth]{server/gateway.pdf}
1563    \caption{Onze netwerktopologie}
1564    \label{gatewayfig}
1565    \end{center}
1566    \end{figure}
1567    
1568    \subsection{Masquerading gateway onder Linux 2.2.x}
1569    De volgende regels zorgen ervoor dat onze computer pakketten van het subnet 10.1.1.x
1570    aanvaardt en ze doorstuurt naar de gepaste gateway.
1571  \begin{verbatim}  \begin{verbatim}
1572  postmaster:    root  IPMASQ=10.1.1.0
1573  root:   geert  echo "1" >/proc/sys/net/ipv4/ip_forward
1574    /sbin/modprobe ip_masq_ftp
1575    /sbin/modprobe ip_masq_raudio
1576    /sbin/modprobe ip_masq_irc
1577    /sbin/ipchains -P forward DENY
1578    /sbin/ipchains -A forward -s ${IPMASQ}/24 -j MASQ
1579  \end{verbatim}  \end{verbatim}
1580  Hier wordt alle mail naar \textit{postmaster@onze.mailserver} gestuurd naar  De verschillende \commando{modprobe} commando's zorgen er ook voor dat
1581  gebruiker \textit{root@onze.mailserver}, en die mail wordt dan weer doorgestuurd  speciale maatregelen genomen worden om de FTP, real audio en IRC protocollen
1582  naar \textit{geert@onze.mailserver} (we gaven hier ``geert'' op bij de installatie van Postfix  te ondersteunen. Deze maatregelen zijn nodig omdat die protocollen in de war
1583  als de gebruiker die mail van de root moest ontvangen).  kunnen raken doordat de masquerading gateway ``achter hun rug'' IP adressen
1584  We kunnen dit mechanisme ook gebruiken om aliassen te maken voor een groep personen,  zit te veranderen.
1585  bijvoorbeeld:  
1586    Ipchains kan nog veel meer: je kan bepaalde trafiek blokkeren, bepaalde pakketten
1587    meer prioriteit geven (``Type Of Service (TOS)''),~\ldots, te veel om hier te bespreken.
1588    Als je ooit ipchains instellingen volledig om zeep helpt, kan je in geval van nood
1589  \begin{verbatim}  \begin{verbatim}
1590  postmaster:    root  echo 0 > /proc/sys/net/ipv4/ip_forward
1591  root:   geert, jan  ipchains -F
1592  directie: rudy, tom, els  ipchains -X
1593  secretariaat: joris, eva  ipchains -P input ACCEPT
1594  personeel: hans, geert, jan, jef  ipchains -P output ACCEPT
1595  alumni: bart@ergensanders.be, bert@nogergensanders.us  ipchains -P forward ACCEPT
 iedereen: directie, secretariaat, personeel  
1596  \end{verbatim}  \end{verbatim}
1597  Als we bijvoorbeeld mail sturen naar \textit{secretariaat@onze.mailserver},  doen, waardoor elke vorm van firewalling en masquerading uitgeschakeld wordt.
 dan krijgen zowel \textit{joris@onze.mailserver} als \textit{eva@onze.mailserver}  
 die mail. Zoals we zien in de alias \textit{alumni} mogen de doeladressen van een alias  
 gerust adressen op een andere mailserver zijn. We kunnen ook aliassen gebruiken die  
 zelf weer andere aliassen oproepen: sturen we iets naar \textit{iedereen@onze.mailserver}  
 dan krijgen in totaal 9 mensen een mail (alleen de arme \textit{alumni} niet).  
 Na het aanpassen van \file{/etc/aliases} is het nodig de instellingen te activeren  
 met het commando \commando{newaliases}.  
1598    
1599  \section{Verdere configuratie}  Een voorbeeld: we blokkeren alle WWW-trafiek van ons lokaal netwerkje dat op 10.1.1.x
1600  Verdere fijnregeling van Postfix is mogelijk door \file{/etc/postfix/mail.cf} aan te passen,  zit naar buiten:
 of door het commando \commando{postconf} te gebruiken. Om bijvoorbeeld in  
 te stellen dat de inbox van gebruikers maximaal 10 megabyte mag zijn, passen we de regel  
1601  \begin{verbatim}  \begin{verbatim}
1602  mailbox_size_limit = 0  ipchains -A input -j REJECT -p tcp -s 10.1.1.0/24 -d 0.0.0.0/0 80
1603  \end{verbatim}  \end{verbatim}
1604  aan tot  We weigeren hier binnenkomende (\texttt{input}) pakketten die komen van
1605    \texttt{10.1.1.0/24} en die als doel gelijk welk adres hebben (\texttt{0.0.0.0/0}) maar
1606    gericht zijn naar poort \texttt{80}, hetgeen de poort is die voor WWW-trafiek gebruikt wordt.
1607    We hadden ook een poortnummer kunnen opgeven bij het bronadres (we schreven enkel
1608    \texttt{10.1.1.0/24}, zonder poortnummer erachter); in dit geval zou dat niet zo verstandig
1609    zijn omdat poortnummers van de webbrowser geen vast nummer gebruiken.
1610    
1611    Met \commando{ipchains -L} krijgen we een lijst van alle instellingen die we gemaakt hebben.
1612  \begin{verbatim}  \begin{verbatim}
1613  mailbox_size_limit = 10000000  Chain input (policy ACCEPT):
1614    target     prot opt     source                destination           ports
1615    REJECT     tcp  ------  10.1.1.0/24          anywhere              www ->   any
1616    Chain forward (policy DENY):
1617    target     prot opt     source                destination           ports
1618    MASQ       all  ------  10.1.1.0/24          anywhere              n/a
1619    Chain output (policy ACCEPT):
1620  \end{verbatim}  \end{verbatim}
1621  of tikken we simpelweg  We zien dat we binnenkomende pakketten filteren op WWW-pakketten, die we weigeren
1622  \begin{center}\commando{postconf -e mailbox\_size\_limit=10000000}\end{center}  (\texttt{REJECT}), we doen aan \texttt{MASQ}erading, en bij het verlaten van
1623    de computer (\texttt{output}) filteren we niets speciaals.
1624    
1625    \subsection{Masquerading gateway onder Linux 2.4.x}
1626    Voor wie de 2.4 kernel zou ge\"\i nstalleerd hebben, is alles hetzelfde maar net iets anders:
1627    het \commando{ipchains} is hier vervangen door \commando{iptables}.
1628    %%%[[[ PENDING: hoe 2.4 installeren ]]]
1629    \begin{verbatim}
1630    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
1631    echo "1" >/proc/sys/net/ipv4/ip_forward
1632    modprobe ip_nat_ftp
1633    modprobe ip_conntrack_ftp
1634    \end{verbatim}
1635    waarbij eth0 de netwerkkaart is naar waar de pakketten van ons intern net gestuurd
1636    moeten worden (in ons geval dus de kaart die aan 157.193.53.x hangt).
1637    
1638    Ook hier dienen de \commando{modprobe} commando's om het FTP protocol
1639    beter te ondersteunen.
1640    
1641  \chapter{Systeembeheer via het web: webmin}  \chapter{WWW proxy}
1642  Webmin is een systeem dat een webservertje draait dat we kunnen gebruiken om onze  Een proxyserver is een server die clients gebruiken om verbinding te leggen met
1643  server te configureren. De basismodule heet ``webmin'', maar die bevat niet veel meer  een andere computer, in plaats van rechtstreeks een verbinding met de bestemmeling
1644  dan de webmin-webserver zelf. Voor al de rest hebben we extra webmin-modules nodig,  te leggen. De proxyserver zelf zal dan de bestemmeling contacteren.
1645  en zo zijn er genoeg: het commando \commando{apt-cache search webmin} levert  Een proxyserver werkt dus altijd voor \'e\'en bepaald protocol;
1646    in dit geval zullen we de WWW-proxyserver \begrip{squid} bespreken.
1647    
1648    Het gebruik van een proxyserver lijkt nogal een overbodige bedoening: waarom niet
1649    gewoon rechtstreeks een verbinding leggen met de bestemmeling, in plaats van
1650    rond te gaan via de proxy? Er zijn twee voordelen aan de proxy-aanpak:
1651    \begin{itemize}
1652    \item Beveiliging: we kunnen onze firewall zo instellen dat er geen WWW-trafiek
1653    van binnen ons netwerk naar buiten wordt toegelaten, tenzij vanop de proxyserver.
1654    De proxyserver zelf moet uiteraard wel WWW-verbindingen kunnen opzetten naar buiten.
1655    Op die manier kunnen we binnen de proxyserver instellen wie welke WWW-pagina's
1656    wel of niet te zien mag krijgen.
1657    \item Efficientie: de proxyserver heeft ook een \begrip{cache} aan boord van recent
1658    opgevraagde webpagina's. Pagina's die in de cache zitten, zal de proxyserver niet meer
1659    opnieuw bij de originele webserver opvragen, maar rechtstreeks uit de cache halen.
1660    Op die manier sparen we heel wat netwerktrafiek uit als bijvoorbeeld een hele
1661    PC-klas naar dezelfde site aan het surfen is.
1662    \end{itemize}
1663    Het nadeel van de proxy-aanpak is dat de software van de client (in ons geval: de webbrowser)
1664    in staat moet zijn met een proxy server om te gaan. Gelukkig is dat voor de meeste
1665    moderne webbrowsers het geval.
1666    
1667    \subsection{Installatie en configuratie}
1668    De installatie is zoals we dat van Debian gewoon zijn eenvoudig:
1669    \begin{center}\commando{apt-get install squid}\end{center}
1670    
1671    De configuratie is ook niet zo moeilijk: we bewerken het omvangrijke bestand
1672    \file{/etc/squid.conf}. We zullen twee regels toevoegen: de regel
1673  \begin{verbatim}  \begin{verbatim}
1674  webmin - Web-based administration toolkit  acl mijnclients src 10.1.1.0/24
1675  webmin-apache - apache control module for webmin  \end{verbatim}
1676  webmin-bind8 - bind 8+ control module for webmin  die een nieuwe `Access Control List' genaamd ``mijnclients'' aanmaakt
1677  webmin-burner - CD burning module for webmin  (waarin iedereen zit met een IP adres van de vorm 10.1.1.x),
1678  webmin-cluster-software - cluster software control module for webmin  en een regel
1679  webmin-cluster-useradmin - cluster user control module for webmin  \begin{verbatim}
1680  webmin-core - core modules for webmin  http_access allow mijnclients
 webmin-cpan - CPAN module for webmin  
 webmin-dhcpd - dhcpd control module for webmin  
 webmin-exports - NFS exports control module for webmin  
 webmin-fetchmail - fetchmail mail retrieval module for webmin  
 webmin-grub - grub control module for webmin  
 webmin-heartbeat - heartbeat monitor control module for webmin  
 webmin-inetd - inetd control module for webmin  
 webmin-jabber - jabber server control module for webmin  
 webmin-lpadmin - printer control module for webmin  
 webmin-mon - mon control module for webmin  
 webmin-mysql - mysql-server control module for webmin  
 webmin-nis - NIS clients/servers control module for webmin  
 webmin-postfix - postfix control module for webmin  
 webmin-postgresql - postgresql control module for webmin  
 webmin-ppp - PPP configuration module for webmin  
 webmin-qmailadmin - qmail control module for webmin  
 webmin-quota - disk quota control module for webmin  
 webmin-raid - raid control module for webmin  
 webmin-samba - samba control module for webmin  
 webmin-sendmail - sendmail control module for webmin  
 webmin-software - software packages control module for webmin  
 webmin-squid - squid control module for webmin  
 webmin-sshd - SSH server control module for webmin  
 webmin-status - server and system status control module for webmin  
 webmin-stunnel - stunnel control module for webmin  
 webmin-wuftpd - wu-ftpd control module for webmin  
 webmin-xinetd - xinetd control module for webmin  
1681  \end{verbatim}  \end{verbatim}
1682    die aangeeft dat iedereen in de lijst ``mijnclients'' toegang heeft tot onze proxyserver.
1683    Deze regel moet komen v\'o\'or de regel met
1684    \begin{verbatim}
1685    http_access deny all
1686    \end{verbatim}
1687    Alle computers op ons eigen netwerkje, met IP adres 10.1.1.x dus, kunnen dus
1688    toegang krijgen tot onze proxyserver. Eventueel kan je meerdere ACL's opstellen
1689    (bijvoorbeeld PC-zalen, sekretariaatscomputers,~\ldots) die dan allemaal een
1690    aparte configuratie kunnen krijgen.
1691    
1692  \section{Installatie}  Er is nog veel meer mogelijk, bijvoorbeeld bepaalde (stukken van) websites blokkeren;
1693  We beginnen klein met  zie bijvoorbeeld \url{http://www.squid-cache.org/Doc/FAQ/FAQ.html} voor meer informatie.
 \begin{center}\commando{apt-get install webmin-core}\end{center}  
 Later kunnen we dan de nodige modules toevoegen.  
1694    
1695  Tijdens het installeren krijgen we de melding dat webmin een eigen gebruikerlijst  We kunnen de configuratie snel uittesten door vanop \'e\'en van de toegelaten computers
1696  bijhoudt in \file{/etc/webmin/miniserv.users}; standaard maakt het installatieproces  eens \commando{lynx http://mijn.favoriete/website} te doen, waarbij we eerst
1697  een gebruiker ``root'' aan met hetzelfde wachtwoord als het Unix wachtwoord van root.  met
1698  Er zullen dus twee verschillende lijsten met gebruikers en wachtwoorden actief zijn:  \begin{verbatim}
1699  \'e\'en van Webmin en \'e\'en van ons Unix besturingssysteem. Dit heeft als voordeel  export http_proxy="http://debianserver:3128"
1700  dat we een Webmin-gebruiker kunnen maken zonder dat we die een volledige Unix  \end{verbatim}
1701  account moeten geven (we zullen verderop ``secretariaat'' aanmaken) en als we daar niet zo  aangeven dat \commando{lynx} onze proxyserver (die draait op de computer
1702  van houden kunnen we een Webmin-gebruiker aanmaken met dezelfde naam als  \texttt{debianserver}) moet gebruiken. Als het goed is krijgen we de gevraagde pagina te zien.
1703  een Unix-gebruiker en Webmin vragen om de wachtwoorden gelijk te houden (als  
1704  de gebruiker haar Unix wachtwoord aanpast, zal het Webmin wachtwoord automatisch  
1705  mee veranderen en omgekeerd).  %%%[[[ hoe gewone gateway maken zonder masquerading? ]]]
1706  Verder wordt ons nog de \textit{hostname} gevraagd; het voorstel van de installer is meestal  
1707  in orde.  %%%\section{Linux als firewall}
1708    %%% [[[ PENDING ]]]
1709    
1710    \chapter{Regelmatig terugkerende taken}
1711    \section{Taken uitvoeren bij het opstarten}
1712    \subsection{Eigen scripts}
1713    \index{/etc/rc.boot}\label{etc_rcboot}%
1714    Als je een bepaalde actie, laten we zeggen het uitkuisen van de \file{/tmp}
1715    directory bij het opstarten met \commando{rm -rf /tmp}, bij elke herstart van
1716    de computer wil laten uitvoeren, volstaat het een scriptbestandje te maken
1717    en dat in \file{/etc/rc.boot/} te plaatsen. De eerste lijn moet van de vorm
1718    \verb|#!/bin/shellnaam| zijn en het bestand moet uitvoerbaar zijn. We kunnen dus
1719    een bestand maken \file{/etc/rc.boot/kuisTmp} met inhoud
1720    \begin{verbatim}
1721    #!/bin/sh
1722    rm -rf /tmp/*
1723    \end{verbatim}
1724    en natuurlijk niet vergeten \commando{chmod a+x /etc/rc.boot/kuisTmp} te doen.
1725    
1726    \subsection{Systeemdiensten}
1727    Er worden bij het opstarten ook een aantal diensten opgestart.
1728    Diensten staan beschreven in scripts in \file{/etc/init.d/}: de dienst \file{keymap.sh}
1729    zorgt voor het instellen van het toetsenbord, \file{networking} is in staat het netwerk
1730    te starten of te stoppen, enzovoort. Al deze scripts hebben als mogelijke opties
1731    op zijn minst \file{stop} en \file{start} als opties, dus je kunt manueel het netwerk
1732    stoppen met
1733    \begin{center}\commando{/etc/init.d/networking stop}\end{center}
1734    In de directory \file{etc/rcS.d/} staan alle diensten beschreven die moeten gestart
1735    worden wanneer de computer opgestart wordt. Het zijn allemaal symbolische links
1736    naar scripts in de \file{/etc/init.d} directory, met een speciale naamgeving: de eerste
1737    letter is een \texttt{S} (om aan te geven dat een dienst gestart moet worden;
1738    \texttt{K} kan in principe ook om een dienst te stoppen (\texttt{K}ill) maar is nogal
1739    onzinnig bij het opstartproces), gevolgd door twee cijfers, gevolgd door de naam van de dienst.
1740    De twee cijfers geven aan wanneer de dienst moet gestart worden: diensten met het laagste
1741    getal worden het eerst opgestart.
1742    
1743    \section{Taken regelmatig uitvoeren: cron}
1744    Elke gebruiker kan een tabel aanmaken van taken die hij regelmatig uitgevoerd wil zien.
1745    Deze tabel kan je bewerken met het commando \commando{crontab -e}.
1746    Elke regel bevat een aantal velden: minuut, uur, dag van de maand, maand, dag
1747    van de week (1 is maandag, 7 zondag) en uit te voeren commando. Bijvoorbeeld,
1748    om de \file{/tmp} directory elke zondag te wissen om 23 uur 59 voegen we een lijn
1749    \begin{verbatim}
1750    59 23 * * 7     rm -rf /tmp/*
1751    \end{verbatim}
1752    toe. De velden die er niet toe doen worden opgevuld met sterretjes. Je kan ook
1753    een bereik aangeven:
1754    \begin{verbatim}
1755    0 10-12 * * 1-5 echo Koffiepauze | lpr
1756    \end{verbatim}
1757    zal om 10u00, 11u00 en 12u00 tijdens weekdagen een blad afprinten met ``Koffiepauze'' erop.
1758    Je kan ook ``om de zoveel'' tijd iets laten gebeuren met `/':
1759    \begin{verbatim}
1760    0 8-17/2 * * 1-5        echo Koffiepauze | lpr
1761    \end{verbatim}
1762    zal om 8u00, 10u00,~\dots, 16u00 een blad afprinten: \texttt{8-17/2} betekent
1763    ``van 8 tot 17 uur, om de twee uur''. Je zou net zo goed
1764    \begin{verbatim}
1765    0 8,10,12,14,16 * * 1-5 echo Koffiepauze | lpr
1766    \end{verbatim}
1767    mogen geschreven hebben: met de komma kan je een lijst van tijdstippen opgeven.
1768    Combinaties van dit alles zijn ook mogelijk: om elke vijf minuten iets te doen kan je
1769    \begin{verbatim}
1770    */5 * * * *     iets
1771    \end{verbatim}
1772    doen.
1773    
1774    Wil je een taak een keer per dag, week of maand uitvoeren, dan kan je er ook voor kiezen
1775    een bestand bij te plaatsen in \file{/etc/cron.daily}, \file{/etc/cron.weekly}
1776    of \file{/etc/cron.monthly}. Het formaat is hetzelfde als in \file{etc/rc.boot}
1777    (zie~\S\ref{etc_rcboot}): de eerste lijn moet van de vorm
1778    \verb|#!/bin/shellnaam| zijn en het bestand moet uitvoerbaar zijn.
1779    
 \section{Gebruik van webmin}  
 We kunnen dan met onze browser de pagina \url{https://server:10000} bezoeken  
 (figuur~\ref{webminmain}). Het is (gelukkig maar) een beveiligde pagina, we moeten  
 dus eerst een gebruikersnaam (``root'' is de enige gekende naam na het installeren)  
 en een wachtwoord ingeven.  
 \begin{figure}[!h]  
 \begin{center}  
 \includegraphics[width=0.8\textwidth]{server/webminmain.png}  
 \caption{Het hoofdmenu van \commando{webmin}}  
 \label{webminmain}  
 \end{center}  
 \end{figure}  
 We kunnen bijvoorbeeld de optie \textit{Webmin Users} kiezen. We krijgen een  
 lijst van alle webmin gebruikers te zien. We kiezen  
 \textit{Create a new Webmin} om een webmin gebruiker ``secretariaat'' te maken  
 (figuur~\ref{webminuser}).  
 Deze gebruiker zal enkel nieuwe Unix gebruikers kunnen aanmaken  
 (bijvoorbeeld voor nieuwe studenten die een email account nodig hebben);  
 we selecteren dus enkel de module \textit{Users and Groups}. We  
 vergeten ook niet een wachtwoord te kiezen en drukken op \textit{Save}.  
 We keren dan weer terug naar de lijst van gebruikers. Eventueel kunnen we  
 nog fijner afstellen wat webmin gebruiker ``secretariaat'' allemaal wel en niet mag  
 binnen \textit{Users and Groups} door op de gelijknamige link te klikken.  
 \begin{figure}[!h]  
 \begin{center}  
 \includegraphics[width=0.8\textwidth]{server/webminuser.png}  
 \caption{Een nieuwe \commando{webmin} gebruiker aanmaken}  
 \label{webminuser}  
 \end{center}  
 \end{figure}  
 We herstarten onze browser eens en loggen in als ``secretariaat'' en zie: deze gebruiker  
 kan enkel maar de module \textit{Users and Groups} gebruiken  
 (figuur~\ref{webminsecretariaat}).  
 \begin{figure}[!h]  
 \begin{center}  
 \includegraphics[width=0.8\textwidth]{server/webminsecretariaat.png}  
 \caption{Een \commando{webmin} gebruiker heeft toegang tot maar enkele (hier zelfs maar \'e\'en) configuratiemodule}  
 \label{webminsecretariaat}  
 \end{center}  
 \end{figure}  
1780    
1781  \chapter{Elementair systeembeheer}  \chapter{Elementair systeembeheer}
1782  Als superuser hebben we de volledige macht over het systeem:  Als superuser hebben we de volledige macht over het systeem:
# Line 2846  kan je het resultaat met \commando{less} Line 2040  kan je het resultaat met \commando{less}
2040  SSH-verbindingen openstaan van onze computer (157.193.53.222) naar  SSH-verbindingen openstaan van onze computer (157.193.53.222) naar
2041  ``ergens.be'' en ``ergensanders.be''. Verder zien we dat er iemand onlangs  ``ergens.be'' en ``ergensanders.be''. Verder zien we dat er iemand onlangs
2042  een WWW-connectie heeft gelegd met ``157.193.41.38'' (er staat TIME\_WAIT,  een WWW-connectie heeft gelegd met ``157.193.41.38'' (er staat TIME\_WAIT,
2043  hetgeen betekent dat de verbinding onlangs be\"eindigd geweest is).  hetgeen betekent dat de verbinding onlangs be\"eindigd werd).
2044    
2045  Met \commando{host 157.193.41.38} kunnen we de naam van ``157.193.41.38'' achterhalen:  Met \commando{host 157.193.41.38} kunnen we de naam van ``157.193.41.38'' achterhalen:
2046  \begin{verbatim}  \begin{verbatim}
# Line 2948  paswoordfile in hoofletters laat zien. Line 2142  paswoordfile in hoofletters laat zien.
2142  spaties te converteren naar tabs, gebruiken we \com{unexpand}.  spaties te converteren naar tabs, gebruiken we \com{unexpand}.
2143  \end{itemize}  \end{itemize}
2144    
2145  \chapter{WWW proxy}  \chapter{Systeembeheer via het web: webmin}
2146  Een proxyserver is een server die clients gebruiken om verbinding te leggen met  Webmin is een systeem dat een webservertje draait dat we kunnen gebruiken om onze
2147  een andere computer, in plaats van rechtstreeks een verbinding met de bestemmeling  server te configureren. De basismodule heet ``webmin'', maar die bevat niet veel meer
2148  te leggen. De proxyserver zelf zal dan de bestemmeling contacteren.  dan de webmin-webserver zelf. Voor al de rest hebben we extra webmin-modules nodig,
2149  Een proxyserver werkt dus altijd voor \'e\'en bepaald protocol;  en zo zijn er genoeg: het commando \commando{apt-cache search webmin} levert
2150  in dit geval zullen we de WWW-proxyserver \begrip{squid} bespreken.  \begin{verbatim}
2151    webmin - Web-based administration toolkit
2152    webmin-apache - apache control module for webmin
2153    webmin-bind8 - bind 8+ control module for webmin
2154    webmin-burner - CD burning module for webmin
2155    webmin-cluster-software - cluster software control module for webmin
2156    webmin-cluster-useradmin - cluster user control module for webmin
2157    webmin-core - core modules for webmin
2158    webmin-cpan - CPAN module for webmin
2159    webmin-dhcpd - dhcpd control module for webmin
2160    webmin-exports - NFS exports control module for webmin
2161    webmin-fetchmail - fetchmail mail retrieval module for webmin
2162    webmin-grub - grub control module for webmin
2163    webmin-heartbeat - heartbeat monitor control module for webmin
2164    webmin-inetd - inetd control module for webmin
2165    webmin-jabber - jabber server control module for webmin
2166    webmin-lpadmin - printer control module for webmin
2167    webmin-mon - mon control module for webmin
2168    webmin-mysql - mysql-server control module for webmin
2169    webmin-nis - NIS clients/servers control module for webmin
2170    webmin-postfix - postfix control module for webmin
2171    webmin-postgresql - postgresql control module for webmin
2172    webmin-ppp - PPP configuration module for webmin
2173    webmin-qmailadmin - qmail control module for webmin
2174    webmin-quota - disk quota control module for webmin
2175    webmin-raid - raid control module for webmin
2176    webmin-samba - samba control module for webmin
2177    webmin-sendmail - sendmail control module for webmin
2178    webmin-software - software packages control module for webmin
2179    webmin-squid - squid control module for webmin
2180    webmin-sshd - SSH server control module for webmin
2181    webmin-status - server and system status control module for webmin
2182    webmin-stunnel - stunnel control module for webmin
2183    webmin-wuftpd - wu-ftpd control module for webmin
2184    webmin-xinetd - xinetd control module for webmin
2185    \end{verbatim}
2186    
2187    \section{Installatie}
2188    We beginnen klein met
2189    \begin{center}\commando{apt-get install webmin-core}\end{center}
2190    Later kunnen we dan de nodige modules toevoegen.
2191    
2192    Tijdens het installeren krijgen we de melding dat webmin een eigen gebruikerlijst
2193    bijhoudt in \file{/etc/webmin/miniserv.users}; standaard maakt het installatieproces
2194    een gebruiker ``root'' aan met hetzelfde wachtwoord als het Unix wachtwoord van root.
2195    Er zullen dus twee verschillende lijsten met gebruikers en wachtwoorden actief zijn:
2196    \'e\'en van Webmin en \'e\'en van ons Unix besturingssysteem. Dit heeft als voordeel
2197    dat we een Webmin-gebruiker kunnen maken zonder dat we die een volledige Unix
2198    account moeten geven (we zullen verderop ``secretariaat'' aanmaken) en als we daar niet zo
2199    van houden kunnen we een Webmin-gebruiker aanmaken met dezelfde naam als
2200    een Unix-gebruiker en Webmin vragen om de wachtwoorden gelijk te houden (als
2201    de gebruiker haar Unix wachtwoord aanpast, zal het Webmin wachtwoord automatisch
2202    mee veranderen en omgekeerd).
2203    Verder wordt ons nog de \textit{hostname} gevraagd; het voorstel van de installer is meestal
2204    in orde.
2205    
2206    \section{Gebruik van webmin}
2207    We kunnen dan met onze browser de pagina \url{https://server:10000} bezoeken
2208    (figuur~\ref{webminmain}). Het is (gelukkig maar) een beveiligde pagina, we moeten
2209    dus eerst een gebruikersnaam (``root'' is de enige gekende naam na het installeren)
2210    en een wachtwoord ingeven.
2211    \begin{figure}[!h]
2212    \begin{center}
2213    \includegraphics[width=0.8\textwidth]{server/webminmain.png}
2214    \caption{Het hoofdmenu van \commando{webmin}}
2215    \label{webminmain}
2216    \end{center}
2217    \end{figure}
2218    We kunnen bijvoorbeeld de optie \textit{Webmin Users} kiezen. We krijgen een
2219    lijst van alle webmin gebruikers te zien. We kiezen
2220    \textit{Create a new Webmin} om een webmin gebruiker ``secretariaat'' te maken
2221    (figuur~\ref{webminuser}).
2222    Deze gebruiker zal enkel nieuwe Unix gebruikers kunnen aanmaken
2223    (bijvoorbeeld voor nieuwe studenten die een email account nodig hebben);
2224    we selecteren dus enkel de module \textit{Users and Groups}. We
2225    vergeten ook niet een wachtwoord te kiezen en drukken op \textit{Save}.
2226    We keren dan weer terug naar de lijst van gebruikers. Eventueel kunnen we
2227    nog fijner afstellen wat webmin gebruiker ``secretariaat'' allemaal wel en niet mag
2228    binnen \textit{Users and Groups} door op de gelijknamige link te klikken.
2229    \begin{figure}[!h]
2230    \begin{center}
2231    \includegraphics[width=0.8\textwidth]{server/webminuser.png}
2232    \caption{Een nieuwe \commando{webmin} gebruiker aanmaken}
2233    \label{webminuser}
2234    \end{center}
2235    \end{figure}
2236    We herstarten onze browser eens en loggen in als ``secretariaat'' en zie: deze gebruiker
2237    kan enkel maar de module \textit{Users and Groups} gebruiken
2238    (figuur~\ref{webminsecretariaat}).
2239    \begin{figure}[!h]
2240    \begin{center}
2241    \includegraphics[width=0.8\textwidth]{server/webminsecretariaat.png}
2242    \caption{Een \commando{webmin} gebruiker heeft toegang tot maar enkele (hier zelfs maar \'e\'en) configuratiemodule}
2243    \label{webminsecretariaat}
2244    \end{center}
2245    \end{figure}
2246    
2247    \chapter{De shell}
2248    \label{bash}
2249    
2250    \citaatnnn{How many Unix hacks does it take to change a light bulb?\\
2251    Let's see, can you use a shell script for that or does it need a C program?}
2252    
2253    \section{Inloggen, een shell kiezen}
2254    
2255    Wanneer een gebruiker op een systeem inlogt (zie \ref{basiscommandos})
2256    wordt zijn identiteit gecontroleerd door middel van een password.  Na
2257    het inloggen wordt een proces gestart dat een uitvoerbaar bestand (zie
2258    \ref{chmod}) ge\"assoc\"\i eerd met de gebruiker uitvoert.  Het
2259    bestand dat uitgevoerd wordt is afhankelijk van het systeem, maar is
2260    gebaseerd op de inhoud van \file{/etc/passwd}.
2261    
2262    Een stukje uit \file{/etc/passwd}:
2263    
2264    \input{server/passwd}
2265    
2266    Normaal gezien is dit uitvoerbaar bestand het \begrip{shell} programma
2267    dat commando's interactief inleest van de gebruiker en ze uitvoert.
2268    
2269    Merk op dat de shell geen deel uit maakt van het besturingssysteem;
2270    het is perfect mogelijk (en dit wordt vaak gedaan) om een ander
2271    programma in \file{/etc/passwd} in te vullen.  Bijvoorbeeld, men zou
2272    een gebruiker ``date'' kunnen defini\"eren ge\"associ\"eerd met het
2273    programma \com{/usr/bin/date}.  Elke keer dat ``date'' inlogt zal het
2274    programma \com{/usr/bin/date} gestart worden.  Interessanter is dat we
2275    hierdoor een beperkte shell kunnen opgeven aan een gebruiker zoals
2276    \com{/bin/false} waardoor een gebruiker niet kan inloggen.
2277    
2278    In dit hoofdstuk geven we een introductie tot een van de meest
2279    gebruikte shell programma's: \begrip{Bash} (\begrip{Bourne again
2280      shell}\footnote{Bourne is de ontwikkelaar van de oude ``Bourne
2281      shell'' \file{/bin/sh} (dat nog veel gebruikt wordt voor shell
2282      scripts en beschikbaar is op iedere \unix)})
2283    
2284    Na wat ervaring opgedaan te hebben met bash merken we heel vlug dat
2285    het gebruik van de command-line resulteert in een hogere
2286    productiviteit dan als we de zogenaamde GUI's zouden gebruiken.  Dit
2287    is niet verrassend als men vergelijkt hoeveel moeite er nodig is om
2288    iets in te tikken tegenover het voortdurend slepen en klikken met de
2289    muis\footnote{Natuurlijk veronderstelt het gebruik van de shell iets
2290      meer kennis van het systeem.}.
2291    
2292    \section{Basis bash}
2293    
2294    Het gedrag van de shell kan het best begrepen worden met de volgende pseudocode:
2295    
2296    \begin{verbatim}
2297    while(true){
2298      bool background = false;
2299      show promt on screen # if interactive
2300      read a command line from input
2301      if (the command line consists of <eof> only)
2302        exit
2303      if (the command line ends with '&')
2304        background = true
2305      perform substitutions and
2306        split command line into words #details later
2307      find an executable file F that corresponds to
2308        the first word (taking \$PATH into account)
2309      create a new child process and let it
2310        exec(F, path-of-F, 2nd word, 3rd word, ...)
2311      if (not background)
2312        wait for the child process to finish
2313    }
2314    \end{verbatim}
2315    
2316    Zodat ieder commando van de vorm \com{command parameter$_1$ ...
2317      parameter$_n$} zal resulteren in een nieuw proces dat \com{command}
2318    uitvoert met parameter$_1$ tot parameter$_n$.  Dus, als \com{command}
2319    een gecompileerd C programma is zal zijn \com{main} functie
2320    aangeroepen worden als \com{main(n+1,argv,envp)} dat dan uitgevoerd zal worden.
2321    
2322    \section{PATH}
2323    
2324    We hebben reeds gezien (\ref{sec:verschdirs}) dat de meeste
2325    programma's zich in \file{/usr/} en \file{/bin/} bevinden.  Het zou
2326    dus heel ineffici\"ent zijn om telkens het volledige \begrip{PATH} op
2327    te geven. B.v. \com{/usr/bin/less /etc/passwd} telkens intikken kost
2328    veel tijd.  Gelukkig gebruikt de shell een PATH environment variabele
2329    om de volledige padnaam te construeren.  De waarde van PATH is een
2330    lijst van directories gescheiden door dubbele punten (:).  Als een
2331    ingegeven commando geen volledig of relatief pad bevat wordt er in die
2332    directories gekeken naar dat commando.  
2333    
2334    Meestal ziet het PATH environment variabele als
2335    \com{.:/bin:/usr/bin:/usr/local/bin} uit. Dus \com{less /etc/passwd} heeft
2336    hetzelfde als daarjuist.
2337    
2338    Het is interessant in te zien dat als de huidige directory (``.'')
2339    zich niet in het PATH bevindt een programma dat zich in de huidige
2340    directory bevindt niet zal uitgevoerd worden. We kunnen dan de huidige
2341    directory (``.'') aan ons PATH toevoegen of het programma
2342    \file{mijnprogramma} uitvoeren met \com{./mijnprogramma}.
2343    
2344    We kunnen het PATH environment variabele bekijken door \com{echo
2345      \$PATH} in te tikken.  Eveneens kunnen we het PATH aanpassen door
2346    \com{export PATH=/lijst/van:/directories} op te geven.  Wanneer we het
2347    ingestelde PATH willen uitbreiden kunnen we \com{export
2348      PATH=\$PATH:/lijst/van:/directories} in geven.
2349    
2350    \begin{opgave}
2351    Bestudeer je huidige PATH en pas het aan.
2352    \end{opgave}
2353    
2354    Merk op dat wanneer we ons PATH zo veranderen deze wijziging geldt
2355    voor deze shell sessie.  Loggen we uit en terug in dan is de wijziging
2356    verdwenen.  In \ref{startup} zien we hoe we de wijziging vastleggen.
2357    
2358    \section{Achtergrond processen}
2359    
2360    In \ref{bgjobs} hebben we reeds hierover gesproken.  We geven een heel
2361    korte samenvatting.  Door een \begrip{\&} na een commando te plaatsen
2362    voeren we het commando uit in de achtergrond.  Met \com{fg} plaatsen
2363    we het dan terug op de voorgrond.
2364    
2365    \section{History}
2366    
2367    Bash houdt een lijst bij van de reeds ingegeven processen, de
2368    \begrip{history}.
2369    
2370    \begin{opgave}
2371    Tik de naar boven en naar beneden pijtjes toetsen in.
2372    \end{opgave}
2373    
2374    De reeds ingegeven commando's kunnen we dan bekijken en opnieuw
2375    uitvoeren of aanpassen.
2376    
2377    \section{I/O redirection}
2378    
2379    Zoals we in \ref{ioredirection} reeds zagen kunnen we de uitvoer van
2380    en de invoer naar een programma omleiden.  We introduceren nog extra
2381    begrip: \begrip{/dev/null}.
2382    
2383    \file{/dev/null} kan als de vergeetput aanzien worden.  Alles wat we
2384    naar \file{/dev/null} omleiden zien we nooit meer terug.  Tikken we
2385    \com{cat /etc/passwd $>$ /dev/null} in dan zien we geen output.  Voor
2386    zulke toepassingen is dit niet zo interessant, maar wat als we een
2387    proces hebben dat foutmeldingen geeft waar we niet ge\"\i nteresseerd
2388    in zijn?
2389    
2390    We kunnen dan \begrip{2$>$} gebruiken: \com{programma 2$>$/dev/null}
2391    stuurt alle foutmeldingen dat \file{programma} op het scherm zet naar
2392    \file{/dev/null}.
2393    
2394    \section{Bash opstart bestanden}
2395    \label{startup}
2396    Elke shell heeft een aantal initialisatie-bestanden. Dit wil zeggen,
2397    bestanden met shell-bevelen die altijd uitgevoerd worden wanneer de
2398    gebruiker een nieuwe shell start. Typisch zijn de namen van die
2399    initialisatie-bestanden gevormd uit de naam van de shell met
2400    daarachter ``\file{rc}'' (wat oorspronkelijk stond voor ``resource
2401    configuration''). Zo heeft een typische \gl-installatie voor de bash
2402    shell de bestanden \file{/etc/bash.bashrc} (voor ``system wide''
2403    initialisatie) en een verborgen bestand \file{.bashrc} in de home
2404    directory van elke gebruiker. Het system wide initialisatie-bestand
2405    wordt eerst uitgevoerd, en daarna de \file{.bashrc} van de gebruiker.
2406    
2407    \section{Aliases}\label{sec:alias}
2408    
2409    Gebruikers kunnen (reeksen van) bevelen die ze vaak gebruiken afkorten
2410    met het \begrip{alias} bevel. (En opslaan in hun \file{.bashrc}.)  Een
2411    voorbeeld is \com{alias ll=''ls -l''}.  Als dit bevel is uitgevoerd
2412    levert \com{ll} hetzelfde resultaat als \com{ls -l} voordien.
2413    
2414    Om het aantal alias-definities in het bestand \file{.login} te tellen
2415    kunnen we het volgende bevel uitvoeren: \com{cat .login $\mid$ grep
2416      alias $\mid$ wc -l}.  Het eerste bevel toont het bestand met
2417    omgevingsvariabelen.  Op dit resultaat wordt dan het \com{grep} bevel
2418    toegepast.  Dit bevel weerhoudt alleen de lijnen waarin het woord
2419    ``alias'' voorkomt.  Tenslotte telt \com{wc} (word count) het aantal
2420    lijnen (dankzij de optie -l).  Het resultaat van de hele regel is dus
2421    het aantal aliases dat in .login is gedefini\"eerd.  Als we met bash
2422    werken moeten we het bestand \file{.bashrc} doorzoeken in plaats van
2423    \file{.login}.
2424    
2425    In dit bestand kunnen we ook onze PATH plaatsen.  Wat volgt is een
2426    voorbeeld \file{.bashrc} bestand.
2427    
2428    \begin{verbatim}
2429    # ~/.bashrc: executed by bash(1) for non-login shells.
2430    # see /usr/share/doc/bash/examples/startup-files for examples
2431    
2432    # If running interactively, then:
2433    if [ "$PS1" ]; then
2434    
2435        # enable color support of ls and also add handy aliases
2436    
2437        eval `dircolors`
2438        alias ls='ls --color=auto '
2439        alias ll='ls -l'
2440        alias la='ls -A'
2441        alias l='ls -CF'
2442        alias dir='ls --color=auto --format=vertical'
2443        alias vdir='ls --color=auto --format=long'
2444    
2445    fi
2446    mesg y
2447    export TERM=linux
2448    export EDITOR=emacs
2449    export RTF2LATEX2E_DIR=/usr/local/rtf2latex2e
2450    alias eduserv='ssh rgevaert@eduserv1.rug.ac.be'
2451    alias lugwv='/usr/bin/BitchX -c \#lugwv webworm irc.chat.be'
2452    alias tinnr='tin -nr'
2453    alias tin='tin -r'
2454    IRCNICK=webworm
2455    IRCUSER=riper
2456    IRCNAME="http://www.webworm.org"
2457    IRCSERVER=irc.chat.be
2458    export IRCNICK IRCUSER IRCNAME IRCSERVER
2459    alias afsluiten='sudo /sbin/shutdown -h now'
2460    #fetchmail -d 200 2> /dev/null
2461    PATH=$PATH:$HOME/bin:.:/usr/local/jdk1.3.1/bin
2462    \end{verbatim}
2463    
2464    \section{Programmeren in de shell}
2465    
2466    De shell geeft niet alleen bevelen door aan het besturingssysteem,
2467    maar kan ook \begrip{shell scripts} interpreteren en uitvoeren.  Een
2468    shell script is een bestand dat een aantal shell bevelen bevat.  Het
2469    bestand is uitvoerbaar gemaakt (zie \ref{chmod}), en zijn eerste regel
2470    geeft aan welke shell het bestand moet interpreteren.  
2471    
2472    Deze eerste regel is eigenlijk een commentaar-lijn, en begint met het
2473    commentaar-teken (\#), gevolgd door een uitroepteken, en het volledige
2474    pad van het shell-programma.  Bijvoorbeeld: \verb~#!/bin/sh~ is de
2475    eerste lijn van alle voorbeelden en oefeningen van deze cursus, en ze
2476    zegt dat de Bourne shell de interpreter is van het script.
2477    
2478    Dit tekstbestand kan op twee manieren worden uitgevoerd:
2479    \begin{enumerate}
2480    \item Duid expliciet de interpreter van het bestand aan: \com{/bin/sh
2481        scriptname}.
2482    \item Laat het bestand interpreteren door de huidige shell: \file{
2483        ./scriptname}.  Hiervoor moet het script eerst uitvoerbaar gemaakt
2484      worden met behulp van \com{chmod}.
2485    \end{enumerate}
2486    
2487    \section{Variabelen}
2488    
2489    Zoals de meeste talen kent ook shell scripting variabelen.  En zoals
2490    in de meeste ge\"{\i}nterpreteerde talen hebben shell variabelen geen
2491    expliciet aangegeven type.  Een nieuwe variabele wordt aangemaakt door
2492    een nieuwe naam te gebruiken.  Daarom is het bij scripting zeer
2493    belangrijk om het script op fouten te controleren.
2494    Enkele voorbeelden zijn.\\
2495    \hspace{3cm} \texttt{aantal=5}\\
2496    \hspace{3cm} \texttt{voornaam=Rudy}\\
2497    \hspace{3cm} \texttt{achternaam=Gevaert}\\
2498    Het is zeer belangrijk dat er voor en na = geen spaties worden
2499    geplaatst, anders weet de shell niet hoe het commando moet worden
2500    ge\"{i}nterpreteerd. De waarde van een variabele wordt opgevraagd
2501    door er een dollarteken (\$) voor te plaatsen.  Vb:\\
2502    \begin{verbatim}
2503    naam="$voornaam $achternaam"
2504    \end{verbatim}
2505    ~\\
2506    Het \com{echo} bevel schrijft de waarde op het scherm. Ook hier
2507    gebruiken we het dollarteken:\\
2508    \begin{tabbing}
2509    \com{echo naam}\hspace{3cm}\=  resultaat: {\tt naam}\\
2510    \com{echo \$naam}\> resultaat: {\tt Rudy Gevaert}\\
2511    \end{tabbing}
2512    ~\\
2513    
2514    Anderzijds leest het \com{read} bevel een waarde in, zie het voorbeeld
2515    in \ref{readvar}.
2516    
2517    \begin{figure}
2518    \begin{verbatim}
2519    #!/bin/sh
2520    eentekst="Shell programmeren is fijn"
2521    echo $eentekst
2522    echo "Typ nu zelf een regel in"
2523    read eentekst
2524    echo $eentekst
2525    \end{verbatim}
2526    \caption{}
2527    \label{readvar}
2528    \end{figure}
2529    
2530    Dit voorbeeldje laat zien hoe de variabele \com {eentekst} eerst een
2531    initi\"ele waarde krijgt, en hoe die in de volgende stap uitgeschreven
2532    wordt. Daarna wordt er gevraagd om zelf een regel in te typen; die
2533    wordt ingelezen in de variabele \file{eentekst} en daarna
2534    uitgeschreven. Een ander voorbeeldje vinden we in \ref{readvar2}
2535    
2536    \begin{figure}
2537    \begin{verbatim}
2538    #!/bin/sh
2539    echo "geef je voor- en achternaam, gevolgd door je universiteit,"
2540    echo "je richting en je hobbies"
2541    read voornaam achternaam universiteit richting hobbies
2542    echo "voornaam: $voornaam"
2543    echo "achternaam: $achternaam"
2544    echo "universiteit: $universiteit"
2545    echo "richting: $richting"
2546    echo "hobbies: $hobbies"
2547    \end{verbatim}
2548    \caption{}
2549    \label{readvar2}
2550    \end{figure}
2551    
2552    Als we bij het programma voorgesteld in \ref{readvar2} de invoer
2553    ``\com{Rudy Gevaert RUG informatica Savannah moderator}'' intypen
2554    zullen we de volgende uitvoer bekomen:
2555    
2556    \begin{verbatim}
2557    voornaam: Rudy
2558    achternaam: Gevaert
2559    universiteit: RUG
2560    richting: informatica
2561    hobbies: Savannah moderator
2562    \end{verbatim}
2563    
2564    
2565    De \gl\ shells kennen ook een reeks ingebouwde variabelen,
2566    waarvan de waarde kan worden opgevraagd.\\
2567    
2568    \begin{tabbing}
2569    \texttt{\$\#}\hspace{1cm} \= Het aantal argumenten dat aan het script is meegegeven.\\
2570    \texttt{\$?} \> De exit waarde van het commando dat het laatste is uitgevoerd.\\
2571    \texttt{\$0} \> De naam van het shell script (dit is impliciet het eerste argument).\\
2572    \texttt{\$*} \> De positionele parameters \$1, \$2,\ldots die de parameters bevatten.\\
2573                 \> Vervang * door het gewenste parameter nummer.\\
2574    \texttt{\$@} \> De volledige lijst van parameters (een ``array'' van alle argumenten).\\
2575    \texttt{\$\$} \> Het ID van het huidige proces.\\
2576    % \texttt{\$LOGNAME}\>De login naam van de huidige gebruiker.\\
2577    \end{tabbing}
2578    
2579    Deze ingebouwde variabelen kunnen gebruikt worden in shell scripts,
2580    zoals getoond in figuur \ref{ingebvar}.
2581    
2582    \begin{figure}
2583    \begin{verbatim}
2584    #!/bin/sh
2585    echo the name for this script is $0 and it has $# arguments
2586    echo the first argument of this script is $1
2587    echo the fifth argument of this script is $5
2588    \end{verbatim}
2589    \caption{}
2590    \label{ingebvar}
2591    \end{figure}
2592    
2593    Nu kunnen we desgewenst ook argumenten meegeven als we shell scripts
2594    gaan schrijven.
2595    
2596    \section{Speciale karakters}
2597    
2598    Elke shell heeft een reeks van speciale karakters.  Deze paragraaf
2599    bespreekt er vier belangrijke: double quotes ("), single quotes
2600    (\com{''}), back slash (\textbackslash) en back tick (\com{`}).
2601    
2602    Double quotes worden gebruikt om een string die spaties bevat uit te
2603    schrijven of toe te kennen aan een variabele.  Als de double quotes
2604    worden weggelaten, interpreteert de shell ieder woord als een nieuw
2605    bevel.  Hierdoor zouden ernstige fouten kunnen ontstaan bij de
2606    uitvoering van het script.  De waarden van variabelen worden nog
2607    steeds ingevuld.
2608    
2609    Single quotes zijn sterker dan double quotes.  Een string die tussen
2610    single quotes staat wordt letterlijk ge\"{i}nterpreteerd.  Indien
2611    slechts een gedeelte van een expressie letterlijk moet worden genomen,
2612    dan kan men best double quotes gebruiken in combinatie met de back
2613    slash.  Dit teken zorgt er namelijk voor dat het volgend teken
2614    letterlijk wordt genomen.
2615    Vb.:\\
2616    \begin{tabbing}
2617    \com{echo Hello \$LOGNAME}\hspace{3cm}\=resultaat: {\tt Hello craymaek}\\
2618    \com{echo 'Hello \$LOGNAME'}\>resultaat: {\tt Hello \$LOGNAME}\\
2619    \com{echo Hello \textbackslash\$LOGNAME}\>resultaat: {\tt Hello \$LOGNAME}\\
2620    \end{tabbing}
2621    
2622    Met behulp van de back tick (\com{`}) en het \com{expr} commando kan
2623    het resultaat van een bewerking aan een variabele worden toegekend.
2624    Dit wordt getoond in \ref{toekvar}.
2625    
2626    \begin{figure}
2627    \begin{verbatim}
2628    een=1
2629    twee=`expr $een + 1`
2630    echo $twee
2631    datum=`date`
2632    echo $datum
2633    \end{verbatim}
2634    \caption{Variabelen en expressies}
2635    \label{toekvar}
2636    \end{figure}
2637    
2638    De back tick wordt ook gebruikt om een string \Begrip{uit te voeren},
2639    d.w.z., de shell interpreteert de string als een shell bevel.
2640    Bijvoorbeeld, het bevel \com{info=`ls`} stelt de variabele info niet
2641    gelijk aan ``ls'', maar aan de inhoud van de huidige directory.
2642    
2643    \section{Vergelijken van expressies}
2644    
2645    Het commando om een logische expressie te evalueren is \com{test}.  De
2646    syntax is \com{test expressie}. Vaak worden vierkante haakjes gebruikt
2647    in plaats van het test commando: \com{[ expressie ]}.  Het resultaat
2648    is in beide gevallen hetzelfde. Tabellen \ref{tab:intexpr},
2649    \ref{tab:strexpr}, \ref{tab:bestexpr} en \ref{tab:logexpr}
2650    geven de verschillende expressie weer.  Enkele voorbeelden van
2651    expressies zijn:
2652    
 Het gebruik van een proxyserver lijkt nogal een overbodige bedoening: waarom niet  
 gewoon rechtstreeks een verbinding leggen met de bestemmeling, in plaats van  
 rond te gaan via de proxy? Er zijn twee voordelen aan de proxy-aanpak:  
2653  \begin{itemize}  \begin{itemize}
2654  \item Beveiliging: we kunnen onze firewall zo instellen dat er geen WWW-trafiek          \item \com{[ 5 -eq 6 ]} geeft vals
2655  van binnen ons netwerk naar buiten wordt toegelaten, tenzij vanop de proxyserver.          \item \com{[ -n lala ]} geeft waar
2656  De proxyserver zelf moet uiteraard wel WWW-verbindingen kunnen opzetten naar buiten.          \item \com{[ -d /dev ]} geeft waar
2657  Op die manier kunnen we binnen de proxyserver instellen wie welke WWW-pagina's          \item \com{[ -f /home ]} geeft vals
 wel of niet te zien mag krijgen.  
 \item Efficientie: de proxyserver heeft ook een \begrip{cache} aan boord van recent  
 opgevraagde webpagina's. Pagina's die in de cache zitten, zal de proxyserver niet meer  
 opnieuw bij de originele webserver opvragen, maar rechtstreeks uit de cache halen.  
 Op die manier sparen we heel wat netwerktrafiek uit als bijvoorbeeld een hele  
 PC-klas naar dezelfde site aan het surfen is.  
2658  \end{itemize}  \end{itemize}
 Het nadeel van de proxy-aanpak is dat de software van de client (in ons geval: de webbrowser)  
 in staat moet zijn met een proxy server om te gaan. Gelukkig is dat voor de meeste  
 moderne webbrowsers het geval.  
2659    
2660  \subsection{Installatie en configuratie}  Deze expressies komen pas helemaal tot hun recht bij conditionele expressies
2661  De installatie is zoals we dat van Debian gewoon zijn eenvoudig:  en condities voor het uitvoeren van herhalingslussen. Dit wordt besproken
2662  \begin{center}\commando{apt-get install squid}\end{center}  in de volgende secties.
2663    
2664    \begin{table} %START 1
2665    \begin{center}
2666    \begin{tabular}{|l|c|}\hline
2667    \textsf{Operator} & \textsf{Betekenis}\\ \hline
2668    int1 -eq int2 & int1 $=$\ int2 (equal)\\ \hline
2669    int1 -ge int2 & int1 $\ge$\ int2 (greater than or equal)\\ \hline
2670    int1 -gt int2 & int $>$\ int2 (greater than)\\ \hline
2671    int1 -le int2 & int1 $\le$\ int2 (less than or equal)\\ \hline
2672    int1 -lt int2 & int1 $<$\ int2 (less than)\\ \hline
2673    int1 -ne int2 & int1 $\ne$\ int2 (not equal)\\ \hline
2674    \end{tabular}
2675    \caption{Integer expressies}\label{tab:intexpr}
2676    \end{center}
2677    \end{table} % END 1
2678    
2679    \begin{table} % START 2
2680    \begin{center}
2681    \begin{tabular}{|l|c|}\hline
2682    \textsf{Operator} & \textsf{Betekenis}\\ \hline
2683    str1 = str2 & str1 $=$\ str2 (equal)\\ \hline
2684    str1 != str2 & str1 $\ne$\ str2 (not equal)\\ \hline
2685    str1 & str1 is niet null\\ \hline
2686    -n str1 & de lengte van str1 is groter dan 0\\ \hline
2687    -z str1 & de lengte van str1 is 0\\ \hline
2688    \end{tabular}
2689    \caption{String expressies}\label{tab:strexpr}
2690    \end{center}
2691    \end{table} % END 2
2692    
2693    \begin{table} % START 3
2694    \begin{minipage}{\textwidth}
2695    \begin{center}
2696    \begin{tabular}{|l|c|}\hline
2697    \textsf{Operator} & \textsf{Betekenis}\\ \hline
2698    -d \sl{bestandsnaam} & bestand (\sl{bestandsnaam})is een directory
2699    \footnote{in UNIX is een directory in weze ook een bestand} \\ \hline
2700    -f \sl{bestandsnaam} & bestand is een gewone file\\ \hline
2701    -r \sl{bestandsnaam} & bestand kan worden gelezen door het proces\\ \hline
2702    -s \sl{bestandsnaam} & bestand heeft een lengte groter dan 0\\ \hline
2703    -w \sl{bestandsnaam} & bestand kan worden beschreven door het proces\\ \hline
2704    -x \sl{bestandsnaam} & bestand kan worden uitgevoerd door het proces\\ \hline
2705    -e \sl{bestandsnaam} & bestand bestaat\\ \hline
2706    \end{tabular}
2707    \end{center}
2708    \end{minipage}
2709    \caption{Bestand expressies}\label{tab:bestexpr}
2710    \end{table} % END 3
2711    
2712    \begin{table} % START 4
2713    \begin{center}
2714    \begin{tabular}{|l|c|}\hline
2715    \textsf{Operator} & \textsf{Betekenis}\\ \hline
2716    ! expr1 & Negatie van expr1\\ \hline
2717    expr1 -a expr2 & expr1 en expr2\\ \hline
2718    expr1 -o expr2 & expr1 of expr2\\ \hline
2719    \end{tabular}
2720    \caption{Logische expressies}\label{tab:logexpr}
2721    \end{center}
2722    \end{table} %END 4
2723    
2724    \section{Conditionele expressies}
2725    De Bourne shell kent twee conditionele expressies: \com{if} en
2726    \com{case}.  De syntax van de if expressie is:
2727    
 De configuratie is ook niet zo moeilijk: we bewerken het omvangrijke bestand  
 \file{/etc/squid.conf}. We zullen twee regels toevoegen: de regel  
2728  \begin{verbatim}  \begin{verbatim}
2729  acl mijnclients src 10.1.1.0/24  if [ expressie ]
2730    then
2731            statements
2732    elif [ expressie ]
2733    then
2734            statements
2735    else
2736            statements
2737    fi
2738  \end{verbatim}  \end{verbatim}
2739  die een nieuwe `Access Control List' genaamd ``mijnclients'' aanmaakt  \bigskip
2740  (waarin iedereen zit met een IP adres van de vorm 10.1.1.x),  
2741  en een regel  Een voorbeeldje van het gebruik van een if-statement in een shell
2742    script vinden we in \ref{lst:ifvb}.
2743    
2744    \begin{figure}
2745  \begin{verbatim}  \begin{verbatim}
2746  http_access allow mijnclients  if [ $var = "Yes" ]
2747    then
2748            echo "Value is Yes"
2749    elif [ $var  = "No" ]
2750    then
2751            echo "Value is No"
2752    else
2753            echo "Invalid value"
2754    fi
2755  \end{verbatim}  \end{verbatim}
2756  die aangeeft dat iedereen in de lijst ``mijnclients'' toegang heeft tot onze proxyserver.  \caption{Conditionele expressies}
2757  Deze regel moet komen v\'o\'or de regel met  \label{lst:ifvb}
2758    \end{figure}
2759    
2760    \bigskip
2761    \bigskip
2762    
2763    De case expressie is vergelijkbaar met het switch bevel van C.  De
2764    syntax is beschreven in \ref{lst:casesyntax}.
2765    
2766    \begin{figure}
2767  \begin{verbatim}  \begin{verbatim}
2768  http_access deny all  case word in
2769            str1)
2770                    statements;;
2771            str2 | str3)
2772                    statements;;
2773            *)
2774                    statements;;
2775    esac
2776  \end{verbatim}  \end{verbatim}
2777  Alle computers op ons eigen netwerkje, met IP adres 10.1.1.x dus, kunnen dus  \caption{De syntax van case}
2778  toegang krijgen tot onze proxyserver. Eventueel kan je meerdere ACL's opstellen  \label{lst:casesyntax}
2779  (bijvoorbeeld PC-zalen, sekretariaatscomputers,~\ldots) die dan allemaal een  \end{figure}
 aparte configuratie kunnen krijgen.  
2780    
2781  Er is nog veel meer mogelijk, bijvoorbeeld bepaalde (stukken van) websites blokkeren;  \bigskip
 zie bijvoorbeeld \url{http://www.squid-cache.org/Doc/FAQ/FAQ.html} voor meer informatie.  
2782    
2783  We kunnen de configuratie snel uittesten door vanop \'e\'en van de toegelaten computers  Een voorbeeldje van het gebruik van een case-expressie in een shell
2784  eens \commando{lynx http://mijn.favoriete/website} te doen, waarbij we eerst  script vinden we in \ref{lst:casevb}.
2785  met  
2786    \begin{figure}
2787  \begin{verbatim}  \begin{verbatim}
2788  export http_proxy="http://debianserver:3128"  case $1 in
2789            01 | 1) echo "Month is January";;
2790            02 | 2) echo "Month is February";;
2791            03 | 3) echo "Month is March";;
2792            04 | 4) echo "Month is April";;
2793            05 | 5) echo "Month is May";;
2794            06 | 6) echo "Month is June";;
2795            07 | 7) echo "Month is July";;
2796            08 | 8) echo "Month is August";
2797            09 | 9) echo "Month is September";;
2798            10) echo "Month is October";;
2799            11) echo "Month is November";;
2800            12) echo "Month is December";;
2801            *) echo "Invalid Parameter";;
2802    esac
2803  \end{verbatim}  \end{verbatim}
2804  aangeven dat \commando{lynx} onze proxyserver (die draait op de computer  \caption{Case aan het werk}
2805  \texttt{debianserver}) moet gebruiken. Als het goed is krijgen we de gevraagde pagina te zien.  \label{lst:casevb}
2806    \end{figure}
2807    
2808    \bigskip
2809    \bigskip
2810    
2811    \section{Iteraties}
2812    
2813    Een iteratie in een shell script kan op drie verschillende manieren
2814    worden ge\"{i}mplementeerd: for, while en until.
2815    
2816    \subsection{for}
2817    De syntax van de for expressie is:
2818    
2819    \begin{verbatim}
2820    for var in list
2821    do
2822            statements
2823    done
2824    \end{verbatim}
2825    
2826    \bigskip
2827    
2828    Een voorbeeldje van het gebruik van een for expressie in een shell
2829    script vinden we in \ref{lst:forvb}.  Het script in
2830    \ref{lst:forvb} schrijft de huidige directory uit.
2831    
2832    \begin{figure}
2833    \begin{verbatim}
2834    #!/bin/sh
2835    dirlist=`ls`
2836    for file in $dirlist
2837    do
2838            echo $file
2839    done
2840    \end{verbatim}
2841    \caption{Klussen met for lussen}
2842    \label{lst:forvb}
2843    \end{figure}
2844    \bigskip
2845    
2846    Stel dat we in een directory heel wat tar.gz files staan hebben die we
2847    allemaal willen decomprimeren en uitpakken, dan kunnen we daarvoor een
2848    soortgelijk script schrijven. Een voorbeeldje hiervan zien we in
2849    \ref{lst:forutargz}.
2850    
2851    \begin{figure}
2852    \begin{verbatim}
2853    #!/bin/sh
2854    for file in `ls *tar.gz`
2855    do
2856            tar -xvzf $file
2857    done
2858    \end{verbatim}
2859    \caption{Eenvoudig uitpakken}
2860    \label{lst:forutargz}
2861    \end{figure}
2862    
2863    Merk op dat \com{`ls *tar.gz`} een verzameling bestanden teruggeeft
2864    waarover ge\"{i}tereerd wordt.  We kunnen in plaats van het \com{ls} bevel uit
2865    te voeren, het te expanden patroon meegeven: \com{for file in
2866      *tar.gz}.  De shell zal dit dan eerst expanden tot all tar.gz files
2867    in de huidige directory.  \bigskip In feite hoeft dit helemaal niet in
2868    een bestand gezet te worden. We zouden ook het script kunnen intypen
2869    achter de shell prompt, waarbij we de enters vervangen door \com{;}.
2870    Zo zouden we in plaats van \ref{lst:forutargz} in een bestand te plaatsen
2871    ook kunnen intypen:
2872    
2873    \begin{figure}
2874    \begin{verbatim}
2875    for file in `ls *tar.gz`; do tar -xvzf $file ; done
2876    \end{verbatim}
2877    \end{figure}
2878    Dit heeft hetzelfde effect.
2879    
2880    \bigskip
2881    
2882    \subsection{while}
2883    
2884    De syntax van de while expressie is:
2885    
2886    \begin{verbatim}
2887    while expressie
2888    do
2889            statements
2890    done
2891    \end{verbatim}
2892    
2893    \bigskip
2894    
2895    Een voorbeeldje van het gebruik van een while expressie in een shell
2896    script vinden we in \ref{lst:whilevb}.
2897    
2898    \begin{figure}
2899    \begin{verbatim}
2900    #!/bin/sh
2901    i=1
2902    while [ $i -le 10 ]
2903    do
2904            echo $i
2905            i=`expr $i + 1`
2906    done
2907    \end{verbatim}
2908    \caption{Voorbeeld van een while expressie}
2909    \label{lst:whilevb}
2910    \end{figure}
2911    
2912    Het script in \ref{lst:whilevb} telt tot 10 en schrijft de getallen uit.
2913    \bigskip
2914    \bigskip
2915    
2916    \section{Functies}
2917    
2918    Scripts voor de Bourne shell kunnen ook functies bevatten. De syntax
2919    is voorgesteld in \ref{lst:funcsyntax}.
2920    
2921    \begin{figure}
2922    \begin{verbatim}
2923    functienaam () {
2924            statements
2925    }
2926    \end{verbatim}{}
2927    \caption{}
2928    \label{lst:funcsyntax}
2929    \end{figure}
2930    
2931    De functie kan worden opgeroepen met de functienaam.  Ook kunnen er
2932    parameters worden doorgegeven: \com{functienaam param1 param2 \ldots}.
2933    Deze parameters kunnen dan in de functie worden aangeroepen door
2934    middel van de positionele parameters (\$1, \$2, \ldots).  Een
2935    voorbeeldje van een functie die argument1 argument2-keer met zichzelf
2936    optelt (zoals een gewone vermenigvuldiging dus) vinden we in
2937    \ref{lst:funcvb}. Merk op dat de functie voor de aanroep moet
2938    gedefinieerd worden.
2939    
2940    \begin{figure}
2941    \begin{verbatim}
2942    #!/bin/sh
2943    telkeerop(){
2944     result=$1
2945     teller=$2
2946     until [ $teller -eq  1 ]
2947     do
2948       result=`expr $result + $1`
2949       teller=`expr $teller - 1`
2950     done
2951     echo $result
2952    }
2953    
2954    telkeerop 5 7
2955    \end{verbatim}
2956    \caption{Functies in een shell script}
2957    \label{lst:funcvb}
2958    \end{figure}
2959    
2960    \section{Scripts onderbreken}
2961    Een iteratie (for, while en until) kan worden onderbroken door middel
2962    van het bevel \com{break}.  Het hele script kan be\"{e}indigd worden
2963    met het bevel \com{exit}.
2964    
2965    \section{Opgaves}\label{sec:shelloef}
2966    
2967    \begin{opgave}
2968      Schrijf een script dat een reeks van bestanden aanvaardt en naar een
2969      back-up directory copi\"{e}ert.  Zorg ervoor dat de copies read-only
2970      zijn en maak een gezipt archive van de back-up directory.  Vergeet
2971      niet om alle tijdelijke bestanden en directories op te ruimen.
2972    \end{opgave}
2973    
2974    \begin{opgave}
2975      Maak een script dat een reeks van bestanden aanvaardt en voor ieder
2976      bestand een functie aanroept.  Deze functie schrijft de gegevens van
2977      het bestand (ls -l) en de inhoud uit.
2978    \end{opgave}
2979    
2980    \begin{opgave}
2981      Schrijf een script dat een directory als parameter krijgt en de
2982      inhoud per email naar de gebruiker stuurt.  Tip: bekijk de man pages
2983      van \com{mail}.
2984    \end{opgave}
2985    
2986    \begin{opgave}
2987      Maak een script dat een lijst van email-adressen meekrijgt en als
2988      laatste argument een tekst.  Zorg ervoor dat deze tekst doorgestuurd
2989      wordt naar alle email-adressen.
2990    \end{opgave}
2991    
2992    \begin{opgave}
2993      Maak een script dat als argument de login van een gebruiker
2994      meekrijgt en een melding op het scherm geeft wanneer dat die
2995      gebruiker inlogt. Dit wil zeggen dat het script moet blijven werken
2996      totdat de gebruiker inlogt, waarna het een melding geeft en dan
2997      stopt. Tip: u kan hiervoor het \com{sleep} en het \com{grep}
2998      commando gebruiken.
2999    \end{opgave}
3000    
3001    \begin{opgave}
3002     Breid het vorige programma uit zodat je een lijst van loginnamen
3003      kan meegeven om te melden.  Het script is dan bedoeld om vanaf het
3004      starten ervan altijd te blijven lopen.
3005    \end{opgave}
3006    
3007    \begin{opgave}
3008      Maak een script dat als invoer shell-commando's krijgt en deze zelf
3009      uitvoert, waarbij er een minimale boekhouding gedaan wordt.  Schrijf
3010      de naam van het process, uitvoeringstijd en starttijd in een
3011      bestand, samen met de gebruiker die het process opgestart heeft.
3012      Dit programma moet altijd blijven werken. Gebruik {\tt read} voor de
3013      invoer.  Zorg ervoor dat je het script kan be\"eindigen door quit in
3014      te typen.
3015    \end{opgave}
3016    
3017    

Legend:
Removed from v.1.22  
changed lines
  Added in v.1.23

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26