Bash Programmierung: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(53 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
=Bash Basics=
+
=Allgemeines=
*[[Einfache Shellsonderzeichen]]
+
*[[Thomas Will]]
*[[Bash Eingabe/Ausgabe]]
+
*[[Zeiten]]
*[[Jokerzeichen]]
+
=Themen=
*[[Prinzip der Bash]]
+
*[[Bash Programmierung Inhalt]]
*[[Interpretator]]
+
<!-- == Tag 1 ==  -->
*[[Ablauf eines Shell-Skriptes]]
+
* [[Die Geschichte der Shells]]
*[[Möglichkeiten ein Shellskript aufzurufen]]
+
* [[Ziele des IT Trainings Bash Programmierung]]
*[[Bash Variablen]]
+
* [[Arten von Shells]]
*[[Bash Dateien]]
+
* [[Prinzip der Bash]]
*[[Here Dokument]]
+
* [[Unterschiede zwischen bash und powershell]]
*[[read-Kommando]]
+
* [[Skript Interpreten in Linux]]
*[[Einfache Verzweigungen]]
+
* [[Möglichkeiten ein Shellskript aufzurufen]]
*[[Endestatus]]
+
* [[Bash Eingabe/Ausgabe]]
*[[test-Kommando]]
+
* [[Bash Pipe]]
*[[Optionen der Bash]]
+
* [[Einfache Shellsonderzeichen]]
*[[Bash Der if-Block]]
+
* [[Jokerzeichen/Wildcard]]
*[[Bash Der case-Block]]
+
* [[Ein paar Kommandos]]
*[[Rechnen mit der Bash]]
+
* [[Kommandolokalisierung]]
*[[Bash Die while-Schleife]]
+
* [[Bash ssh in Programmen nutzen]]
*[[Bash Die until-Schleife]]
+
<!-- == Tag 2 == -->
 +
* [[Ablauf eines Shell-Skriptes]]
 +
* [[Bash Variablen]]
 +
* [[Bash Dateien]]
 +
* [[Here Dokument]]
 +
* [[Here String]]
 +
* [[read-Kommando]]
 +
* [[Endestatus]]
 +
* [[Bash Einfache Verzweigungen]]
 +
* [[test-Kommando]]
 +
* [[Bash Das neue Test Kommando]]
 +
* [[Rechnen mit der Bash]]
 +
<!-- == Tag 3 == -->
 +
<!-- == Tag 4 == -->
 +
* [[Bash Der if-Block]]
 +
* [[Bash Der case-Block]]
 +
* [[Bash Die while-Schleife]]
 +
* [[Bash Die until-Schleife]]
 +
* [[Bash Die for-Schleife]]
 +
* [[Bash Steuerung der Ablaufanweisungen]]
 +
* [[Bash funktion]]
 +
* [[cron]]
 +
* [[Bash Signalverarbeitung]]
 +
<!-- == Tag 5 == -->
 +
* [[Bash printf]]
 +
* [[Aliase]]
 +
* [[Prozesse]]
 +
* [[Bash Filedeskriptoren]]
 +
* [[Bash Farben]]
 +
* [[Bash getopts]]
 +
* [[Bash eval]]
 +
* [[Optionen der Bash]]
 +
* [[Bit Operationen mit der Bash]]
 +
* [[Bash Skripte]]
 +
* [[Mail Kommando]]
 +
* [[Bash Passwort generieren]]
 +
* [[Bash Alter eine Datei]]
 +
* [[Ssh VPN]]
 +
* [[Aufgaben gesamt]]
  
*[[Bash Die for-Schleife]]
+
= Links=
 
+
* http://openbook.rheinwerk-verlag.de/shell_programmierung/
*[[Bash Steuerung der Ablaufanweisungen]]
+
* http://mywiki.wooledge.org/BashFAQ/031
 
+
* http://tldp.org/LDP/abs/html/index.html
*[[bash funktion]]
+
* http://openbook.rheinwerk-verlag.de/shell_programmierung/shell_006_003.htm
 
+
* https://kuepper.userweb.mwn.de/informatik/printf.pdf
*[[Bash Signalbehandlung]]
 
 
 
=Weitere Möglichkeiten der Bash-Shell=
 
==Alias-Namen==
 
*[[aliase]]
 
 
 
=Filedeskriptoren=
 
==Schreibenden Deskriptor==
 
;anlegen
 
*exec 5> /tmp/five
 
;rein schreiben
 
*echo eins >&5
 
*echo zwei >&5
 
*echo drei >&5
 
;ausgeben
 
*cat /tmp/five
 
;aufheben
 
*exec 5>&-
 
;führt zu Fehler
 
*echo vier >&5
 
==Lesender Deskriptor==
 
;anlegen
 
*exec 7< /etc/hosts
 
;auslesen
 
*cat <&7
 
;geht nur einmal
 
*cat <&7
 
 
 
==Gleichzeitiges Lesen aus verschiedenen Dateien==
 
<syntaxhighlight>
 
#!/bin/bash
 
exec 3< /etc/passwd
 
exec 4< /etc/shadow
 
while true
 
do
 
  read var3 <&3
 
  read var4  <&4
 
  echo passwd  $var3
 
  echo shadow $var4 ;
 
  test -z $var4 && break
 
done
 
</syntaxhighlight>
 
==Gleichzeitiges Lesen aus Datei und Standardeingabe==
 
<syntaxhighlight>
 
#!/bin/bash
 
exec 3< $1
 
while read line <&3
 
do
 
  echo $line
 
  printf "Eine weitere Zeile einlesen? [j/n] : "
 
  read REPLY
 
  test "$REPLY" = "n"  && break
 
done
 
</syntaxhighlight>
 
 
 
=Bearbeiten von Farben=
 
 
 
Um die Farben in der Shell zu ändern, müssen wir bestimmte Zeichenfolgen senden. Die Zeichenkette \033\13301;31m würde z.B. alles Weitere in Rot ausgeben.
 
 
 
Format: \033\133;m
 
 
 
Diese Methode kann allerdings beim Setzen der Variable $PS1, die den Prompt kontrolliert, dazu führen, dass der Zeilenumbruch falsch berechnet wird. Deshalb ist in diesem Fall der Einschluss in \[ \] erforderlich.
 
 
 
Format: \[\033\133;m\]
 
 
 
Um mit dem Farbigen aufzuhören und wieder normal zu schreiben sendet man einfach folgende Zeichenfolge:
 
 
 
\033\1330m
 
 
 
Textdekorationen:
 
00 - Schmaldruck
 
01 - Keine
 
02 - dunkle Version der Farbe
 
04 - Unterstreichen
 
05 - Invertieren
 
 
 
Farben:
 
30 - Schwarz
 
31 - Rot
 
32 - Grün
 
33 - Gelb
 
34 - Blau
 
35 - Lila
 
36 - Cyan
 
37 - Grau
 
 
 
Hintergründe färben:
 
40 - Schwarz
 
41 - Rot
 
42 - Grün
 
43 - Gelb
 
44 - Blau
 
45 - Lila
 
46 - Cyan
 
47 - Grau
 
 
 
Austesten wie es dann genau aussieht kann man das mit den folgenden Befehlen:
 
 
 
for i in `seq 40 47`;do echo -e "Farbnummer:\033\13301;"$i"m $i \033\01330m";done
 
for i in `seq 30 37`;do echo -e "Farbnummer:\033\13301;"$i"m $i \033\01330m";done
 
 
 
=getopts=
 
<syntaxhighlight>
 
#!/bin/bash
 
function examine()
 
{
 
FILE=$1
 
shift
 
echo "Rights on $FILE"
 
for k in $*
 
do
 
case $k in
 
u) echo USER : $(ls -l $FILE | cut -c 1-3) ;;
 
g) echo GROUP: $(ls -l $FILE | cut -c 4-6) ;;
 
