Bash Programmierung

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen

Bash Basics

Weitere Möglichkeiten der Bash-Shell

Alias-Namen

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

#!/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

Gleichzeitiges Lesen aus Datei und Standardeingabe

#!/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

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

#!/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
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.


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:

\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:

%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

#!/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

Links

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.
if [ -f "$ FILE"]
  • um leere Zeichenfolgen oder Dateinamen mit Leerzeichen richtig zu behandeln. Mit "[[" sind die Anführungszeichen unnötig:
if [[ -f $ FILE ]]
  • 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
if ["$ ANSWER" = y -o "$ ANSWER" = yes]
  • Mit [[ können Sie dies als schreiben
if [[ $ ANSWER = ~ ^ y (es)? ]]
  • 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