\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 ` 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 :s/^#* *// :map :s/^/# / \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}