490 lines
15 KiB
HTML
490 lines
15 KiB
HTML
<!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: .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>
|
|
<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>
|
|
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>
|
|
<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">
|
|
</section>
|
|
<section><pre><code>#!/bin/bash
|
|
for f in {1..9}
|
|
do
|
|
touch "$f xx.txt"
|
|
done</code></pre></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>
|