\documentclass[a4paper,11pt]{article}
\usepackage[german]{babel}
\usepackage{epsfig}
\usepackage{verbatim}
\newcommand{\url}[1]{\nobreak{\it#1}}
\newcommand{\tilda}{\def\~{}}
\newcommand{\grad}{\ensuremath{^\circ}}
\usepackage{german}
\selectlanguage{\austrian}
\begin{document}
\title{Technische Praxis der Computersysteme Ausarbeitung UE 1 - 3 Wintersemester 2005/2006 Bernhard Lamel, Roland Steinbauer, Gerald Teschl}
\section{\"Ubung 1}
\begin{enumerate}
\item  Erkunde Deine Desktop-Umgebung und das KDE-Kontrollzentrum und finden sie heraus:
\begin{itemize}
\item Welche KDE-Version auf Deinem System l\"auft. Welche Version ist aktuell? (Die Homepage des KDE-Projekts ist www.kde.org).
\begin{verbatim}
> kdesktop -v
Qt: 3.3.4
KDE: 3.3.2
KDesktop: 3.3.2
> lynx -dump www.kde.org| grep Released| head -n1
   [19]KDE 3.5 Beta2 ("Koalition") Released
\end{verbatim}

\item Wie Du das Aussehen des Desktops ver\"andern kannst. (Hintergrund, Window-Aussehen, u.s.w.).
\begin{verbatim}
> xsetroot -solid black
> vi .kde*
> vi .fvwmrc
> ...
...: Command not found.
\end{verbatim}
\item Wie Du das Keyboard-Layout ver\"andern kannst.
\begin{verbatim}
# xkbseldb -R
> xkbseldb -L | grep xfree86\( | cut -f2 -d\"
> xkbsel us
\end{verbatim}
\item Wie Du die Geschwindigkeit der Maus beeinflussen kannst.
\begin{verbatim}
> ( xset -h >&/dev/stdout ) | grep -A1 mouse
    To set mouse acceleration and threshold:
		     m [acc_mult[/acc_div] [thr]]    m default
> xset m 10 10
\end{verbatim}
\item Wie Du mit dem Filebrowser ein neues Directory erzeugen kannst.
\begin{verbatim}
> mkdir uebung1
\end{verbatim}
\item Wie Du eine Konsole \"offnest (Du ben\"otigst eine f\"ur den Rest der �bung). Finde eine Einstellung, die Dir gef\"allt!
\begin{verbatim}
> xterm&
\end{verbatim}
\end{itemize}
\item  Lade von www.mat.univie.ac.at/praxis/ das Archiv, das f\"ur die heutige �bung vorgesehen ist, herunter. Falls Du nicht auf Deinem eigenen Account arbeitest, w\"are jetzt eine gute Gelegenheit, dein Home-Directory zu s\"aubern...
\begin{verbatim}
> curl -O http://www.mat.univie.ac.at/~praxis/ws0506_ue/archivuebung1.tar
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
	                                 Dload  Upload   Total   Spent    Left  Speed
100 20480  100 20480    0     0   101k      0 --:--:-- --:--:-- --:--:--  502k
\end{verbatim}
\begin{itemize}
\item Entpacke das Archiv mit Hilfe von tar -xvf Archivname.
\item Welche Verzeichnisse und Dateien befinden sich nun in Deinem Home-Directory?
\begin{verbatim}
> cd uebung1; tar -xvf ../archivuebung1.tar
file1
file2
file3
file4
hallo
rnd
\end{verbatim}
\item F\"uhre (mittels ./hallo) das Shellscript hallo aus.
\begin{verbatim}
> less hallo # offenbar harmlos bis auf potentielle race condition in /tmp
> ./hallo
Die Datei ichbinhier ist versteckt!
\end{verbatim}

\end{itemize}
\item In dem Verzeichnis /tmp/ueverzeichnis/ befinden sich 40 Unterverzeichnisse. Wechsle in jenes Unterverzeichnis, in dem sich die Datei ichbinhier befindet. (Du solltest die Datei zuerst finden!)
\begin{verbatim}
> find /tmp/ueverzeichnis -iname ichbinhier
/tmp/ueverzeichnis/unterverzeichnis13/ichbinhier
> bash -c 'cd $( dirname `find /tmp/ueverzeichnis -iname ichbinhier`  ); pwd'
/tmp/ueverzeichnis/unterverzeichnis13
\end{verbatim}

\item Lege einen symbolischen Link symlink und einen harten Link hardlink von Deinem Home-Directory zu dem File ichbinhier an.
\begin{verbatim} 
> bash -c 'for i in "" "-s"; do ln $i ichbinhier ~/link$i; done'
\end{verbatim}

\item L\"osche das File ichbinhier. Was passiert mit den Links?
What's in a name?\\
Der symlink ist Schall und Rauch, er zeigt ins Nirvana, der Hardlink
\"uebersteht alle Eradikationsversuche (zus. Direntry f\"ur inode, siehe
auch linkcount.\\
Siehe auch /usr/src/linux/fs/ext2/symlink.c, /usr/src/linux/fs/ext2/file.c
(sowie dir.c) und meine Arbeiten unter\\
\url{http://tigerente.htu.tuwien.ac.at/\~{}aoe/mystuff/smb.symlinks}.
\item Lege eine Kopie des gesamten uebung1-Directory in dem von dir zu erstellenden Ordner backup ab, und l\"osche danach das uebung1-Directory.
\begin{verbatim}
> cd; mkdir backup; cp -raf uebung1 ~/backup/; rm -rf ~/uebung1
\end{verbatim}

\item Lege einen Directory bin in Deinem Home-Directory an, kopiere das Script hallo dorthin, und f\"uge das Directory Deinem Suchpfad hinzu. Wie kannst Du das Script nun ausf\"uhren?
\begin{verbatim}
> bash -c 'if [ "x${PATH/*$USER\/bin*/asd}" == "xasd" ]; then \
    echo "~/bin already in path, no action needed"; \
	else \
	  PATH=~/bin:$PATH; \
	fi; \
	hallo'
\end{verbatim}
\begin{itemize}
\item Setze die Berechtigungen auf file1 so, dass Sie es lesen und schreiben k\"onnen, aber sonst niemand Rechte hat.
\begin{verbatim}
> chmod 600 file1; ls -l file1
-rw-------  1 aoe aoe 0 Oct 13  2004 file1
\end{verbatim}

\item Setze die Berechtigungen auf file2 so, dass es alle lesen, aber niemand schreiben kann. Wer kann es trotzdem schreiben?
\begin{verbatim}
> chmod 444 file2; ls -l file2
-r--r--r--  1 aoe aoe 0 Oct 13  2004 file2
> su -c "echo asd >> file2"
\end{verbatim}
\item Setze die Berechtigungen auf file3 so, dass Benutzer aus derselben Gruppe Lese- und Schreibrechte haben, alle anderen nur Leserechte.
\begin{verbatim}
> chmod 664 file3; ls -l file3
-rw-rw-r--  1 aoe aoe 0 Oct 13  2004 file3
\end{verbatim}
\item Setze die Berechtigungen auf file4 so, dass es alle Benutzer ausf\"uhren k\"onnen, aber nur sie auch lesen und schreiben.
\begin{verbatim}
> chmod 755 file4; ls -l file4
-rwxr-xr-x  1 aoe aoe 0 Oct 13  2004 file4
\end{verbatim}
\end{itemize}
\item Besuche die Homepage des GNU Projekts, und sieh Dich im Bereich der Lizenzen um. Versuche, die folgenden Fragen zu beantworten:
\begin{itemize}
\item Warum ist es wichtig, den Sourcecode zug\"anglich zu machen?
\\
Damit BenutzerInnen Source Code nach ihrer Notwendigkeit adaptieren k\"onnen
\dots
\item Warum ist es wichtig, freie Software in irgendeiner Form zu lizenzieren?
\\
Ohne entsprechende Lizensierung liegt das Copyright bei dem/der AutorIn,
\"Anderungen d\"urfen nicht weitergegeben werden
\item Wenn Du ein Programm, dass unter der GPL lizenziert wurde ver\"anderst und weitergibst, musst Du den ver\"anderten Sourcecode auch zug\"anglich machen?
\\
yup
\end{itemize}
\item Wie voll ist die Partition, auf der das Root-Verzeichnis gemountet ist? (Dh wieviel Plattenplatz ist dort noch frei?)
\begin{verbatim}
> df /
Filesystem           1K-blocks      Used Available Use% Mounted on
nfs:/nfsroot/192.168.2.10
                      10080520   9419224    149232  99% /
\end{verbatim}

\end{enumerate}


\section{\"Ubung 2}
\begin{enumerate}
\item Lade das zur heutigen �bung geh\"orende tar-Archiv in Dein Homedirectory und entpacke es. Erweitere Deinen Suchpfad auf das im Archiv enthaltene bin-Verzeichnis und rufe das Script prepareuebung auf. Dieses Script erstellt einen Verzeichnisbaum unter /tmp/uebung und darin Dateien.  
\begin{verbatim}
> curl -O http://www.mat.univie.ac.at/~praxis/ws0506_ue/uebung2.tar.bz2
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
	                               Dload  Upload   Total   Spent    Left  Speed
100  6898  100  6898    0     0   187k      0 --:--:-- --:--:-- --:--:--  421k
> tar -xjvf uebung2.tar.bz2 
bin/
bin/makelist
bin/mkdirs
bin/mkfiles
bin/rnd
bin/prepareuebung
bin/mkfiles2
text1.txt
> if [ ${PATH/*$HOME\/bin*/mybin} = "mybin" ]; then \
		echo already in path; else \
		export PATH=~/mybin:$PATH; \
	fi
already in path
> prepareuebung
[bug: nicht . gesourcte scripts hinterlassen keine veraenderungen
im environment]
> export HOME=/tmp/uebung
\end{verbatim}
\item Finde die Dateien in Deinem Homedirectory und seinen Unterverzeichnissen, deren Name von der Form file.*  sind. (Kleine Nebenfrage: Wieviele solche Dateien sind das? Die Ausgabe des find Befehls wird Dir im n\"achsten Beispiel bestimmt hilfreich sein).

\begin{verbatim}
> find $HOME -name "file*" | wc -l
25
\end{verbatim}

\item Verschiebe nun all diese Dateien in den von Dir zu erstellenden Ordner target.
\begin{verbatim}
> mkdir target
> find $HOME -name "file*" -exec mv "{}" target ";"
\end{verbatim}

\item Kopiere jene Dateien im Ordner target, deren Dateiname einem der Eintr\"age in dem File liste folgt, in den von Dir zu erstellenden Ordner target2. Auch dieses sollte automatisiert
werden, Du kannst zB das File liste einfach zeilenweise abarbeiten (dies ist nicht unbedingt die \"okonomischste L\"osung).
\begin{verbatim}
> mkdir target2
> for i in `<liste`; do cp target/$i target2; done
\end{verbatim}

\item L\"osche den gesamten Directorybaum dir\_{}xx/dir\_{}xx\_{}yy, das Directory target2, und entleere das Directory target.
\begin{verbatim}
> rm -rf dir dir_xx target2 target/*
\end{verbatim}

\item F\"uhre das Script mkfiles2 aus. In dem Ordner source befinden sich nun einige Dateien mit dem Namen ws0405\_{}*. Kopiere diese Dateien in den Ordner target, wobei sie neue Namen erhalten sollen: statt ws0405 soll nun sosem05 stehen.
\begin{verbatim}
> o=source/ws0405_; for i in $o*; do cp $i ${i/$o/target\/sosem05_}; done
\end{verbatim}

\item Schreibe ein Makro f\"ur den vi-Editor, der eine Zeile in einem Shellscript auskommentiert (dies geschieht dadurch, dass der Zeile ein \#{} vorangestellt wird). Schreibe auch ein Makro, dass umgekehrt einen solchen Kommentar entfernt. (Der Punkt hier ist, dass man das Makro von jeder Position in der Zeile aufrufen kann)
\begin{verbatim}
:map <F2> <ESC>:s/^#* *//<enter>
:map <F3> <ESC>:s/^/# /<enter>
\end{verbatim}

{\bf Anmerkung:} in den folgenden Beispielen wurde stillschweigend die 
Anweisung, vi zu benutzen, ignoriert und stattdessen regexes fuer sed 
verfasst, die (fast) genauso funktionieren und commandline-tauglicher sind.\\

\item Ersetze in dem File text1.txt jedes Vorkommen von ,,Vereinsirgendwas'' durch ,,irgendwas des Vereins''. (ohne die Kleinschreibung zu \"andern).
\begin{verbatim}
> sed -e 's/\(Vereins\)\(irgendwas\)/\2 des \1/ig'
\end{verbatim}

\item Schreibe einen global-Befehl f\"ur den vi, der in einem Shellscript jeden Kommentar (also s\"amtliche Zeilen, die mit einem \#{} beginnen) entfernt (zum Ausprobieren bietet sich zB eines der Files aus /etc/init.d/ an).

{\bf Anmerkung:} das sind nicht alle Kommentare!

\begin{verbatim}
> sed -e '/^#/d' 
(vi: %s/^#//g)
\end{verbatim}

\item Entferne aus dem editierten File text1.txt alle Vokale. (Dies kann zB mit Hilfe des vi oder mit Hilfe des Kommandos tr geschehen)
\begin{verbatim}
> sed -ie 's/[aeiou]//ig' text1.txt
\end{verbatim}
\end{enumerate}

\section{\"Ubung 3}
\begin{enumerate}
\item Finde in der Bash-Manpage die Beschreibung der verschiedenen M\"oglichkeiten, den Prompt (dh  \${}PS1) zu setzen, und gestalte Deinen Prompt selber, sodass er auf jeden Fall die Uhrzeit und das Arbeitsdirectory anzeigt.
\begin{verbatim}
> man bash|grep -E "^PROMPTING|current time|current  working  directory"
Reformatting bash(1), please wait...
PROMPTING
              \t     the current time in 24-hour HH:MM:SS format
							\T     the current time in 12-hour HH:MM:SS format
							\@     the current time in 12-hour am/pm format
							\A     the current time in 24-hour HH:MM format
							\w     the  current  working  directory,  with $HOME abbreviated
							Print the absolute pathname of the  current  working  directory.
> PS1="\t\w\$ "
10:29:33~/tmp/tp$ 
\end{verbatim}

\item Speichere die �nderungen am Prompt, sodass bei einem Neustart der Bash Dein selbst gestalteter Prompt verwendet wird.
\begin{verbatim}
> echo PS1=\"$PS1\" >> .bash_profile
\end{verbatim}

\item Schreibe ein Skript, dass die Aufgabe vom letzten Mal, die gew\"ohnlichen Dateien ws0405\_{}* auf Dateien mit dem Namen sosem05\_{}* zu kopieren, automatisiert. Dein Skript \"ubernimmt zwei Parameter, also \${}1 und \${}2, und kopiert alle Dateien (in dem Directory, wo das Skript aufgerufen wird) mit dem Namen \${}\{1\}\_{}* auf \$\{2\}\_{}*. (Hint: Verwende eine for Schleife, die \"uber die Dateien mit dem Namen \$\{1\}\_{}* l\"auft. Der Teil \$suffix des Dateinamens nach dem \_{} kann zB mit Hilfe von cut -d\_{} -f2 herausgefunden werden, also falls der volle Dateiname \$fullname ist, mit Hilfe von suffix=`echo \$fullname | cut -d\_{} -f2`.)
\begin{verbatim}
#!/bin/bash
ONAME=$1
RNAME=$2
for i in $ONAME_*; do cp $i ${i/$ONAME_/$RNAME_}; done
\end{verbatim}

\item �ndere Dein Skript nun so, dass es die Anzahl der kopierten Dateien auf die Standardausgabe schreibt. (Hint: Baue in Deine for-Schleife einen Z\"ahler \$counter ein, denn Du am Beginn des Skripts mit Hilfe von counter=1 initialisierst. Erh\"oht wird mit Hilfe von counter=\$(( \$counter + 1 )).)

{\bf Anmerkung:} Eine Initialisierung auf 1 verhindert die effiziente Verarbeitung!

\begin{verbatim}
#!/bin/bash
ONAME=$1
RNAME=$2
counter=1
for i in $ONAME_*; do 
	cp $i ${i/$ONAME_/$RNAME_}; 
	counter=$[ counter+1 ]
done
echo "$[ counter-1 ] files copied"
\end{verbatim}

\item Teste Dein Skript auf 100 (oder so) von Dir erzeugten Dateien (diese k\"onnten zB prefix\_{}001, ..., prefix\_{}100 heissen).
\begin{verbatim}
> for i in `seq 1 100`; do touch prefix_$i; done
> mvmulti prefix newname
100 files copied
> ls|grep prefix|wc -l
0
> ls|grep newname|wc -l
100
\end{verbatim}

\item Schreibe ein Skript runforever, dass nichts tut, aber f\"ur immer weiterl\"auft. (Die Befehle true bzw false eignen sich hervorragend zum L\"osen einer solchen Aufgabe)
\begin{verbatim}
#!/bin/sh
while true; do sleep 1; done
\end{verbatim}

\item Starte runforever im Vordergrund, halte die Ausf\"uhrung an, und starte es im Hintergrund wieder.
\begin{verbatim}
> ./runforever
\^{}Z
[1]+  Stopped                 ./runforever
> bg
[1]+ ./runforever &
\end{verbatim}

\item Finde die PID des vorher gestarteten runforever und lokalisiere es in der Ausgabe von  pstree.
\begin{verbatim}
> pidof runforever
12345
> pstree | grep runforever
     |-xterm---runforever
\end{verbatim}

\item Starte nochmals, diesmal mit Hilfe von nohup, Dein Skript runforever, und finde die PID dieser Instanz. �ffne nun eine zweite Shell, finde die PID der Shell in der Du 2 mal runforever gestartet hast, und sende von der neuen Shell aus ein SIGHUP an die alte Shell. Was ist mit den zwei Instanzen von runforever geschehen? Es sollte nun noch eine Instanz von runforever laufen. Terminiere sie.

{\bf Anmerkung:} Ein h\"ubscher Schummelzettel f\"ur sed-commands
ist zu finden unter {\tt http://www.student.northpark.edu/pemente/sed/sed1line.txt}

\begin{verbatim}
> nohup ./runforever
> pstree -p | grep runforever
     |-xterm(12327)---bash(12344)-+-runforever(12345)
                                  `-runforever(12349)
> kill -HUP  `pstree -p | sed -n '/sleep/{g;1!s/.*bash(\([0-9\]*\)).*/\1/p;};h'`
> pidof runforever
12349
> kill `pidof runforever`
\end{verbatim}

\item  Starte noch einmal Dein Skript runforever, und verwende nun  disown -h um die Weiterreichung von SIGHUP an diese Instanz zu unterbinden. Sende nun ein SIGHUP an die Shell in der diese Instanz l\"auft, finde das weiterlaufende runforever in der Ausgabe von pstree, und terminiere es.
\begin{verbatim}
$ bash
> ./runforever&
[1]+ ./runforever &
> disown -h %1
> kill -HUP $$
Hangup
$ kill `pstree -p |  sed -ne 's/.*runforever(\([0-9\]*\)).*/\1/p'`
\end{verbatim}
\end{enumerate}
\end{document}
