<!doctype html> <html lang="de"> <meta charset="utf-8"> <title>Einführung in Linux</title> <meta name="description" content="YALC - Yet Another Linux Course "> <meta name="author" content="Daniel Schubert"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="stylesheet" href="css/reveal.css"> <link rel="stylesheet" href="css/theme/league.css" id="theme"> <link rel="icon" href="img/openlogo-nd-25.png" type="img/png"> <!-- Theme used for syntax highlighting of code --> <link rel="stylesheet" href="lib/css/zenburn.css"> <!-- Printing and PDF exports --> <script> var link = document.createElement( 'link' ); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css'; document.getElementsByTagName( 'head' )[0].appendChild( link ); </script> <style type="text/css"> .reveal img{ max-height: 60vh} </style> </head> <body> <div class="reveal"> <!-- Any section element inside of this container is displayed as a slide --> <div class="slides"> <section data-transition="slide" data-background="#4d7e65" data-background-transition="zoom"> <h1>LINUX</h1> <h3>Das universelle Betriebssystem</h3> <p>Eine Einführung - Teil 4 <p> <small>Deutsche Angestellten Akademie</small> </p> </section> <section> <h2>Bash Scripting</h2> <h3>Einführung und Übung</h3> <aside class="notes"> Erste skripte, Übungen </aside> </section> <section data-transition="slide" data-background="#4d7e65" data-background-transition="zoom"> <h3>Bash Scripting - Warum sollte ich das tun??</h3> <ul> <li class="fragment">Automatisierung</li> <li class="fragment">Vereinfacht komplizierte Vorgänge</li> <li class="fragment">Verringert den Fehlerfaktor „Mensch“</li> <li class="fragment" >YOLO !!1!</li> </ul> </section> <section data-transition="convex"> <h3>Grundlegende Mechanismen</h3> </section> <section> <p> Begriffe <table style="font-size: .4em"> <tbody> <tr> <td class="tabellentext">Wurzelverzeichnis / (engl. root) </td> <td class="tabellentext">Höchstes Verzeichnis im Verzeichnisbaum </td> </tr> <tr> <td class="tabellentext">Aktuelles Arbeitsverzeichnis </td> <td class="tabellentext">Das Verzeichnis, in dem Sie sich im Augenblick befinden </td> </tr> <tr> <td class="tabellentext">Vollständige Pfadangabe </td> <td class="tabellentext">Ein Pfadname beginnend mit / (Wurzel); alle anderen Verzeichnisse werden ebenfalls mit einem / getrennt. </td> </tr> <tr> <td class="tabellentext">Relative Pfadangabe </td> <td class="tabellentext">Der Pfad ist relativ zum aktuellen Arbeitsverzeichnis; hierbei wird kein voranstehendes / verwendet. </td> </tr> <tr> <td class="tabellentext">Vollständiger Dateiname </td> <td class="tabellentext">Pfadangabe inklusive Angabe zur entsprechenden Datei (bspw. /home/you/Dokumente/brief.txt) </td> </tr> <tr> <td class="tabellentext">Vollständiger Pfadname </td> <td class="tabellentext">Pfadangabe zu einem Verzeichnis, in dem sich die entsprechende Datei befindet (bspw. /home/you/Dokumente) </td> </tr> <tr> <td class="tabellentext"><b>..</b> (zwei Punkte) </td> <td class="tabellentext">Verweisen auf ein Inhaltsverzeichnis, das sich eine Ebene höher befindet </td> </tr> <tr> <td class="tabellentext"><b>. </b>(ein Punkt) </td> <td class="tabellentext">Verweist auf das aktuelle Inhaltsverzeichnis </td> </tr> </tbody></table> </section> <section> <p> Benennung von scripten <ul> <li class="fragment ">(lieber) kein Name, den es bereits als Kommando gibt. Einfach testen mit <pre><code>which script_name</code></pre></li> <li class="fragment ">Nur die Zeichen {A..Z}, {a..z}, {0..9} und _ . Sonderzeichen und [space] vermeiden.</li> </ul> <p> </section> <section style="font-size: .6em"> <h3>Sonderzeichen in der Shell <pre><code>; Befehls-Trennzeichen & Hintergrund-Verarbeitung ( ) Befehls-Gruppierung | Pipe < > & Umlenkungssymbole * ? [ ] ~ + - @ ! Meta-Zeichen für Dateinamen ` ` (Backticks) Befehls-Substitution $ Variablen-Substitution [newline] [space] [tab] Wort-Trennzeichen</code></pre> </section> <section> <h3>Variablen</h3> <pre><code> a=hello # einer Variablen "a" den Wert "hello" zuweisen echo $a # die Variable "a" stdout ausgeben a=7 # der Variablen "a" einen neuen Wert zuweisen b=8 # einer Variablen "b" den Wert "8" zuweisen c=$[a+b] # einer Variablen "c" die Summe von a+b zuweisen echo $c # die Variable "c" an stdout ausgeben</code></pre> </section> <section> <h3>vordefinierte Variablen ( Auszug ;-) )</h3> <pre><code>* Alle Aufrufparameter als ein String ("$*" == "$1 $2 $3 ...") @ Alle Aufrufparameter als einzelne Strings ("$@" == "$1" "$2" "$3" ...) # Anzahl der Aufrufparameter ? Rückgabewert des letzten Kommandos $ Prozessnummer der aktiven Shell 0 Name des aktuellen script ERRNO Fehlernummer des letzten fehlgeschlagenen Systemaufrufs PWD Aktuelles Verzeichnis (wird durch cd gesetzt) PATH Suchpfade USER Benutzername</code></pre> <p>Beispiele <pre><code>echo $PATH</code></pre> <pre><code>echo $$</code></pre> <p><small>Mehr: <a href="http://wiki.bash-hackers.org/syntax/shellvars" target="_blank">http://wiki.bash-hackers.org/syntax/shellvars</a></small></p> </section> <section> <p>Var. Zuweisung: <pre><code>a=10</code></pre> <p>Var. Abruf: <pre><code>echo $a</code></pre> </section> <section> <p>Programmstart <ul> <li class="fragment">Programm startet durch Aufruf : <pre><code>ls</code></pre></li> <li class="fragment">überall im Verz. Baum</li> <li class="fragment">Script muss executable gemacht werden<pre><code>chmod +x tolles_script.sh</code></pre></li> <li class="fragment">Script startet durch Aufruf<pre><code>./tolles-script.sh</code></pre></li> </ul> </section> <section> Damit ein Script wie ein Programm startet: <ul> <li class="fragment ">Pfad d. Skriptes der $PATH Variable hinzufügen</li> <li class="fragment "><pre><code>export PATH=$PATH:/pfad/zum/script</code></pre></li> <li class="fragment ">muss in die .bashrc</li> <li class="fragment ">Best Practice: Scripte in Ordner <code>~/bin/</code> -> diesen zur <code>$PATH</code> dazu</li> </ul> <aside class="notes"> PATH nur in der aktuellen Sizung -> sonst in die .bashrc </aside> </section> <section data-transition="slide" data-background="#4d7e65" data-background-transition="zoom"> <h2>Gentlemen, open your Editor! </h2> </section> <section style="font-size: .7em"> <pre><code>#!/bin/bash clear echo "Diese Infos werden von mysystem.sh bereitgestellt." echo "Hallo, $USER" echo "Heute ist der `date \"+%d.%m.%Y - %H:%M:%S\"`, dies ist Woche Nr. `date +"%V"`." echo echo "Diese Benutzer sind im Moment verbunden:" w | cut -d " " -f 1 - | grep -v USER | sort -u echo echo "Dies ist `uname -s` und wir laufen auf einem $(uname -m) Prozessor." echo echo "Die uptime ist:" uptime MSG="\nDas ist alles! Bye, $USER! \n\n" printf "${MSG}"</code></pre> <p><small><a href="https://www.schubertdaniel.de/linuxkurs" target="_blank">https://www.schubertdaniel.de/linuxkurs</a></small> <p><small><a href="https://git.scytec.de/danthefan/linuxkurs/raw/master/beispiele/mysystem.sh" target="_blank">https://git.scytec.de/danthefan/linuxkurs/raw/master/beispiele/mysystem.sh</a></small> </section> <section> <pre><code>echo "Hallo, $USER"</code></pre> <pre class="fragment"><code>echo "Heute ist der `date \"+%d.%m.%Y - %H:%M:%S\"` "</code></pre> <pre class="fragment"><code>w | cut -d " " -f 1 - | grep -v USER | sort -u</code></pre> <pre class="fragment"><code>`uname -s` vs $(uname -s) </code></pre> <pre class="fragment"><code>MSG="\nDas ist alles! Bye, $USER! \n\n" printf "${MSG}"</code></pre> </section> <section> <p>Ausführende Shell festlegen ( sog. She-Bang )</p> <pre><code>#!/bin/bash</code></pre> <pre><code>#!/usr/bin/env ruby</code></pre> <pre><code>#!/usr/bin/env python3</code></pre> <pre><code>#!/usr/bin/php</code></pre> <span class="fragment"> Nötig, damit die shell weiss, wie das script interpretiert werden soll.</span> </section> <section> Script ohne she-bang: <pre><code>bash mysql-backpup.sh</code></pre> <pre><code>. mysql-backpup.sh</code></pre> <span class="fragment">oder <pre><code>php mysql-backpup.php</code></pre> <span class="fragment">oder <pre><code>ruby mysql-backpup.rb</code></pre> </section> <section> <p>Prozess in der bash - Erklärung:</p> <div class="fragment"> <p>neue Datei anlegen : finduser </p> <pre><code>#!/bin/bash find / -user dany -print 2>/dev/null</code></pre> </div> <div class="fragment"> Dann im Terminal ausführen <pre><code>dany@laptop:~/bin$ chmod u+x finduser dany@laptop:~/bin$ ./finduser 1>/dev/null &</code></pre> <pre><code>dany@laptop:~/bin$ ps -f</code></pre> </div> <aside class="notes"> </aside> </section> <section style="font-size: .7em"> <pre><code>UID PID PPID C STIME TTY TIME CMD dany 4987 23893 0 12:50 pts/4 00:00:00 /bin/bash ./finduser dany 4988 4987 68 12:50 pts/4 00:00:01 find / -user dany -print dany 5011 23893 0 12:50 pts/4 00:00:00 ps -f dany 23893 4143 0 12:33 pts/4 00:00:00 bash </code></pre> <p class="fragment "> Die bash startet eine sub-shell, in der das Kommando ausgeführt wird <p class="fragment "> Der <span class="fragment highlight-red">Kontext</span> aller Script Variablen ist der der <span class="fragment highlight-red">sub-shell</span> </section> <section> <div><span style="color: orange">Aufgabe:</span> Erstellt ein script, das alle Dateien in eurem home in einer tar.gz - Datei archiviert, das Verzeichnis "~/archiv" erstellt, und die tar.gz Datei dorthin verschiebt.<br /> Hinweis: tar -czf ..... <p class="fragment">https://linuxconfig.org/bash-scripting-tutorial</p> </div> <div class="fragment"><pre><code>#!/bin/bash tar -czf myhome_directory.tar.gz /home/$USER mkdir archiv mv myhome_directory.tar.gz archiv/ </code></pre> </div> </section> <section> <h3>Kontrollstrukturen</h3> </section> <section> <h4>if then </h4> <img src="img/if_then_else.svg"> </section> <section><pre><code>#!/bin/bash cd ls if [ -e sample.sh ] then echo "file exists!" else echo "file does not exist" fi</code></pre></section> <section> <h4>if then elif</h4> <img src="img/2_if_then_elif_fi.svg"> </section> <section><pre style="font-size: .35em"><code>#!/bin/bash cd ls -l read -p "Enter a file name: " filename if [ -e $filename ] then echo "file exists!" if [ -r $filename ] then status="readable " fi if [ -w $filename ] then status=$status"writable " fi if [ -x $filename ] then status=$status"executable" fi echo "file permission: "$status else echo "file does not exist" fi</code></pre></section> <section> <h4>for loop</h4> <img src="img/for.svg"> </section> <section><pre><code>#!/bin/bash for f in {1..9} do touch "$f xx.txt" done</code></pre></section> <section> Ein weiteres Beispiel: <pre><code>#!/bin/bash suf=$1 if [ $# -gt 0 ] then for file in *.$suf; do bn=`basename "$file" .$suf | tr [:blank:] _` new=$bn.$suf echo "neuer Dateiname:" echo $new mv "$file" $new done else echo "Verwendung: strip-space.sh SUFFIX" echo "Beende ...." fi </code></pre> <aside class="notes">beispiele/create_files_with_spaces.sh</aside> </section> <section> <h4>case</h4> <img src="img/3_case_var.jpg"> </section> <section><pre style="font-size: .35em"><code>#!/bin/bash clear read -p "Integer1: " int1 read -p "Integer2: " int2 printf "Menu: \n[a] Addition\n[b]Subtraction\n[c]Multiplication\n[d]Division\n" echo "======================" read -p "Your choice: " choice res=0 case $choice in a) res=$((int1+int2)) ;; b) res=$((int1-int2)) ;; c) res=$((int1*int2)) ;; d) res=$((int1/int2)) ;; *) echo "Invalid input" esac echo "The result is: " $res</code></pre></section> <section> <h4>while loop</h4> <img src="img/4_while.svg"> </section> <section><pre><code>#!/bin/bash x=1 while [ $x -le 5 ] do echo "Welcome $x times" x=$(( $x + 1 )) done</code></pre></section> <section> <h4>until loop</h4> <img src="img/until.svg"> </section> <section><pre><code>#!/bin/bash i=1 until [ $i -gt 6 ] do echo "Welcome $i times." i=$(( i+1 )) done</code></pre></section> <section><h3>while vs until</h3> <ol> <li>until läuft bis Bedingung nicht 0 (false)</li> <li>while läuft bis Bedingung 0 (true)</li> <li>until läuft mind. einmal</li> </ol> </section> </div> </div> <script src="lib/js/head.min.js"></script> <script src="js/reveal.js"></script> <script> // More info https://github.com/hakimel/reveal.js#configuration Reveal.initialize({ controls: true, progress: true, history: true, center: true, transition: 'slide', // none/fade/slide/convex/concave/zoom // More info https://github.com/hakimel/reveal.js#dependencies dependencies: [ { src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } }, { src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, { src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, { src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }, { src: 'plugin/search/search.js', async: true }, { src: 'plugin/zoom-js/zoom.js', async: true }, { src: 'plugin/notes/notes.js', async: true } ] }); </script> </body> </html>