1. Einführung 1.1 Die letze Version bekommen http://www.ufoalien.ch/bash.txt 1.2 Anforderungen Auskennen mit den GNU/Linux shell Befehle! Grungkonzepte des Programmierens kennen. Dies ist keine Einführung zum Programmieren, es erklärt nur (oder versucht wenigstens), viele Basis-Konzepte. 1.3 Gebrauch diese Dokuments Diese Dokument versucht in folgenden Situationen nützlich zu sein * Sie haben eine Idee vom Programmieren, und möchten ein paar shell-Skripte machen. * Sie haben ein Waages Wissen über shell-Skripte und möchten es bestätigen/erweitern. * Sie möchten ein paar shell skripts sehen, und mit eigenen anfangen! * Sie steigen gerade von msdos/windows um! * Sie sind ein kompletter nerd und lesen jedes möglich HowTO 2.1 Einfaches Script #!/bin/bash echo Hello World Dieses Script besteht aus nur zwei Linien. Die erste gibt dem system an, mit welchem Programm es die Datei ausführen soll, die Zweite ist was ausgeführt wird (Hello World auf den Bildschirm ausgeben)! Um das Programm nun auszuführen, muss "bash ./bash.sh" ausgeführt werden. Dabei muss ./bash.sh natürlich das obige Script beeinhalten! Bekommt man als Fehlermeldung ähnliches wie "./hello.sh: Command not found" so liegt das wahrscheinlich an #!/bin/bash, das falsch geschrieben ist, oder das Programm bash befindet sich nicht im Ordner /bin/. Um das Programm zu finden, muss mein "whereis bash" eingeben! 2.2 Ein einfaches Back-up script Um z.B. ein back-up script von seinem homedirectory zu machen, genügt ein ganz kleines script: #!/bin/bash tar -cf /home/michele/backup.tar /home/michele/ Es erstellt ein tar Archiv von /home/michele/ und speichert es in /home/michele/backup.tar! 3. Weiterleiten 3.1 Es gibt 3 Datei Beschreiber, stdin, stdout und stderr (std=standard). Damit kann man: 1. stdout zu datei 2. stderr zu datei 3. stdout zu stderr 4. stderr zu stdout 5. stderr und stdout zu datei 6. stderr und stdout zu stdout 7. stderr und stdout zu stderr 3.2 stdout 2 file Dies Schreibt die Ausgabe von einem Befehl (hier ls -l) in eine Datei (hier ls.txt)! #!/bin/bash ls -l > ls.txt Eine Datei ls.txt wird erstellt, und beeinhaltet das, was man auf dem Bildschirm sehen würde, wenn man den Befehl "ls -l" ausführen würde! 3.3 stderr 2 file Die stderr Ausgabe eines Programmes wird in grep-errors.txt geschrieben! #!/bin/bash grep da * 2> grep-errors.txt Hier wird in die Datei grep-errors.txt die stderr Ausgabe von dem Befehl "grep da *" geschrieben 4. Pipes Dieser Teil erklärt den ganz einfachen und praktischen Weg, wie pipes zu benützen sind und warum sie sie vielleicht wollen! 4.1 Was sie sind, und warum sie sie brauchen möchten Pipes lassen sie die Ausgabe eines Programms mit einer Ausgabe eines anderen Programms verbinden! 3.2 Datei finden #!/bin/bash ls -l --color /home/michele | grep star Diese skript sucht im Ordner /home/michele/ nach einer Datei, die z.B. star, star2 oder 2star heisst. Der Dateiname muss einfach das word star beeinhalten. Achtung [!] Beachten sie, dass auf einem linux filesystem zwischen Gross- und Kleinschreibung unterschieden wird. Also gibt "ls ./ | grep star" keine Auskunft nach der Datei STAR! Um auch der Gross/Klein-Schreubung keine Beachtung zu schenken, verwenden sie den Befehl "ls -l ./ | grep -i Star" Die Option -i (oder --ignore-case) ignoriert diesen Unterschied! 5. Variabeln Sie können hier Varbiabeln, wie in allen anderen Programmier-Sprachen benützen. Eine Varbiabel in bash, kann eine nummer, ein Zeichen, oder einen String sein. Sie müssen die Variabel nicht deklarieren. Nur den Wert zu seinem Namen, und die Variabel wird genereirt! 5.1 Beispiel: Hallo Michele! mit Variabeln #!/bin/bash string="Hallo Michele!" echo $string Die Zweite Linie bildete eine Variabel "string"! Der Wert dieser Datei kann mit einem Dollar-Zeichen ($) gefolgt vom Namen ($string) angezeigt werden! Vergisst man das $ vor der Variabel, kann das fatale folgen haben, die Ausgabe von echo $string und echo string ist nicht dieselbe! 5.2 Das Back-up skript verbessert #!/bin/bash name=/home/michele/backup-$(date +%d%m%Y).tgz echo $name tar -cf $name /home/michele/ In diesem Skript, kommt ein Punkt mehr zu dem Thema Variabeln dazu. Zuerst, müssen sie sich mit der Variabel-Bildung auf der zweiten Linie vertraut machen! Beachten sie den Ausdruck $(date +%d%m%Y). Wenn sie das skript starten, werden sie bemerken, dass der Befehl innerhalb der Klammern ausgeführt und in die Variabel gesetzt wird! In diesem skript, ändert täglich der Name, der Variabel, als auch der Datei, weil der Name mit dem Befehl "date +%d%m%Y" gebildet wird! Der Befehl "date +%d%m%Y" gibt das Datum wie folgt aus: TagMonatJahr! Die Reihenfolge kann beliebig geändert werden! So wäre die Ausgabe am 12. September 2004: nirvana@sarah:~$ date +%d%m%Y 12092004 nirvana@sarah:~$ Man kann auch die Zeit miteinbeziehen: nirvana@sarah:~$ date +%k%M%S%d%m%Y 16440012092004 nirvana@sarah:~$ Gennerel gillt: date + %A locale's full weekday name, variable length (Sunday..Saturday) %b locale's abbreviated month name (Jan..Dec) %B locale's full month name, variable length (January..December) %c locale's date and time (Sat Nov 04 12:02:33 EST 1989) %C century (year divided by 100 and truncated to an integer) [00-99] %d day of month (01..31) %D date (mm/dd/yy) %H hour (00..23) %I hour (01..12) %j day of year (001..366) %k hour ( 0..23) %l hour ( 1..12) %m month (01..12) %M minute (00..59) %N nanoseconds (000000000..999999999) %r time, 12-hour (hh:mm:ss [AP]M) %R time, 24-hour (hh:mm) %s seconds since 00:00 1970-01-01 UTC' (a GNU extension) %S second (00..60); the 60 is necessary to accommodate a leap second %T time, 24-hour (hh:mm:ss) %u day of week (1..7); 1 represents Monday %V week number of year with Monday as first day of week (01..53) %x locale's date representation (mm/dd/yy) %X locale's time representation (%H:%M:%S) %y last two digits of year (00..99) %Y year (1970...) Andere Beispiele: echo ls /= echo $(ls) Die Ausgabe von echo ls, is ls, aber echo $(ls) gibt den Befehl "ls" aus! 5.3 Lokale Variabeln Lokale Variabeln können mit dem Schlüsselwort local gebildet werden!. #!/bin/bash HELLO=Hello function hello { local HELLO=World echo $HELLO } echo $HELLO hello echo $HELLO Diese Beispiel sollte reichen, um zu zeigen, wie lokale Variabeln funktionieren! 6. Bedingungen Bedingungen lassen entscheiden, ob eine Aktion ausgeführt wird, oder nicht! Diese Entscheidung wird getroffen, indem ein Bedingung ausgewertet wird! 6.1 Trockene Theorie Bedingungen haben viele Formen. Das häufigste is: if Bedingung then mach_das mach_das, wird nur ausgeführt, wenn die Bedingung nach if der Wahrheit entspricht! Andere Formen sind: if Bedingung then mach_das else mach_dies mach_das, wird nur ausgeführt, wenn die Bedingung nach if der Wahrheit entspricht! Sonst wird mach_dies ausgeführt! Noch eine andere Form: if Bedingung1 then mach_das else if Bedingung2 then mach_dies else mach_jenes Hier wird noch else if Bedingung2 then mach_dies else mach_jenes hinzugefügt was mach_dies nur ausführt, falls Bedingung2 stimmt! Ein Wort über Syntaxe: Die Basis für eine "if" Konstruktion in bash ist: if [Bedingung]; then mach_das fi 6.2 Einfaches Beispiel mit if .. then #!/bin/bash if [ "nirvana" = "nirvana" ]; then echo Bedingung stimmt! fi 6.3 Einfaches Beispiel mit Variabeln #!/bin/bash var1="nirvana" var2="him" if [ "$var1" = "$var2" ]; then echo Bedingnung stimmt! else echo Bedingung stimmt nicht! fi 7. Schlaufen: for, while and until Hier werden die while, for und until Schlaufen erklärt! Die Schlaufen in bash sind ein bisschen verschieden als die von anderen Programmiersprachen! Im Allgemeinen lässt es uns eine Reihe von Worten, innerhalb einer Zeichenkette wiederhohlen! Die while Schlaufe führt ein Stück code so lange aus, wie die Bedingung stimmt. Sie endet nur, wenn die Bedingung nicht stimmt (oder ein Stopp im ausgeführten Skript gefunden wurde! Die until Schlaufe ist fas identisch mit der while Schlaufe, ausser das der code ausgeführt wird, so lange die Bedingung nicht stimmt! Wenn sie verdächtigen, die while und until Schlaufen seien fast gleich, liegen sie sehr richtig! 7.1 Ein Beispiel mit for #!/bin/bash for i in $( ls ); do echo item: $i done Auf der zweiten Linie, legen wir fest, dass i in der Variabel is, die die verschiedenen Werte in $( ls ) beeinhalted! Die dritte Line könnte länger sein, wenn sie es brauchen, oder es könnten mehr Linien vor done stehen 'done' zeigt an, dass der gebrauchte code für den Wert $i fertig ist und $i eine neue Variabel sein kann! Dieses Skript macht wenig Sinn, aber ein brauchbarer Weg, diese Schaufe zu brauchen, wäre, nur einzelne Dateien im vorherigen Beispiel auszugeben! 7.2 Siehe wie for Diese Form der Scheife hat ähnlichkeiten, mit Schleifen in C oder perl! #!/bin/bash for i in 'Seq 1 10'; do echo $i done 7.3 Beispiel mit while #!/bin/bash zaehler=0 while [ $zaehler -lt 100 ]; do echo Der Zaehler ist $zaehler let zaehler=zaehler+1 done Dieses skript emuliert die bekannte (C, Pascal, perl, etc) "for" Struktur 7.4 Beispiel mit until #!/bin/bash zaehler=100 until [ $zaehler -lt 0 ]; do echo Zaehler ist $zaehler let zaehler-=1 done 8. Funktionen Wie in den meisten anderen Programmiersprachen, kann man Funktionen verwenden, um Stücke des Codes in einer logischeren Weise zu gruppieren oder die göttliche Kunst der Rekursion zu üben. Eine Funktion zu deklarieren heisst nur, "function my_func { my_code }" zu schreiben! Eine Funktion aufrufen, ist wie ein anderes Programm zu starten, sie schreiben nur dessen Namen! 8.1 Beispiel mit function #!/bin/bash function quit { exit } function hallo { echo Hi Michele! } hello quit echo Liess mich? Die Zeilen 2-4 enthalten die quit Funktion. Die Zeilen 5-7 enthalten die hallo funktion! Wenn sie nicht absolut sicher sind, was diese Skript macht (vor allem die letzte Zeile), probieren sie es bitte aus! Beachten sie, dass die Funktionen nicht in bestimmten Ordunngen deklariert sein müssen! Wenn sie das Programm ausführen, werden sie bemerken, dass die erste Funktion hallo gestartet wird und die zweite Funtkion quit. Das Programm wird/hat die Zeile 10 nie erreichen! 8.2 Beispiel mit function mit Parameter #!/bin/bash function quit { exit } function e { echo $1 } e Hallo e Michele quit echo Liess mich? Dieses Skript ist fast identisch mit dem Vorherigen. Der Hauptunterschied ist die Funktion e. Diese Funktion, gibt das erste Argument aus, das es empfängt. Argumente innerhalb der Funktion, werden auf die selbe Weise behandelt wie die Argumente die zum Skript gegeben werden! 9. User Interfaces 9.1 Gebrauch von select für einfache Menüs #!/bin/bash options="Hallo Quit" select opt in $options; do if [ "$opt" = "Quit" ]; then echo done exit elif [ "$opt" = "Hallo" ]; then echo Hallo Michele else clear echo Falsche Option fi done Wenn sie dieses Skript starten, werden sie sehen, das es ein Traum eines Programmieres für textbasierte Menüs ist! Sie werden vielleicht bemerken, das der Aufbau sehr ähnlich mit "for" ist! prompts the user. 9.2 Die Kommando-Zeile benützen #!/bin/bash if [ -z "$1" ]; then echo usage: $0 directory exit fi sourcedir=$1 targetdir="/home/michele/backup/" datum=home-michele$(date +%d%m%Y).tgz tar -cf $targetdir$datum $sourcedir Was diese Sktipt tut, sollte ihnen jetzt klar sein. Die erste Bedingung testet, ob das Programm das Argumment ($1) bekommen hat, und endet, wenn dies nicht der Fall ist. 10. Verschiedenes 10.1 Input mit read lesen Oft möchtens sie vielleicht die Eingabe des Benützers lesen. Es gibt verschiedene Wege dafür, hier einer: #!/bin/bash echo Geben sie bitte ihren Namen ein! read name echo "Hallo $name!" Als Variante, können sie mehrere Werte mit read herauslesen. #!/bin/bash echo Geben sie bitte ihren Vornamen und Nachnamen ein! read vn nn echo "Hallo! $nn, $vN !" 10.2 Arithmetische Evolution Probieren sie das in der Schelle aus: echo 1 + 1 Wenn sie denken, sie würden 2 als Ausgabe sehen, werden sie verwirrt und enttäuscht sein! Hier die Lösung: echo $((1+1)) Dies produziert eine logischere Ausgabe! Hier eine Alternative: echo $[1+1] Würde ich "echo $[3/4]" in einer shell eingeben, würde es zu 0 zurückfallen, weil nur ganze Zahlen Ausgegeben werden! Die Lösung: echo 3/4|bc -l 10.3 bash finden Sie haben immer #!/bin/bash benützt! Aber wie bash finden, wenn bash nicht in /bin/ ist?!? "locate bash" wird bevorzugt, nicht alle Maschienen kennen jedoch locate "find ./ -name bash" im Verzeichniss / ausführen sollte immer funktionieren! "whereis bash" und "which bash" sind auch sehr zu empfehlen! Standart Orte! ls -l /bin/bash ls -l /sbin/bash ls -l /usr/local/bin/bash ls -l /usr/bin/bash ls -l /usr/sbin/bash ls -l /usr/local/sbin/bash 10.4 Denn Rückwert eines Programms bekommen In bash, the return value of a program is stored in a special variable called $?. In bash, wird der Rückwert eines Prgrammes in einer Speziellen Variabel gespeichert, genannt $?! Hier suchen wir nach der Variabel! #!/bin/bash cd /dada &> /dev/null echo rv: $? cd $(pwd) &> /dev/null echo rv: $? 10.5 Ausgabe eines Befehls aufnehmen! Diese kleine Skript, zeigt alle Tabellen aus allen Datenbanken (natürlich nur, wenn sie MySQL installiert haben). #!/bin/bash DBS='Mysql -uroot -e"show databases"' for b in $DBS ; do mysql -uroot -e"show tables from $b" done 11. Tabellen 11.1 Strings vergleichen: Operationszeichen s1 = s2 s1 ist gleich s2 s1 != s2 s1 ist nicht gleich s2 s1 < s2 s1 ist kleiner als s2 s1 > s2 s1 ist grösser als s2 -n s1 ist nicht Null -z s1 ist Null 11.2 Strings vergleichen: Beispiele Zwei Strings vergleichen. #!/bin/bash s1='string' s2='String' if [ $s1=$s2 ]; then echo "s1('$s1') ist nicht gleich S2('$S2')" fi if [ $s1=$s1 ]; then echo "s1('$s1') ist gleich s1('$s1')" fi 11.3 Arithmetische Operationszeichen + - * / % (rest) 11.4 Arithmetische Vergleichungs Operationszeichen -lt (<) -gt (>) -le (<=) -ge (>=) -eq (==) -ne (!=) 11.5 Nützliche Befehle sed (stream editor) awk (manipulation of datafiles, text retrieval and processing) wc (counts lines, words and bytes) sort (sort lines of text files) bc (a calculator programming language) tput (initialize a terminal or query terminfo database) 12. Mehr Skripts 12.2 Sample: Ein sehr einfaches Back-up Skript #!/bin/bash SRCD="/home/" TGTD="/var/backups/" OF=home-$(date +%Y%m%d).tgz tar -cf $TGTD$OF $SRCD 12.3 Datei Neubennenr #!/bin/sh # renna: rename multiple files according to several rules # written by felix hudson Jan - 2000 # first check for the various 'modes' that this program has # if the first ($1) condition matches then we execute that # portion of the program and then exit # check for the prefix condition if [ $1 = p ]; then #we now get rid of the mode ($1) variable and prefix ($2) prefix=$2 ; shift ; shift # a quick check to see if any files were given # if none then its better not to do anything than rename some # non-existent files!! if [$1 = ]; then echo "no files given" exit 0 fi # this for loop iterates through all of the files that we gave #the program it does one rename per file given for file in $* do mv ${file} $prefix$file done #we now exit the program exit 0 fi # check for a suffix rename # the rest of this part is virtually identical to the previous #section please see those notes if [ $1 = s ]; then suffix=$2 ; shift ; shift if [$1 = ]; then echo "no files given" exit 0 fi for file in $* do mv {file} $file$suffix done exit 0 fi # check for the replacement rename if [ $1 = r ]; then shift # i included this bit as to not damage any files if the user # does not specify # anything to be done # just a safety measure if [ $# -lt 3 ] ; then echo "usage: renna r [expression] [replacement] files... " exit 0 fi # remove other information OLD=$1 ; NEW=$2 ; shift ; shift # this for loop iterates through all of the files that we give # the program # it does one rename per file given using the program 'sed' # this is a sinple command line program that parses standard # input and replaces a set expression with a give string # here we pass it the file name ( as standard input) and # replace the nessesary text for file in $* do new=cho ${file} | sed s/${OLD}/${NEW}/g mv ${file} $new done exit 0 fi # if we have reached here then nothing proper was passed to the # program so we tell the user how to use it echo "usage;" echo " renna p [prefix] files.." echo " renna s [suffix] files.." echo " renna r [expression] [replacement] files.." exit 0 # done! 12.4 Dateineubennener (einfacher) #!/bin/bash # renames.sh # basic file renamer criteria=$1 re_match=$2 replace=$3 for i in $( ls *$criteria* ); do src=$i tgt=$(echo $i | sed -e "s/$re_match/$replace/") mv $src $tgt done 13. Wenn etwas schief geht (debugging) 13.1 Bash debuggen In der ersten Zeile, "-x" dazu schreiben! #!/bin/bash -x Dies wird ein paar interessante Ausgaben zeigen! 14. Über dieses Dokument Fühlen sie sich frei, Vorschhläge und Korrektur, oder was immer sie denken, was das Dokument interassenter machen würde zu machen! Ich versuche es so schnell wie möglich zu ändern! 14.1 (keine) Grantie Diese Dokument kommt absolut ohne Garantie! 14.2 Übersetzungen Italian: by William Ghelfi (wizzy at tiscalinet.it) is here French: by Laurent Martelli is missed Korean: Minseok Park http://kldp.org Korean: Chun Hye Jin unknown Spanish: unknow http://www.insflug.org German: Nick Weyland http://nweyland.ch.vu ufoalien@weyland.ch irc.lugs.ch #area51 Ich denke, es wird nich mehr Übersetzungen geben, aber ich habe keine Informationen über sie! Wenn sie welche haben, senden sie sie mir! Ich werde diese Sektion dann so früh wie möglich überhohlen! 14.3 Danke * Leute, die dieses Dokument übersetzt haben (oben,14.2) * Nathan Hurst, sendete viele Korrekturen. * Jon Abbott, sendete viele Artikel über Arithmetik. * Felix Hudson, schrieb das renna Skript * Kees van den Broek, sendet viele Korrekturen, schrieb die "Nützliche Befehle" Sektion neu! * Mike (pink), testet die Skripts und machte Vorschläge um bash im System zu finden * Fiesh, machte einen guten Vorschlag für die "Schlaufen" Sektion. * Lion, machte einen vorschlag wegen "hallo.sh: Command not found.". * Andreas Beck, sendete einige Kommentare und Korrekturen! 14.4 Geschichte Neue Übersetzungen und Hauptkorrekturen. "Nützliche Befehle" Sektion von Kess neugeschrieben Beispiele und String Vergleichen hinzugefügt! v0.8 VersionsAngabe verloren, Datum ist genug! v0.7 Mehr Korrekturen und alte TO-DO Sektionen geschrieben. v0.6 Hauptkorrekturen. v0.5 "Weiterleitungs" Sektion hinzugefügt. v0.4 Ortswechesl zu korrektem Ort: www.linuxdoc.org. 14.5 Mehr Nachschlagewerke Introduction to bash (under BE) http://org.laol.net/lamug/beforever/bashtut.htm Bourne Shell Programming http://207.213.123.70/book/