# Einführung in Linux
YALC - Yet Another Linux Course
Author: Daniel Schubert

# LINUX

### Das universelle Betriebssystem

Eine Einführung - Teil 5

Deutsche Angestellten Akademie

Frage: Fragen zur letzten Stunde?

### LINKS

http://tldp.org/LDP/abs/html/complexfunct.html

http://programmingexamples.wikidot.com/bash-scripting#toc24

- script kontrolle ( strg-z etc ) - input - parameter - functions - kontrollstrukturen -

## Bash scripting - Fortsetzung

### Wiederholung

### Variablen

    #!/bin/bash

    x=10            #NICHT x = 10 -> keine Leerzeichen!
    X=20            #variablen sind Case Sensitive
    $y=             #NULL variable
    echo "x = $x"
    echo "X = $X"
    echo "y = $y"
    unset x 		#variable löschen
    echo $x

### Kommentare

    #!/bin/bash
    # Diese Zeile ist ein Kommentar
    echo "A comment will follow." # Comment here.
    echo "The # here does not begin a comment."
    echo 'The # here does not begin a comment.'
    echo The \# here does not begin a comment.
    echo The # here begins a comment.

    echo ${PATH#*:}       # Parameter substitution, not a comment.
    echo $(( 2#101011 ))  # Base conversion, not a comment.

### Quoting

- `" "` (Anführungszeichen) Alles zwischen diesen Zeichen ist buchstabengetreu zu interpretieren. Ausnahmen :`$ ` " \`
- `' '` (Ticks) Alles zwischen diesen Zeichen wird wörtlich genommen, mit Ausnahme eines weiteren `'`.
- `\` (Backslash) Das Zeichen nach einem `\` wird wörtlich genommen. Anwendung z. B. innerhalb von " ", um ", $ und ` zu entwerten.
- `` `` (Backticks) Alles innerhalb wird als Kommando interpretiert.

    $ echo 'Ticks "schützen" Anführungszeichen'
    Ticks "schützen" Anführungszeichen

    $ echo "Ist dies ein \"Sonderfall\"?"
    Ist dies ein "Sonderfall"?

    $ echo "Sie haben `ls | wc -l` Dateien in `pwd`"
    Sie haben 43 Dateien in /home/dany

    $ echo "Der Wert von \$x ist $x"
    Der Wert von $x ist 100

    # Maskierung der Leerstelle mit \
    message="hallo Welt"
    message=hello\ Welt

    echo 'So sprach'"'"'s und ging ohne einen Backslash (\) weiter.'
         └───┬───┘└┬┘└──────────────────┬─────────────────────┘
              │      │                       │
              │      │                       └ Dritter Bereich: Wieder
              │      │                         von ' umschlossen, der
              │      │                         Backlash verliert
              │      │                         seine Sonderbedeutung.
              │      │
              │      └ Zweiter Bereich: Von " umschlossen, enthält ein
              │        einzelnes '.
              │
              └ Erster Bereich: Von ' umschlossen.

### Input - Output redirection

    #!/bin/bash
    # > : output in Datei. Best. Datei wird überschrieben!
    ls > file_list

    # >> : output an Datei anhängen.
    ls -la >> file_list

    # < : Kommando Input aus Datei lesen
    cat < file_list

Man kann Kommandos auch verkettten:

Kommando1; Kommando2 | fühert die Kommandos hintereinander aus
Kommando1 && Kommando2 | führt Kommando2 aus, wenn kommando1 erfolgreich war
Kommando1 || Kommando2 | führt Kommando2 aus, wenn kommando1 NICHT erfolgreich war
Kommado & | Führt Kommando im Hintergrund aus
Kommando1 & Kommando2 | startet Kommando1 im Hintergrund, Kommando2 im Vordergrund
( Kommando1; Kommando2 ) | Führt die beiden K. nacheinander in einer Subshell aus

    sudo apt-get update && sudo apt-get upgrade -y

    tar cf archiv.tar && rm *.doc || echo "fehler"

Aufgabe: Erstellt ein script, das den Inhalt eures home in eine Variable `liste` schreibt, und gebt den Inhalt dieser Variablen in eine Textdatei `liste.txt` aus.
Hinweis: ls , tee

    #!/bin/bash
    OUTFILE="liste.txt"

    liste=`ls`
    echo $liste > $OUTFILE

    #mit tee in einer Zeile
    liste=`ls | tee $OUTFILE`

    cat $OUTFILE

### exit status

    exit 0

heisst : alles gut gelaufen

    exit 1

heisst : kommando fehlgeschlagen

der exit code in scripten kann beliebig gesetzt werden

Standard: exit 0 -> alles fein

### Funktionen

    #!/bin/bash

    #Funktions Deklaration:
    count () {
      ls | wc -l

      # ls: Liste aller Objekte im Verzeichnis
      # wc: Word-Count; mit Attribut -l werden Zeilen gezählt
      # in Verbindung mit ls werden also die
      # (nicht versteckten) Objekte gezählt
    }

    count        # Aufruf der Funktion

    #!/bin/sh

    fatal() {
         msg=$1
         echo "Fatal: $msg"
         exit 1
    }

    [ -d /tmp ] || fatal "Verzeichnis /tmp existiert nicht"
    [ -w /tmp ] || fatal "Verzeichnis /tmp nicht schreibbar"

    TMP=/tmp/mydir
    [ -d $TMP ] || mkdir $TMP    # tmp-Verz. erzeugen, wenn noch nicht vorhanden

    #!/bin/bash
    count2 () {
    	# überprüfen, ob der erste Parameter ein Verzeichnis ist
    	if [ -d "$1" ]; then
    		ls $1 | wc -l
    		exit 0            # alles OK
    	else
    		echo "Ungültiges Verzeichnis: $1"
    		exit 1            # Fehler
    	fi
    }
    count2 "/gibt/es/garnicht"  # Aufrufe der Funktion count2
    echo "Status: $?"

    count2 "/etc"
    echo "Status: $?"

Aufgabe: Erstellt script mit mind einer Funktion das:

- ein Backup eines Verzeichnisses erstellt
- per Parameter den namen des Quell-Verzeichnis erhält
- per Parameter den Namen der Zieldatei erhält
- einen nützlichen exit code setzt
- vielleicht nützliche Meldungen ausgibt

Tipps:

- Parameter Übergabe: kommando param1 param2
- Parameter Übernahme: param1 = $1 , param2 = $2 etc

    #!/bin/bash
    function file_backup {
    	echo 'Backup --- building tar File...'
    	tar -czf $2 $1 || fail "Fehler beim Archiv erstellen"
    	echo '+DONE'

    	exit 0
    }

    fail () {
    	echo "Fehler! + $1"
    	exit 1
    }

    #function call
    # file_backup 'backup-quelle' 'backup-ziel.tar.gz'
    file_backup $1 $2

hinzufügen überprüfung ob quelle verz.
überprüfung ob ziel existiert
überpr. ob ziel angelegt
überprüf ob param vorhanden
backup verz anlegen

#### Script Kontrolle

- CTRL + C - Abbbruch
- CTRL + Z - Pausieren
- `fg` - Fortsetzen
- `bg` - im Hintergrund Fortsetzen
- CTRL + D - Eingabe beenden

#### Job Control

    #!/bin/bash
    find / -name *lib* 	2>/dev/null > libs.txt

    # CTRL - Z

    jobs

    fg

    # CTRL - Z

    bg

cat > test.txt
dd
ff
gg
CTRL - D

    Integer Berechnungen
    let "m = 4 * 1024";echo $m

    let "m += 15"
    let "m -= 3"
    let "m /= 5"
    let "m %= 10"
    let "m++"
    let "m--"

    Floating Point:
    echo "32.0 + 1.4" | bc

    echo `expr $m + 18`
    m=`expr $m + 18`

    (( m *= 4 ))

ternary operator

    let "k = (m < 9) ? 0 : 1"
    condition ? value-if-true : value-if-false

### Maus ist voll 90er !!

https://github.com/agarrharr/awesome-cli-apps https://github.com/alebcay/awesome-shell