Artikel Debian

Benutzeravatar
davidvajda.de
Site Admin
Beiträge: 1520
Registriert: Di Jul 18, 2023 8:36 pm
Wohnort: D-72072, Tübingen
Kontaktdaten:

Bash Programmierung

Beitrag von davidvajda.de »

Ein erster Code, den ich vorstellen möchte.

Es ist ein typisches Problem - ich möchte auf phpBB3 viele Bilder posten. Oder ich möchte wie jetzt eine Ansammlung an skripten posten. Alle eines Ordners möchte ich in eine Textdatei tun. Damit es nicht zu viele Bilder werden, möchte ich pro Beitrag - 40 Bilder. Die ich selber auf phpBB3 poste. Ich könnte auch ein Bot schreiben, ja, dafür ist es an der Zeit.

Bilder werden in phpBB3 mit

Code: Alles auswählen

[img]bild.jpg[/img]
Codes mit

Code: Alles auswählen

\[code]...["/code]
gebildet. Ich möchte diese Elemente selbstständig anfügen. Hier ein Bash-Skript dafür, in diesem Falle werden sogar unterverzeichnisse des nächsten Levels im Verzeichnis bedient

Code: Alles auswählen

#!/bin/bash 

rm *.txt
l=$(ls)
p=$(pwd)

for s in $l
do
    l2=$(ls $s/*.sh)
    for s2 in $l2
    do
        echo "[code]" >> "$s.txt"
        cat "./$s2" >> "$s.txt"
        echo $s2
        echo "[/code"] >> "$s.txt"
    done

done


Ich möchte hier ein paar Übungen vorstellen

viewtopic.php?t=85

Also, fangen wir an - Bash-Programmierung

Das erste was wir wissen müssen, ist wie wir ein Bash-Skript erstellen
  1. Bash-Skripte editieren - und das wichtigste

    Als erstes müssen wir uns einen Editor suchen, möglich sind, neben vielen weiteren:
    1. Code: Alles auswählen

      KDE: kate
    2. Code: Alles auswählen

      bash: nano
    3. Code: Alles auswählen

      bash: emacs
    Damit erstellen wir ein Bash-Skript

    Code: Alles auswählen

    /home/user/hallo.sh
    
    Hier schreiben wir Minimum rein

    Code: Alles auswählen

    #!/bin/bash 
    
    echo "Hallo Welt"
    
    wir verlassen den Editor und starten das Skript

    Code: Alles auswählen

    /bin/bash hallo.sh
    
    Und erhalten die Ausgabe

    Code: Alles auswählen

    Hallo Welt
    
  2. Dieser Befehl gibt hallo welt aus

    Code: Alles auswählen

    echo "Hallo Welt
    
    Dieser Befehl gibt uns den Inhalt der Datei

    Code: Alles auswählen

    hallo.sh
    
    aus

    Code: Alles auswählen

    cat hallo.sh
    
    Wir erhalten

    Code: Alles auswählen

    david@git:~$ cat hallo.sh 
    #!/bin/bash 
    
    echo "Hallo Welt" 
    david@git:~$ 
    
    kann dateien aneinandergehängt ausgeben

    Code: Alles auswählen

    cat hallo1.sh hallo2.sh
    
  3. Zeichenketten
    • Im Gegensatz zu anderen Programmiersprachen sind Zeichenketten kein eigener Datentyp
    • Code: Alles auswählen

       " abd " 
      Die Anführungsstriche maskieren
    • Was passiert denn, wenn wir zwei
      Zeichenketten haben

      Code: Alles auswählen

      echo Hallo Welt
      
      In dem Falle wird trotzdem

      Code: Alles auswählen

      Hallo Welt
      ausgegeben, weil die Parameter nacheinander ausgibt, wie . aber, was ist, wenn wir an ein Bash-Skript den Namen

      Code: Alles auswählen

      Max Mustermann
      ausgeben wollen

      Code: Alles auswählen

      Max Mustermann
      wird als zwei Zeichenketten interpretiert und

      Code: Alles auswählen

      Mustermann
      . Damit es als ganzes zu einem interpretiert wird muss man eingeben

      Code: Alles auswählen

      "Max Mustermann"
      . Leerzeichen sind bei der Bash immer der Beginn von etwas neuem. Wir werden das bei übergabeparameter an die Bash genauer kennen lernen.
  4. Umleitungen
    • Code: Alles auswählen

      > datei.txt
      Um die Ausgabe eines Programms zum Beispiel

      Code: Alles auswählen

      echo "Hallo Welt"
      
      In eine Datei
      Um zu leiten
      , dass heisst sie werden nicht auf dem Terminal ausgeben, sondern landen in einer Datei - verwendet man das Zeichen
      grösser
      . Dabei wird mit jedem Aufruf der für dieses Zeichen gilt, die Datei, in der die Ausgabe landet, überschrieben.

      Code: Alles auswählen

      echo "Hallo Welt" > datei1.txt
      cat "hallo.sh" > datei2.txt
      
    • Code: Alles auswählen

      >> datei.txt
      Damit die Datei nicht überschrieben wird, wie bei der vorherigen Umlenkung, sondern die neue Ausgabe angehängt wird, gibt es das Zeichen

      Code: Alles auswählen

      echo "#Hallo Welt" >> hallo2.sh
      cat "hallo.sh" >> hallo2.sh
      
      Hier wird die gemeinte Datei nicht überschrieben, sondern der Inhalt wird angehängt
    • Code: Alles auswählen

      < input.txt
      Hier dient zur Umleitung, der Standardeingabe

      Code: Alles auswählen

      stdin
      . Anstatt, dass die Eingabe von der Tastatur kommt, kommt sie aus einer Datei
    • Code: Alles auswählen

      prog1 | prog2
      Hier wird die Ausgabe von Programm

      Code: Alles auswählen

      prog1
      als Eingabe für

      Code: Alles auswählen

      prog2
      verwendet

    Code: Alles auswählen

    cat "hallo" | dd
    

    Code: Alles auswählen

    david@git:~$ cat hallo.sh | dd
    #!/bin/bash 
    
    echo "Hallo Welt" 
    0+1 Datensätze ein
    0+1 Datensätze aus
    33 Bytes kopiert, 2,0113e-05 s, 1,6 MB/s
    david@git:~$ 
    
  5. Einfache Variablen
    1. Definition

      Um eine Variable zu definieren schreiben wir

      Code: Alles auswählen

      s=Hallo
      s2="Hallo Welt"
      s3="Hallo"
      
      Wollen wir erreichen, dass

      Code: Alles auswählen

      Hallo Welt
      wie oben beschrieben zugewiesen werden müssen wir Anführungsstriche verwenden. Wichtig ist - dass zwischen dem Gleichheitszeichen und dem Namen der Variablen und dem konstanten Wert, kein Leerzeichen besteht. Es geht nicht anders. Es geht nur so:

      Code: Alles auswählen

      s=Hallo
      s2="Hallo Welt"
      s3="Hallo"
      
      Was wir wissen müssen, ist, dass wir bei der Definition und Zuweisung eines Wertes kein verwenden. Der Variablennamen steht alleine ohne Haben wir diesen Schritt vollzogen, existieren die Variablen. Wir können auch integre Werte zuweien

      Code: Alles auswählen

      i=0
      x=52
      
    2. Zugriff

      Um auf eine Variable zu zu greifen, brauchen wir nun das Zeichen vor dem Variablennamen

      Code: Alles auswählen

      echo $s
      echo "$s"
      echo "$s2"
      echo "$s3"
      echo $i
      echo "$i"
      echo $x
      echo "$x"
      
      Es macht keinen Unterschied ob das und der Variablennamen nun zwischen Anführungszeichen stehen, sie werden immer als Variable interpretiert. Um das als eigenes Zeichen aus zu geben, müssen wir es maskieren.

      Code: Alles auswählen

      david@git:~$ echo \$Hallo
      $Hallo
      david@git:~$ 
      
  6. Variablen als Argumente für das Bash-Skript

    Wir schreiben folgendes Bash-Skript

    Code: Alles auswählen

    #!/bin/bash 
    
    echo "$1" "$2" "$3"
    
    Und rufen es auf

    Code: Alles auswählen

    david@git:~$ /bin/bash test2.sh Hallo Welt sagt
    Hallo Welt sagt
    david@git:~$ /bin/bash test2.sh Hallo Welt sagt man
    Hallo Welt sagt
    david@git:~$ 
    
    steht für den ersten Parameter an das Bash-Skript usw.
  7. Arithmetische Ausdrücke und verweis auf auf Wir können mit der Bash ganz normal rechnen. Es gibt Mathematische Ausdrücke, wie:

    Code: Alles auswählen

    4+2
    (3+2)*4
    ($i+1)
    ($x+2)*4
    
    Variablen müssen hier mit erscheinen. Es gibt auch Zuweisungen

    Code: Alles auswählen

    y1=4+2
    y2=(3+2)*4
    y3=($i+1)
    y4=($x+2)*4
    i=($i+1)
    
    So sehen wir schon, wir können inkrementieren, wie bei jeder Programmiersprache

    Code: Alles auswählen

    i=($i+1)
    i=($i+1)
    
    Es gibt eine besonderheit. Um der Bash mit zu teilen, dass es sich um einen arithmetischen Ausdruck handelt müssen wir ihn so stellen

    Code: Alles auswählen

    $((<arithmetischer Ausdruck>))$
    
    Wir dürfen uns durch das

    Code: Alles auswählen

    $(())$
    
    Nicht beeindrucken lassen. Was seltsam aussieht, leitet den Ausdruck ein und beendet ihn. Alles, was wir an arithmetischen Ausdrücken schreiben, muss einfach da rein, ungeachtet alles anderen. Das hat nichts mit Variablen zu tun. Wir dürfen uns ebenso wenig dadurch beeindrucken lassen, dass

    Code: Alles auswählen

    (()))
    es jeweils 2 klammern sind. Das gehört einfach dazu. Es leitet arithmetische Ausdrücke ein. Es gibt die Version auch mit einer Klammer

    Code: Alles auswählen

    l=$(ls)
    
    Das bedeutet, der Variablen oder wir als Array die Ausgabe von zugewiesen. Es handelt sich lediglich um Syntax

    So können wir einen funktionierenden Code erstellen:

    Code: Alles auswählen

    i=0
    echo $i
    i=$(($i+1))
    echo $i
    i=$(($i+1))
    echo $i
    
    Jetzt sind wir irritiert. Warum steht:

    Code: Alles auswählen

    i=0
    i=$(($i+1))
    i=$(($i+1))
    
    Das ohne dem wir den Wert zuweisen nicht mit in

    Code: Alles auswählen

    $(())
    . Wir müssen wissen, was der arithmetische Ausdruck selber ist:

    Code: Alles auswählen

    $(($i+1))
    
    Dieser hat einen Wert. Und der gehört in

    Code: Alles auswählen

    $(())
    . Der hat so oder so einen Wert. Da es keine Typen bei der Bash gibt, wird dieser Wert, wie bisher einer Variablen zugewiesen. Wie bei

    Code: Alles auswählen

    s="Hallo Welt"
    i=0
    
  8. Bedingungen

    Code: Alles auswählen

    if then else
    und Verweis auf Pascal

    In Pascal gehen Bedingung so

    Code: Alles auswählen

    IF <condition> THEN
    BEGIN 
    
    END
    ELSE
    BEGIN 
    
    END;
    
    Dies ist die typische Pascal-Syntax. In C schreibt man

    Code: Alles auswählen

    if (Condition) {
    
    }
    else {
    
    }
    
    und

    Code: Alles auswählen

    BEGIN
    und und sehen zwar unterschiedlich aus. Meinen aber das gleiche. Lexikalisch sind es Token. Die typische Pascalsyntax hat folgende Form

    Code: Alles auswählen

    IF <condition> THEN
    BEGIN 
    
    END
    ELSE
    BEGIN 
    
    END;
    
    Es gibt allerdings eine abweichende Notation, was auch gleich ähnlich bei

    Code: Alles auswählen

    WHILE
    gilt:

    Code: Alles auswählen

    IF condition THEN
    ELSE 
    FI
    
    leitet das Ende des

    Code: Alles auswählen

    IF THEN ELSE
    ein. Bei dieser Syntax wird bei

    Code: Alles auswählen

    WHILE DO 
    die Schleife mit

    Code: Alles auswählen

    OD[/beendet]. Oder auch als Variante mit [code]DONE
    Eine Bedingung sieht bei der Bash richtig aus:

    Code: Alles auswählen

    #!/bin/bash
    
    if [ "$1" == "Max Mustermann" ]
    then
    	echo "Hallo"
    elif [ "$1" == "Martin Mustermann" ]
    then 
    	echo "Tschüss"
    else 
    	echo "Super"
    fi
    
    Wichtig sind bei bei den Bedingungen:

    Code: Alles auswählen

    [ ... ]
    
    Die eckigen Klammern. Hierrin muss die Bedingung stehen und sie müssen einen Abstand zu und so weiter haben. Ein Vergleich von Strings geht mit
  9. Schleifen

    Code: Alles auswählen

     while do done 
    und Verweis auf Pascal

    Code: Alles auswählen

     
    while [ Bedingung ] 
    do
    
    done
    
    Worauf wir achten müssen ist, dass das in der nächsten Zeile steht.
  10. Gleich, ungleich, grösser Gleich, Bedingungen, vergleich zu anderen Sprachen

    Wir hatten es von arithmetischen Ausdrücken. In der Mathematik gibt es die Trichonometrie, das heisst, zwischen zwei Zahlen und ihrer Grössenrelation gilt entweder

    Code: Alles auswählen

    <, =, >
    Wir können das beim Programmieren erweitern

    Code: Alles auswählen

    <, <=, =, >, >=
    Und um das Nicht-Gleich

    Code: Alles auswählen

    <, <=, =, >, >=, !=
    Und rein theoretisch, bei intel ist das so, für alles das nicht einführen

    Code: Alles auswählen

    <, <=, =, >, >=, !<, !<=, !=, !>, !>=
    Wir haben also
    1. Gleich
    2. Ungleich
    3. Kleiner
    4. Kleiner Gleich
    5. Grösser
    6. Grösser gleich
    Und eventuell
    1. Gleich
    2. Ungleich
    3. Kleiner
    4. Nicht kleiner
    5. Kleiner Gleich
    6. Nicht Kleiner Gleich
    7. Grösser
    8. Nicht Grösser
    9. Grösser gleich
    10. Nicht Grösser gleich
    das schlägt sich bei Intel und MIPS in den Assemblerbefehlen nieder: Intel verwendet sowohl

    Code: Alles auswählen

    greater
    und

    Code: Alles auswählen

    above
    als auch und

    Code: Alles auswählen

    below
    Intel:

    Code: Alles auswählen

    je 
    jne
    jg, ja
    jng, jna
    jge, jae
    jnge, jnae
    jl, jb
    jnl, jnb
    jle, jbe
    jnle, jnbe
    
    MIPS:

    Code: Alles auswählen

    beq, bne
    blt*, ble*
    bgt*, bge*
    
    Bei der Bash sieht das so aus

    Code: Alles auswählen

    - eq
    - ne
    - gt
    - ge
    - lt
    - le
    
    Diese können wir in der Bedingung für arithmetische Ausdrücke benutzen

    Code: Alles auswählen

    
    WHILE [ $i -lt 10 ]
    DO 
       ...
    DONE
    
    Was sich hinter der Bedingung letzten Endes verbirgt, ist das

    Code: Alles auswählen

    test
    
    Programm. Und jetzt können wir ein Programm schreiben, was zählt und hallo ausgibt

    Code: Alles auswählen

    i=0
    while [ $i -lt 10 ]
    do
    	echo "Hallo zum $(($i+1))."
    	i=$(($i+1))
    done
    
  11. Arrays

    Arrays werden initialisiert mit

    Code: Alles auswählen

    a=(Hallo super Sache)
    
    und erweitert mit

    Code: Alles auswählen

    a+=(Hallo auch)
    
    Also

    Code: Alles auswählen

    a=(Hallo super Sache)
    a+=(Hallo auch)
    
    Um auf das Array zu zu greifen, geht es entweder mit der Schleife, wie im nächsten Beispeil oder mit einem Index

    Code: Alles auswählen

    echo ${a[0]}
    echo ${a[1]}
    echo ${a[2]}
    echo ${a[3]}
    
    Das sieht jetzt etwas kompliziert aus. Aber wie

    Code: Alles auswählen

    $(())
    einen arithmetischen Ausdruck umgibt, umgibt ein einzelnes Element. Das muss es. Für das Element selbst. Zugegriffen wird auf die einzelnen Elemente, wie üblich über Indizes. Was wichtig ist: Innerhalb von wird vor der Variable kein geschrieben. Um die Werte mit einem Variablen Index aus zu geben, muss man sich der etwas umständlich aussehenden Schreibweise bedienen

    Code: Alles auswählen

    i=3
    echo ${a[$i]}
    
    Ist es bei genauerem Hinsehen nicht. Um auf das Ganze Array zu zu greifen verwendet man

    Code: Alles auswählen

    echo "${a[@]}"
    
    [*] Schleifen [code] for ... in .. do 

    Code: Alles auswählen

    l=$(ls)
    
    liefert die Ausgabe von als Array an . Um einzeln aus zu geben, kann man verwenden:

    Code: Alles auswählen

    l=$(ls)
    for s in $l
    do
    	echo "$s"
    done
    
Antworten