Linux Professional Institute Learning Logo.
Weiter zum Inhalt
  • Home
    • Alle Ressourcen
    • LPI Lernmaterialien
    • Mitmachen
    • Publishing Partner
    • Publishing Partner werden
    • Über uns
    • FAQ
    • Mitwirkende
    • Roadmap
    • Kontakt
  • LPI.org
3.3 Lektion 2
Thema 1: Die Linux-Community und Karriere im Open-Source-Umfeld
1.1 Die Entwicklung von Linux und gängige Betriebssysteme
  • 1.1 Lektion 1
1.2 Die wichtigsten Open-Source-Anwendungen
  • 1.2 Lektion 1
1.3 Open-Source-Software und -Lizenzen
  • 1.3 Lektion 1
1.4 IKT-Fähigkeiten und Arbeiten mit Linux
  • 1.4 Lektion 1
Thema 2: Sich auf einem Linux-System zurechtfinden
2.1 Grundlagen der Befehlszeile
  • 2.1 Lektion 1
  • 2.1 Lektion 2
2.2 Hilfe suchen über die Befehlszeile
  • 2.2 Lektion 1
2.3 Verzeichnisse verwenden und Dateien auflisten
  • 2.3 Lektion 1
  • 2.3 Lektion 2
2.4 Erstellen, Verschieben und Löschen von Dateien
  • 2.4 Lektion 1
Thema 3: Die Macht der Befehlszeile
3.1 Dateien mithilfe der Befehlszeile archivieren
  • 3.1 Lektion 1
3.2 Daten in Dateien suchen und extrahieren
  • 3.2 Lektion 1
  • 3.2 Lektion 2
3.3 Von Befehlen zum Skript
  • 3.3 Lektion 1
  • 3.3 Lektion 2
Thema 4: Das Linux-Betriebssystem
4.1 Ein Betriebssystem auswählen
  • 4.1 Lektion 1
4.2 Verständnis von Computer-Hardware
  • 4.2 Lektion 1
4.3 Wo Daten gespeichert werden
  • 4.3 Lektion 1
  • 4.3 Lektion 2
4.4 Der Rechner im Netzwerk
  • 4.4 Lektion 1
Thema 5: Sicherheit und Dateiberechtigungen
5.1 Sicherheitsgrundlagen und Identifizierung von Benutzertypen
  • 5.1 Lektion 1
5.2 Benutzer und Gruppen anlegen
  • 5.2 Lektion 1
5.3 Dateiberechtigungen und Dateieigentum verwalten
  • 5.3 Lektion 1
5.4 Besondere Verzeichnisse und Dateien
  • 5.4 Lektion 1
How to get certified
  1. Thema 3: Die Macht der Befehlszeile
  2. 3.3 Von Befehlen zum Skript
  3. 3.3 Lektion 2

3.3 Lektion 2

Zertifikat:

Linux Essentials

Version:

1.6

Thema:

3 Die Macht der Befehlszeile

Lernziel:

3.3 Von Befehlen zum Skript

Lektion:

2 von 2

Einführung

Im letzten Abschnitt haben wir dieses einfache Beispiel verwendet, um das Bash-Skripting zu demonstrieren:

#!/bin/bash

# A simple script to greet a single user.