o) echo OTHER: $(ls -l $FILE | cut -c 7-9) ;;
 
esac
 
done
 
}
 
while getopts ugof: opt
 
do
 
  case $opt in
 
      u) OPT="${OPT} u";;
 
      g) OPT="${OPT} g";;
 
      o) OPT="${OPT} o";;
 
      f) DAT=$OPTARG;;
 
      ?) echo "USAGE: $0 -ugo -f FILE"; exit 2 ;;
 
  esac
 
done
 
examine $DAT $OPT
 
</syntaxhighlight>
 
;Erklärung
 
*Das Program kann mit den Optionen -u -g -o und -f Datei aufgerufen werden.
 
*Die Optionen ugo werden in der Variable $OPT "gesammelt".
 
*Alle Optionen werden an die Funktion examine übergeben.
 
*Die Optionen werden oben getrennt und je nach vorhandener Option werden Anweisungen ausgeführt.
 
 
 
 
 
*http://openbook.galileocomputing.de/shell_programmierung/shell_005_007.htm
 
 
 
=printf=
 
Formatierte Ausgabe mit printf
 
 
 
Im einfachsten Fall wird ein fester Text auf dem Bildschirm ausgegeben:
 
*printf("Dies ist ein einfaches Beispiel");
 
Der Text kann auch Sonderzeichen (z. B. Zeilenumbrüche) enthalten:
 
