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 >
2019-01-04 10:41:14 +01:00
< style type = "text/css" >
.reveal img{ max-height: 60vh}
< / style >
2018-12-11 10:48:20 +01:00
< / 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 >
2019-01-04 10:41:14 +01:00
< 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 >
2019-01-02 15:04:16 +01:00
< 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 >
2019-01-04 10:41:14 +01:00
< 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 >
2019-01-02 15:04:16 +01:00
< / 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 >
2019-01-04 10:41:14 +01:00
2018-12-11 10:48:20 +01:00
2019-01-04 10:41:14 +01:00
< 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 >
< dir class = "fragment" > < pre > < code > #!/bin/bash
tar -czf myhome_directory.tar.gz /home/$USER
mkdir archiv
mv myhome_directory.tar.gz archiv/
< / code > < / pre > < / dir >
< / 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" >
2019-01-02 15:04:16 +01:00
< / section >
2019-01-04 10:41:14 +01:00
< section > < pre > < code > #!/bin/bash
for f in {1..9}
do
touch "$f xx.txt"
done< / code > < / pre > < / section >
2019-01-02 15:04:16 +01:00
< 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 >
2019-01-04 10:41:14 +01:00
< aside class = "notes" > beispiele/create_files_with_spaces.sh< / aside >
2019-01-02 15:04:16 +01:00
< / section >
< section >
2019-01-04 10:41:14 +01:00
< 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" >
2019-01-02 15:04:16 +01:00
< / section >
2019-01-04 10:41:14 +01:00
< 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 >
2019-01-02 15:04:16 +01:00
< / 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 >