2018-12-11 10:48:20 +01:00
<!doctype html>
< html lang = "de" >
2018-12-17 18:33:11 +01:00
< meta charset = "utf-8" >
2018-12-11 10:48:20 +01:00
2018-12-17 12:34:44 +01:00
< title > Einführung in Linux< / title >
2018-12-11 10:48:20 +01:00
2018-12-17 12:34:44 +01:00
< meta name = "description" content = "YALC - Yet Another Linux Course " >
2018-12-11 10:48:20 +01:00
< 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" >
2018-12-17 12:34:44 +01:00
< link rel = "icon" href = "img/openlogo-nd-25.png" type = "img/png" >
2018-12-11 10:48:20 +01:00
<!-- 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 >
< / head >
2018-12-17 12:34:44 +01:00
2018-12-11 10:48:20 +01:00
< 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 >
2018-12-17 12:34:44 +01:00
2019-01-02 15:04:16 +01:00
< / section >
< section >
< h2 > Bash Scripting< / h2 >
< h3 > Einführung und Übung< / h3 >
2018-12-11 10:48:20 +01:00
< aside class = "notes" >
2019-01-02 15:04:16 +01:00
Erste skripte, Übungen
2018-12-11 10:48:20 +01:00
< / aside >
< / section >
2019-01-02 15:04:16 +01:00
< 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 style = "font-size: .6em" >
< 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 >
< 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 >
2018-12-11 10:48:20 +01:00
< section >
2019-01-02 15:04:16 +01:00
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 >
2018-12-11 10:48:20 +01:00
< / section >
2019-01-02 15:04:16 +01:00
< 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 >
2018-12-11 10:48:20 +01:00
< / section >
2019-01-02 15:04:16 +01:00
< 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 >
Damit Script wie 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 >
2018-12-11 10:48:20 +01:00
2019-01-02 15:04:16 +01:00
< aside class = "notes" >
PATH nur in der aktuellen Sizung -> sonst in die .bashrc
< / aside >
< / 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 >
< / section >
< section >
< p > Kommando Verkettung< / p >
< ul >
< li class = "fragment " > this< / li >
< / ul >
< / section >
< / div >
2018-12-11 10:48:20 +01:00
< / 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 >