*printf("Hier werden \n zwei Zeilen ausgegeben!");
 
Die Zeichensequenz \n bewirkt einen Sprung an den Anfang der folgenden Bildschirmzeile. Weitere gebräuchliche Sonderzeichen sind:
 
{| class="wikitable"
 
|-
 
|\n
 
|Sprung an den Anfang der folgenden Bildschirmzeile
 
|-
 
|\b
 
|Gehe ein Zeichen zurück
 
|-
 
|\a
 
|Akustisches Signal
 
|-
 
|\r
 
|Sprung an den Anfang der aktuellen Bildschirmzeile
 
|-
 
|\\
 
|Ausgabe des Gegenschrägstrichs "\" (Backslash)
 
|-
 
|%%
 
|Ausgabe des Prozent-Zeichens "%"
 
|-
 
|\"
 
|Ausgabe eines doppelten Anführungszeichens
 
|-
 
|\t
 
|Sprung zur nächsten Tabulatorposition
 
|}
 
Sollen aktuelle Variablenwerte ausgegeben werden, werden in den Aufruf der
 
 
 
Funktion printf entsprechende „Platzhalter“ eingefügt:
 
*int x = 10;
 
*printf("Der Wert %d wurde der Variablen x zugewiesen.", x);
 
Auf dem Bildschirm erfolgt die Ausgabe „Der Wert 10 wurde der Variablen x zugewiesen“, es wird also der Platzhalter %d durch den aktuellen Wert der Variablen x
 
ersetzt. Es ist möglich, mehrere Variablen zugleich auszugeben:
 
*int x = 123, y = 234;
 
*printf("x = %d und y = %d", x, y);
 
Die Ausgabe lautet in diesem Fall „x = 123 und y = 234“. Für jede Variable ist ein
 
eigener Platzhalter (hier: %d) notwendig. Die auszugebenden Variablen werden
 
durch Kommas getrennt aufgelistet. Für jeden Platzhalter muss dabei eine Variable angegeben werden (hier: x, y).
 
Es ist zu beachten, dass der Platzhalter zum Typ der auszugebenden Variablen
 
passt (z. B. dient %d zur Ausgabe einer Variablen des Typs int, short oder long).
 
Weitere Platzhalter sind:
 
 
 
{| class="wikitable"
 
|-
 
|%d, %i
 
|int, short, long
 
|Ganze Zahl
 
|-
 
|%x, %X
 
|int, short, long
 
|Ganze Zahl, Ausgabe als Hexadezimalzahl
 
|-
 
|%f
 
|float, double
 
|Fließkommazahl
 
|-
 
|%e, %E
 
|float, double
 
|Fließkommazahl, Ausgabe im Exponentialformat
 
|-
 
|%c
 
|char
 
|Einzelnes Zeichen (Buchstabe, Ziffer, …)
 
|-
 
|%s
 
|char*
 
|Zeichenkette („String“)
 
|}
 
;Beispiel:
 
*int i = 10; double d = 22.22; char c = 'X';
 
*char* str = "abcdefg...";
 
*printf("Beispiel zu printf:\n");
 
*printf("%d, %f, %c\n", i, d, c);
 
*printf("%s", str);
 
Es kann die Breite des Ausgabebereichs angegeben werden. So wird mit %10d
 
eine ganze Zahl rechtsbündig in einem Bereich von 10 Zeichen Länge ausgegeben:
 
int i = 123;
 