if [ $# -eq 1 ]
then
  username=$1

  echo "Hello $username!"
else
  echo "Please enter only one argument."
fi
echo "Number of arguments: $#."
  • Alle Skripte sollten mit einem Shebang beginnen, der den Pfad zum Interpreter definiert.

  • Alle Skripte sollten Kommentare enthalten, um ihre Verwendung zu beschreiben.

  • Dieses spezielle Skript arbeitet mit einem Argument, das beim Aufruf an das Skript übergeben wird.

  • Dieses Skript enthält eine if-Anweisung, die die Bedingungen einer eingebauten Variablen $# testet. Diese Variable wird auf die Anzahl der Argumente gesetzt.

  • Wenn die Anzahl der an das Skript übergebenen Argumente gleich 1 ist, dann wird der Wert des ersten Arguments an eine neue Variable namens username übergeben und das Skript gibt einen Gruß aus. Andernfalls erscheint eine Fehlermeldung.

  • Schließlich gibt das Skript die Anzahl der Argumente aus. Dies ist für die Fehlersuche nützlich.

Dies ist ein nützliches Beispiel, um einige weitere Funktionen von Bash-Skripting zu erklären.

Exit Codes

Sie werden feststellen, dass unser Skript zwei mögliche Zustände hat: Entweder es druckt "Hello <user>!" oder es gibt eine Fehlermeldung aus, was für viele unserer Kern-Utilities ganz normal ist. Denken Sie an cat, mit dem Sie zweifellos sehr vertraut werden.

Lassen Sie uns eine erfolgreiche Verwendung von cat mit einer Situation vergleichen, in der es fehlschlägt. Erinnern wir uns, dass unser obiges Beispiel ein Skript namens new_script.sh ist.

$ cat -n new_script.sh

     1	#!/bin/bash
     2
     3	# A simple script to greet a single user.
     4
     5	if [ $# -eq 1 ]
     6	then
     7	  username=$1
     8
     9	  echo "Hello $username!"
    10	else
    11	  echo "Please enter only one argument."
    12	fi
    13	echo "Number of arguments: $#."

Dieser Befehl ist erfolgreich, und Sie werden feststellen, dass das -n-Flag auch Zeilennummern gedruckt hat, die sehr hilfreich beim Debuggen von Skripten sind, aber bitte beachten Sie, dass sie nicht Teil des Skripts sind.

Jetzt werden wir den Wert einer neuen eingebauten Variablen $? überprüfen. Im Moment beachten Sie einfach die Ausgabe:

$ echo $?
0

Betrachten wir nun eine Situation, in der cat fehlschlägt. Zuerst erhalten wir eine Fehlermeldung und überprüfen dann den Wert von $?.

$ cat -n dummyfile.sh
cat: dummyfile.sh: No such file or directory
$ echo $?
1

Die Erklärung für dieses Verhalten ist folgende: Jede Ausführung des Dienstprogramms cat gibt einen Exit Code zurück. Ein Exit Code sagt uns, ob der Befehl erfolgreich war oder ein Fehler auftrat. Ein Exit Code von null zeigt an, dass der Befehl erfolgreich abgeschlossen wurde, was für fast jeden Linux-Befehl gilt, mit dem Sie arbeiten. Jeder andere Exit Code weist auf einen Fehler hin. Der Exit Code des letzten auszuführenden Befehls wird in der Variablen $? gespeichert.

Exit Codes werden normalerweise nicht von menschlichen Benutzern gesehen, aber sie sind sehr nützlich beim Schreiben von Skripten. Stellen Sie sich ein Skript vor, bei dem wir Dateien auf ein entferntes Netzlaufwerk kopieren. Es gibt viele Möglichkeiten, wie die Kopieraufgabe fehlgeschlagen sein kann: Unser lokaler Rechner ist nicht mit dem Netzwerk verbunden oder das Remote-Laufwerk ist voll. Indem wir den Exit Code unseres Kopierprogramms überprüfen, können wir den Benutzer auf Probleme beim Ausführen des Skripts aufmerksam machen.

Es ist gute Praxis, Exit Codes zu implementieren, also werden wir das jetzt tun. Wir haben zwei Pfade in unserem Skript: Erfolg und Misserfolg. Wir nutzen null, um Erfolg anzuzeigen, und eins für den Misserfolg.

     1	#!/bin/bash
     2
     3	# A simple script to greet a single user.
     4
     5	if [ $# -eq 1 ]
     6	then
     7	  username=$1
     8
     9	  echo "Hello $username!"
    10	  exit 0
    11	else
    12	  echo "Please enter only one argument."
    13	  exit 1
    14	fi
    15	echo "Number of arguments: $#."
$ ./new_script.sh Carol
Hello Carol!
$ echo $?
0

Beachten Sie, dass der Befehl echo in Zeile 15 vollständig ignoriert wurde und das Skript mit exit sofort beendet wird, so dass diese Zeile nie gefunden wird.

Behandlung mehrerer Argumente

Bisher kann unser Skript nur einen einzigen Benutzernamen auf einmal verarbeiten, eine beliebige Anzahl von Argumenten außer einem wirft einen Fehler. Wir wollen herausfinden, wie wir dieses Skript vielseitiger gestalten können.

Ein Benutzer könnte instinktiv dazu übergehen, mehr Positionsvariablen wie $2, $3 usw. zu verwenden. Leider können wir aber die Anzahl der Argumente, die ein Benutzer benötigt, nicht vorhersehen. Um dieses Problem zu lösen, ist es hilfreich, mehr eingebaute Variablen einzuführen.

Wir werden die Logik unseres Skripts ändern: Null Argumente sollen einen Fehler werfen, aber eine beliebige Anzahl von Argumenten sollte erfolgreich sein. Dieses neue Skript wird friendly2.sh heißen.

     1	#!/bin/bash
     2
     3	# a friendly script to greet users
     4
     5	if [ $# -eq 0 ]
     6	then
     7	  echo "Please enter at least one user to greet."
     8	  exit 1
     9	else
    10	  echo "Hello $@!"
    11	  exit 0
    12	fi
$ ./friendly2.sh Carol Dave Henry
Hello Carol Dave Henry!

Es gibt zwei eingebaute Variablen, die alle an das Skript übergebenen Argumente enthalten: $@ und $*. Meist verhalten sich beide gleich, Bash wird die Argumente parsen und jedes Argument trennen, wenn es auf ein Leerzeichen stößt. Der Inhalt von $@ sieht also so aus:

0

1

2

Carol

Dave

Henry

Wenn Sie mit anderen Programmiersprachen vertraut sind, erkennen Sie diese Art von Variable vielleicht als Array. Arrays sind in Bash einfach zu erstellen, indem Sie Leerzeichen zwischen Elementen wie der Variablen FILES im Skript arraytest unten setzen:

FILES="/usr/sbin/accept /usr/sbin/pwck /usr/sbin/chroot"

Es enthält eine Liste mit mehreren Elementen. Das ist bisher nicht sehr hilfreich, da wir noch keine Möglichkeit eingeführt haben, diese Elemente individuell zu behandeln.

For-Schleifen

Kommen wir noch einmal zu dem zuvor gezeigten Beispiel arraytest. Hier legen wir ein eigenes Array namens FILES an. Wir brauchen eine Methode, um diese Variable zu “entpacken” und nacheinander auf jeden einzelnen Wert zugreifen zu können. Dafür nutzem wir eine Struktur namens for-Schleife, die es in allen Programmiersprachen gibt. Es gibt zwei Variablen, auf die wir zugreifen werden: eine ist der Bereich, und die andere ist für den individuellen Wert, an dem wir gerade arbeiten. Dies ist das gesamt Skript:

#!/bin/bash

FILES="/usr/sbin/accept /usr/sbin/pwck /usr/sbin/chroot"

for file in $FILES
do
  ls -lh $file
done
$ ./arraytest
lrwxrwxrwx 1 root root 10 Apr 24 11:02 /usr/sbin/accept -> cupsaccept
-rwxr-xr-x 1 root root 54K Mar 22 14:32 /usr/sbin/pwck
-rwxr-xr-x 1 root root 43K Jan 14 07:17 /usr/sbin/chroot

Im obigen Beispiel friendly2.sh sehen Sie, dass wir mit einer Reihe von Werten arbeiten, die in einer einzigen Variablen $@ enthalten sind. Der Übersichtlichkeit halber nennen wir die letztgenannte Variable username:

     1	#!/bin/bash
     2
     3	# a friendly script to greet users
     4
     5	if [ $# -eq 0 ]
     6	then
     7	  echo "Please enter at least one user to greet."
     8	  exit 1
     9	else
    10	  for username in $@
    11	  do
    12	    echo "Hello $username!"
    13	  done
    14	  exit 0
    15	fi

Denken Sie daran, dass die Variable, die Sie hier definieren, beliebig benannt werden kann und dass alle Zeilen in do…​ done einmal für jedes Element des Arrays ausgeführt werden. Betrachten wir die Ausgabe unseres Skripts:

$ ./friendly2.sh Carol Dave Henry
Hello Carol!
Hello Dave!
Hello Henry!

Nehmen wir nun an, wir wollen unseren Output etwas menschlicher gestalten, indem wir unseren Gruß in eine Zeile setzen.

     1	#!/bin/bash
     2
     3	# a friendly script to greet users
     4
     5	if [ $# -eq 0 ]
     6	then
     7	  echo "Please enter at least one user to greet."
     8	  exit 1
     9	else
    10	  echo -n "Hello $1"
    11	  shift
    12	  for username in $@
    13	  do
    14	    echo -n ", and $username"
    15	  done
    16	  echo "!"
    17	  exit 0
    18	fi

Einige Anmerkungen:

  • Die Verwendung von -n mit echo unterdrückt den Zeilenumbruch nach der Ausgabe, d.h. alle Ausgaben werden auf dieselbe Zeile gedruckt, und der Zeilenumbruch folgt erst nach dem ! in Zeile 16.

  • Der Befehl shift entfernt das erste Element unseres Arrays. So wird aus:

0

1

2

Carol

Dave

Henry

das Folgende:

0

1

Dave

Henry

Betrachten wir die Ausgabe:

$ ./friendly2.sh Carol
Hello Carol!
$ ./friendly2.sh Carol Dave Henry
Hello Carol, and Dave, and Henry!

Reguläre Ausdrücke bei der Fehlerprüfung

Nehmen wir an, wir wollen alle Argumente, die der Benutzer eingibt, überprüfen, z.B. dass alle an friendly2.sh übergebenen Namen nur Buchstaben enthalten und alle Sonderzeichen oder Zahlen einen Fehler werfen. Für eine solche Fehlerprüfung nutzen wir grep.

Erinnern Sie sich daran, dass wir reguläre Ausdrücke mit grep verwenden können.

$ echo Animal | grep "^[A-Za-z]*$"
Animal
$ echo $?
0
$ echo 4n1ml | grep "^[A-Za-z]*$"
$ echo $?
1

Das ^ und das $ kennzeichnen den Anfang und das Ende der Zeile, das [A-Za-z] kennzeichnet einen Bereich von Buchstaben, Groß- oder Kleinschreibung. Das * ist ein Quantisierer und modifiziert unseren Buchstabenbereich von null bis zu (beliebig) vielen Buchstaben. Zusammenfassend lässt sich sagen, dass unser grep erfolgreich ist, wenn die Eingabe ausschließlich Buchstaben umfasst — andernfalls schlägt es fehl.

Im nächsten Schritt müssen wir dafür sorgen, dass grep Exit Codes zurückgibt, abhängig davon, ob es eine Übereinstimmung gab oder nicht. Eine positive Übereinstimmung gibt 0 zurück, andernfalls wird der Wert 1 zurückgegeben. Wir können dies verwenden, um die Argumente in unserem Skript zu testen.

     1	#!/bin/bash
     2
     3	# a friendly script to greet users
     4
     5	if [ $# -eq 0 ]
     6	then
     7	  echo "Please enter at least one user to greet."
     8	  exit 1
     9	else
    10	  for username in $@
    11	  do
    12	    echo $username | grep "^[A-Za-z]*$" > /dev/null
    13	    if [ $? -eq 1 ]
    14	    then
    15	      echo "ERROR: Names must only contains letters."
    16	      exit 2
    17	    else
    18	      echo "Hello $username!"
    19	    fi
    20	  done
    21	  exit 0
    22	fi

In Zeile 12 leiten wir die Standardausgabe an /dev/null um, was eine einfache Möglichkeit ist, sie zu unterdrücken, denn wir wollen keine Ausgabe des Befehls grep sehen, sondern nur seinen Exit Code testen, was in Zeile 13 geschieht. Beachten Sie auch, dass wir einen Exit Code 2 verwenden, um ein ungültiges Argument anzuzeigen. Es ist gute Praxis, verschiedene Exit Codes zu verwenden, um verschiedene Fehler anzuzeigen; so kann ein erfahrener Benutzer diese Exit Codes zur Fehlersuche nutzen.

$ ./friendly2.sh Carol Dave Henry
Hello Carol!
Hello Dave!
Hello Henry!
$ ./friendly2.sh 42 Carol Dave Henry
ERROR: Names must only contains letters.
$ echo $?
2

Geführte Übungen

  1. Lesen Sie das folgende script1.sh:

    #!/bin/bash
    
    if [ $# -lt 1 ]
    then
      echo "This script requires at least 1 argument."
      exit 1
    fi
    
    echo $1 | grep "^[A-Z]*$" > /dev/null
    if [ $? -ne 0 ]
    then
      echo "no cake for you!"
      exit 2
    fi
    
    echo "here's your cake!"
    exit 0

    Wie lautet die Ausgabe der folgenden Befehle?

    • ./script1.sh

    • echo $?

    • ./script1.sh cake

    • echo $?

    • ./script1.sh CAKE

    • echo $?

  2. Lesen Sie das folgende Skript script2.sh:

    for filename in $1/*.txt
    do
       cp $filename $filename.bak
    done

    Beschreiben Sie den Zweck des Skripts so, wie Sie es verstehen.

Offene Übungen

  1. Erstellen Sie ein Skript, das beliebig viele Argumente vom Benutzer entgegennimmt, und drucken Sie nur solche Argumente, die Zahlen größer als 10 sind.

Zusammenfassung

In diesem Abschnitt haben Sie gelernt:

  • Was Exit Codes sind, was sie bedeuten und wie man sie implementiert.

  • Wie man den Exit Code eines Befehls überprüft.

  • Was for-Schleifen sind, und wie man sie mit Arrays verwendet.

  • Wie man grep, reguläre Ausdrücke und Exit Codes verwendet, um Benutzereingaben in Skripten zu überprüfen.

Befehle, die in den Übungen verwendet werden:

shift

Entfernt das erste Element eines Arrays.

Spezielle Variablen:

$?

Enthält den Exit Code des zuletzt ausgeführten Befehls.

$@, $*

Enthält alle Argumente, die an das Skript übergeben werden, als Array.

Lösungen zu den geführten Übungen

  1. Lesen Sie das folgende script1.sh:

    #!/bin/bash
    
    if [ $# -lt 1 ]
    then
      echo "This script requires at least 1 argument."
      exit 1
    fi
    
    echo $1 | grep "^[A-Z]*$" > /dev/null
    if [ $? -ne 0 ]
    then
      echo "no cake for you!"
      exit 2
    fi
    
    echo "here's your cake!"
    exit 0

    Wie lautet die Ausgabe der folgenden Befehle?

    • Befehl: ./script1.sh

      Ausgabe: This script requires at least 1 argument.

    • Befehl: echo $?

      Ausgabe: 1

    • Befehl: ./script1.sh cake

      Ausgabe: no cake for you!

    • Befehl: echo $?

      Ausgabe: 2

    • Befehl: ./script1.sh CAKE

      Ausgabe: here’s your cake!

    • Befehl: echo $?

      Ausgabe: 0

  2. Lesen Sie das folgende Skript script2.sh:

    for filename in $1/*.txt
    do
       cp $filename $filename.bak
    done

    Beschreiben Sie den Zweck des Skripts so, wie Sie es verstehen.

    Dieses Skript erstellt Sicherungskopien aller Dateien, die mit .txt enden, in einem Unterverzeichnis, das im ersten Argument definiert ist.

Lösungen zu den offenen Übungen

  1. Erstellen Sie ein Skript, das beliebig viele Argumente vom Benutzer entgegennimmt, und drucken Sie nur solche Argumente, die Zahlen größer als 10 sind.

    #!/bin/bash
    
    for i in $@
    do
      echo $i | grep "^[0-9]*$" > /dev/null
      if [ $? -eq 0 ]
      then
        if [ $i -gt 10 ]
        then
          echo -n "$i "
        fi
      fi
    done
    echo ""

Linux Professional Insitute Inc. Alle Rechte vorbehalten. Besuchen Sie die LPI Learning Website: https://learning.lpi.org
Dieses Werk steht unter der Lizenz Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.

Nächste Lektion

4.1 Ein Betriebssystem auswählen (4.1 Lektion 1)

Nächste Lektion lesen

Linux Professional Insitute Inc. Alle Rechte vorbehalten. Besuchen Sie die LPI Learning Website: https://learning.lpi.org
Dieses Werk steht unter der Lizenz Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.

LPI ist eine Non-Profit-Organisation.

© 2022 Linux Professional Institute (LPI) ist eine globale Organisation für Zertifizierungsstandards und zur Karriereplanung für Open-Source-Profis. Mit mehr als 200.000 Zertifikatsinhabern ist es die weltweit erste und größte herstellerneutrale Linux- und Open-Source-Zertifizierungsstelle. LPI verfügt über zertifizierte Fachleute in über 180 Ländern, bietet Prüfungen in mehreren Sprachen an und hat Hunderte von Trainingspartnern.

Unser Ziel ist es, wirtschaftliche und kreative Möglichkeiten für alle zu ermöglichen, indem wir Open-Source-Wissens- und Kompetenzzertifizierungen allgemein zugänglich machen.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Kontaktieren Sie uns
  • Datenschutz und Cookie-Richtlinien

Haben Sie einen Fehler entdeckt oder möchten Sie helfen, diese Seite zu verbessern? Lassen Sie es uns wissen.

© 1999–2022 The Linux Professional Institute Inc. Alle Rechte vorbehalten.