*printf("->%d<-\n", i);
 
*printf("->%4d<-\n", i);
 
*printf("->%5d<-\n", i);
 
Bei der Ausgabe von Fließkommazahlen kann zusätzlich zur Länge des Ausgabebereichs die Anzahl der Nachkommastellen eingestellt werden:
 
*float f = 123.625;
 
*printf("->%f<-\n", f);
 
*printf("->%.2f<-\n", f);
 
*printf("->%10.0f<-\n", f);
 
*printf("->%10.1f<-\n", f);
 
*printf("->%10.2f<-\n", f);
 
*printf("->%10.3f<-\n", f);
 
*printf("->%10.4f<-\n", f)
 
==Beispielskript==
 
<syntaxhighlight>
 
#!/bin/bash
 
for DIR in $(df -t ext4  | awk 'NR>1 {  print $6 }')
 
do
 
  PROZENT=$(df -t ext4 $DIR | awk 'NR>1 {  print $5 }')
 
  PRO=$(echo $PROZENT | tr -d "%")
 
  let KI=PRO*20/100
 
  let MI=20-KI
 
    K="####################"
 
    M='--------------------'
 
  printf "%-10s%-4s%.${KI}s%.${MI}s" $DIR $PROZENT $K $M
 
    echo
 
done
 
</syntaxhighlight>
 
==Links==
 
*https://linuxconfig.org/bash-printf-syntax-basics-with-examples
 
 
 
=Das neue Test Kommando=
 
*"[[" ist Bashs Verbesserung des "[" Befehls.
 
*Es ist die bessere  Wahl, wenn Sie Skripte schreiben, die auf Bash abzielen. Meine Favoriten sind:
 
*Es ist eine syntaktische Funktion der Shell, daher weist sie ein besonderes Verhalten auf, das "[" nicht hat.
 
*Variablen müssen nicht mehr quotiert werden, da leere Zeichenfolgen und Zeichenfolgen mit Leerzeichen intuitiver behandelt werden.
 
*Zum Beispiel müssen Sie mit "[" schreiben.
 
<pre>
 
if [ -f "$ FILE"]
 
</pre>
 
*um leere Zeichenfolgen oder Dateinamen mit Leerzeichen richtig zu behandeln. Mit "[[" sind die Anführungszeichen unnötig:
 
<pre>
 
if [[ -f $ FILE ]]
 
</pre>
 
*Da es sich um eine syntaktische Funktion handelt, können Sie && und || verwenden Operatoren für Boolesche Tests und <und> für Zeichenfolgenvergleiche.
 
*[ kann dies nicht tun, da es sich um einen regulären Befehl handelt und &&, ||, <und> nicht als Befehlszeilenargumente an reguläre Befehle übergeben werden.
 
 
 
*Es hat einen wunderbaren Operator = ~, um Übereinstimmungen mit regulären Ausdrücken zu erstellen. Mit [ könntest du schreiben
 
<pre>
 
if ["$ ANSWER" = y -o "$ ANSWER" = yes]
 
</pre>
 
*Mit [[ können Sie dies als schreiben
 
<pre>
 
if [[ $ ANSWER = ~ ^ y (es)? ]]
 
</pre>
 
*Sie können sogar auf die erfassten Gruppen zugreifen, die in BASH_REMATCH gespeichert sind.
 
*Zum Beispiel wäre $ {BASH_REMATCH [1]} "es", wenn Sie oben ein vollständiges "ja" eingeben.
 
*Sie erhalten die Mustererkennung aka Globbing kostenlos.
 
*Vielleicht sind Sie weniger streng im Schreiben von Ja. Vielleicht bist du okay, wenn der Benutzer y-irgendetwas eingibt. Haben Sie sich versichert:
 
*wenn $ ANSWER = y *
 
 
 
=Links=
 
*http://openbook.rheinwerk-verlag.de/shell_programmierung/
 
*http://mywiki.wooledge.org/BashFAQ/031
 
*http://tldp.org/LDP/abs/html/index.html
 
*http://openbook.rheinwerk-verlag.de/shell_programmierung/shell_006_003.htm
 
*https://kuepper.userweb.mwn.de/informatik/printf.pdf
 

Aktuelle Version vom 9. Juni 2023, 06:25 Uhr