Eine einfache Anleitung zur Linux-Shell-Skripterstellung mit Bash

Haben Sie sich schon einmal gewünscht, mehr über das Linux-Shell-Skripting zu erfahren, aber wussten nicht, wo Sie anfangen sollen? Sind Sie relativ neu in der Welt der auf Unix-basierten Betriebssystemen und möchten Ihre Fähigkeiten erweitern, um einige grundlegende Shell-Programmierung durchzuführen? Dieses Tutorial für Anfänger wird die Grundlagen des Linux-Shell-Skriptings mit Bash behandeln, einschließlich Erstellung und Ausführung eines Skripts sowie Arbeit mit Zeichenketten und Schleifen.

Shell-Skripting wird verwendet, um häufige Verwaltungsaufgaben zu automatisieren

Unabhängig vom Betriebssystem werden Shell-Skripte verwendet, um wiederholte Verwaltungsaufgaben zu automatisieren. Zum Beispiel können Sie in Windows Dateien mit dem Datei-Explorer umbenennen. Aber wenn Sie viele Dateien umbenennen müssen, wäre es eine zeitaufwändige Aufgabe, die grafische Shell zu benutzen. PowerShell ermöglicht es Ihnen, die Aufgabe zu automatisieren und zuverlässig zu wiederholen.

Werbeanzeige

In Linux-basierten Betriebssystemen werden Bash und andere Shells verwendet, um Aufgaben wie die Arbeit mit Dateien, die Änderung von Systemkonfigurationen und viele andere Aufgaben zu automatisieren, die ansonsten durch Eingabe einzelner Befehle durchgeführt werden könnten.

Was Sie benötigen, um Bash-Shell-Skripting zu lernen

Um ein Bash-Skript zu schreiben und auszuführen, benötigen Sie nur drei Dinge:

  • Jeder einfache Text-Editor, wie Notepad, Text Editor, TextEdit, vi, emacs oder Visual Studio Code, tut es.
  • terminal emulator, an application that comes preinstalled with most operating systems and is often called Terminal, Console, or Command Prompt.
  • Bash selbst kann auch verwendet werden.

Der Terminalemulator ist der Ort, an dem Sie Befehle eingeben und durch Drücken von Enter oder Return ausführen. Ob Bash bereits installiert ist, hängt von Ihrem Betriebssystem ab:

  • Mac OS X kommt mit einer vorinstallierten Bash. In jüngeren Versionen ist die Z Shell (zsh) die Standard-Shell, was in Ordnung ist, solange Bash installiert ist, da zsh auch Bash-Skripte ausführen kann.
  • Linux-Distributionen haben in der Regel Bash installiert (überprüfen Sie, ob die Datei /bin/bash auf Ihrem System vorhanden ist). Android wird ohne Bash ausgeliefert. Es gibt zwar Möglichkeiten, Bash auf Android zu installieren, darauf werde ich hier aber nicht eingehen.
  • Windows wird nicht mit Bash mitgeliefert. PowerShell ist die standardmäßige Befehlszeilenshell in Windows. Sie müssen eine Linux-Distribution unter dem Windows-Subsystem für Linux (WSL) installieren, um Bash ausführen zu können.

Um Ihre Bash-Version zu finden, führen Sie den Befehl bash –version aus. Auch wenn ältere Bash-Versionen bereits viele Funktionen bieten, bieten Bash 3 und 4 beide praktische Kurzschreibweisen für bestimmte grundlegende Befehle. Wenn ein Befehl eine dieser Bash-Versionen erfordert, wird dies unten erwähnt.

Werbeanzeige

Was ist eine Shell?

In der Computerwelt ist eine Shell ein Programm, das als Schnittstelle für das zugrunde liegende Betriebssystem dient. Eine Shell kann eine grafische Benutzeroberfläche (GUI) sein, ähnlich der Windows-Shell.

Shell-Skriptsprachen

Allerdings verwenden die Leute im Allgemeinen den Begriff spezifisch für eine Befehlszeilenschnittstelle (CLI) – eine Schnittstelle, die aus Textzeilen besteht, mit der Sie nur über die Tastatur interagieren. Hier sind einige Beispiele für Shell-Skriptsprachen für *nix-Betriebssysteme:

  • die Bash-Shell (Abkürzung für „Bourne Again Shell“)
  • die C-Shell
  • die Korn-Shell

Hier werden wir uns auf die Bash-Shell konzentrieren. Es ist eine beliebte kostenlose Unix-Shell, die auf den meisten Linux-Distributionen und auf macOS vorinstalliert ist.

Was ist ein Shell-Skript?

Shells haben ihre eigene Programmiersprache. Mit dieser Sprache senden Sie Befehle an die Shell, die sie dann ausführt. Sie können diese Befehle direkt in die Shell eingeben oder sie in einer Datei — einem Skript — speichern und dann diese Datei aus der Shell heraus ausführen. Die Syntax zum Schreiben von Befehlen ist in beiden Fällen die gleiche.

Werbung

In diesem Artikel werden die Grundlagen des Shell-Skriptings behandelt, um diese Datei zu erstellen.

Grundlegendes Shell-Skripting

Beginnen wir mit einigen grundlegenden Shell-Skripten. Um ein einfaches Skript zu schreiben, lernen wir einige einfache Shell-Skript-Befehle in Linux:

  1. Erstellen Sie eine neue leere Textdatei in einem Texteditor.
  2. Schreiben Sie #!/bin/bash als erste Zeile.
  3. Geben Sie darunter Ihre Befehle ein.
  4. Speichern Sie die Datei, idealerweise mit der Erweiterung „.sh“ oder ganz ohne Erweiterung.

Die Zeile #!/bin/bash wird als “ shebang“ bezeichnet. Sie gibt Ihrem Shell an, dass dieses Skript in Bash ausgeführt werden soll und sollte die erste Zeile in Ihrem Skript sein. Wenn Sie zu einer anderen Shell wechseln, wird Ihr Skript dennoch in Bash ausgeführt.

Um diesen Prozess selbst auszuprobieren, erstellen Sie eine Datei namens ‘hello_world’ in Ihrem Home-Verzeichnis:

#!/bin/bash
echo "hello world"

Das war’s – Sie haben ein Bash-Skript erstellt!

Our “hello world” script is just a simple text file

Bevor Sie es ausführen können, müssen Sie wahrscheinlich die Berechtigungen für die Datei ändern.

Berechtigungen für die Ausführung eines Shell-Skripts mit chmod setzen

Um die Berechtigungen für unsere ‚hello_world‘-Datei zu ändern, würden Sie diesen spezifischen Befehl in Ihrem Terminal-Emulator ausführen. Dies gibt dem Benutzer, der die Datei besitzt, die Berechtigung, die Datei auszuführen.:

chmod u+x 'hello_world'
Running our script without vs. with the “execute” permission

Wenn Sie Ihr Shell-Skript nur ausführen möchten, können Sie zum nächsten Abschnitt springen. Für diejenigen, die neugierig auf den chmod-Befehl sind, steht chmod für „Änderung Modus“ und dient dazu, Dateiberechtigungen in Unix zu ändern. In Unix-ähnlichen Betriebssystemen können Dateiberechtigungen für 3 Benutzerklassen festgelegt werden:

  • Der Benutzer, dem die Datei gehört (dargestellt durch u in chmod).
  • Die Gruppe, der die Datei gehört (g).
  • Andere (o).

Mit dem chmod-Befehl können Sie auch a verwenden, um sich auf alle zu beziehen.

Jede Datei hat 3 Arten von Berechtigungen (oder „Modi“):

  • Lesen (r)
  • Schreiben (w)
  • Ausführen (x)

Sie können auch Berechtigungen hinzufügen (+) oder entfernen (-).

Der erste Parameter in chmod ist eine Kombination dieser drei – zuerst Benutzer, dann Aktion und zuletzt Modus. Hier sind ein paar Befehlsbeispiele:

  • chmod gu+rw 'hello_world' würde Lese- und Schreibberechtigungen für den Besitzer und die besitzende Gruppe hinzufügen.
  • chmod a-x 'hello_world' würde die Ausführungsberechtigungen für alle entfernen.
  • chmod u+rwx 'hello_world' 'hello_world_2' würde dem Besitzer die Berechtigung geben, die Dateien „hello_world“ und „hello_world_2“ zu lesen, zu schreiben und auszuführen.

Wir haben hier nur die Grundlagen des Befehls chmod abgedeckt. Es gibt auch eine kompliziertere, aber weniger ausführliche Möglichkeit, diese Modi zu definieren (die „numerische Notation“), sowie einen anderen Befehl, den Sie verwenden können, um die Berechtigungen Ihrer Dateien anzuzeigen (ls -l). Darauf werden wir hier nicht eingehen.

Ausführen eines Shell-Skripts

Es ist Zeit, unser erstes Skript auszuführen. Im Allgemeinen geben Sie einfach den Pfad des Skripts in den Terminal-Emulator ein und drücken die Eingabetaste.

./hello_world

Sie können den relativen oder den absoluten Pfad verwenden. Wenn Sie den relativen Pfad verwenden, verwenden Sie immer ./ am Anfang Ihres Befehls: Dadurch wird der Terminal angewiesen, im aktuellen Ordner (dargestellt durch '.') zu suchen, anstatt in den in der Umgebungsvariable PATH definierten Verzeichnissen.

Just typing the script name doesn’t work, but running its relative or absolute paths does

Kommentare zur Anmerkung Ihres Skripts verwenden

Alles nach einem # in einer Zeile in einem Bash-Skript wird als Kommentar betrachtet. Diese können hilfreich sein, um zu erklären, was eine komplexe Zeile macht oder eine Übersicht darüber zu geben, was größere Teile Ihres Skripts tun.

Zum Beispiel:

#!/bin/bash

#
# This shell script prints "hello world".
#

echo "hello world" # This line prints "hello world".

Eine Einführung in Variablen

Beim Schreiben von Skripten kann es nützlich sein, Variablen zu definieren. In Bash geschieht dies, indem Sie den Variablennamen und den Wert durch ein Gleichheitszeichen getrennt eingeben: VARIABLENAME='WERT'.

Sie sollten keine Leerzeichen neben dem Gleichheitszeichen setzen – Bash würde denken, dass Sie einen Prozess ausführen möchten.

Verwenden Sie einfache Anführungszeichen, um den Wert zu umschließen und zu verhindern, dass Bash ihn als etwas anderes interpretiert. In Bash haben Variablen keine Typen – alles ist im Grunde ein String. Es liegt an Bash-Programmen, den String als einen anderen Typ, wie etwa eine Zahl, zu interpretieren.

Um auf den Wert einer Variablen zu verweisen, verwenden Sie den Variablennamen, der vom Dollarzeichen gefolgt wird: $VARIABLENAME.

Um dies in der Praxis auszuprobieren, können Sie Ihr Skript wie folgt ändern:

#!/bin/bash
HELLO="hello variable world"
echo $HELLO # should print "hello variable world"

Argumente empfangen

Die einzelnen Wörter, die Sie beim Eingeben eines Befehls schreiben, werden als Argumente bezeichnet. In unserem Beispiel chmod u+x 'hello_world', sind chmod, u+x und 'hello_world' drei verschiedene Argumente. chmod ist der Befehlsname, während u+x und hello_world als Parameter bezeichnet werden – Argumente, die zusätzliche Informationen für den Befehl bereitstellen.

In Ihrem Skript können Sie auf diese Argumente über Variablen zugreifen. Um Konflikte mit lokalen Variablen zu vermeiden, werden diese Variablen mit Zahlen benannt – $0 bezieht sich auf den Befehlsnamen, $1 ist das nächste folgende Argument, $2 das darauf folgende, und so weiter.

Lassen Sie uns das ausprobieren:

#!/bin/bash
HELLO="hello $1 world"
echo $HELLO

Jetzt führen Sie dieses Skript mit diesen Parametern aus:

./hello_world bash script

Die Ausgabe sollte hello bash world sein, wobei der erste Parameter verwendet und der zweite ignoriert wird.

Wenn Sie möchten, dass bash script als ein Parameter angesehen wird, müssen Sie es in Anführungszeichen setzen: 

./hello_world 'bash script'
Words separated by a space are considered as several arguments, except when in quotes

Verwenden des if-Statements zum bedingten Ausführen von Code

Eines der Hauptanliegen von Programmierern in einem Skript ist es, einen Code nur auszuführen, wenn eine bestimmte Bedingung erfüllt ist. Bash hat dafür das if-Statement:

NUM=$RANDOM
if (( $NUM % 2 )) # if CONDITION
then
    echo "$NUM is odd"
fi # this is how you end an if statement

Hinweis: Von hier an wird angenommen, dass diese Beispiele Teil eines größeren Skripts sind und das #!/bin/bash am Anfang weggelassen wird. Vergiss es dennoch nicht als erste Zeile in deinem Skript!

Sie können auch else innerhalb eines if-Statements verwenden, um anzugeben, was zu tun ist, wenn eine Bedingung nicht erfüllt ist, oder ein elif (aus dem Englischen für „else if“)-Statement, um eine weitere Bedingung anzugeben, wenn die erste Bedingung nicht erfüllt war:

NUM=$RANDOM
if [ $NUM -eq 12 ]
then
    echo "$NUM is my favorite number"
elif (( $NUM % 2 ))
then
    echo "$NUM is odd"
else
    echo "$NUM is even"fi

fi‘ wird verwendet, um das if-Statement zu beenden.

Tipp: Wenn Sie nicht sicher sind, wie Sie die Bedingung selbst schreiben sollen, sehen Sie sich die test-, eckigen Klammern ([])- und doppelten Klammern ((()))-Notationen an.

The output of our script depends on the value of a random variable

Das Wiederholen einer Reihe von Befehlen mit einer for-Schleife

Jetzt, da wir behandelt haben, wie man Code bedingt ausführt, schauen wir uns an, wie man Code eine bestimmte Anzahl von Malen ausführt, solange eine Bedingung erfüllt ist.

Die for-Schleife leistet hier gute Dienste – insbesondere ihre „Drei-Ausdruck-Syntax“. Die Idee dahinter ist, eine schleifenspezifische Variable zuzuweisen und sie allmählich zu ändern, bis eine bestimmte Bedingung erfüllt ist. So ist sie strukturiert:

for (( ASSIGNMENT_EXPRESSION ; CONDITION_EXPRESSION ; UPDATE_EXPRESSION ))
do
    COMMANDS
done

Zum Beispiel, wenn Sie möchten, dass eine Schleife 10 Mal ausgeführt wird, wobei die Werte für i von 0 bis 9 reichen, könnte Ihre for-Schleife so aussehen:

for (( i=0; i<10; i++ ))
do
    echo $i
done

Lassen Sie uns das aufschlüsseln:

  • i=0 is the assignment expression here. It’s run only once before the loop is executed, which is why it’s useful for initializing a variable.
  • i<10 is our condition expression. This expression is evaluated before each iteration of a loop. If it is equal to zero (which means the same as “true” in Bash), the next iteration is not run.
  • i++ is our update expression. It’s run after each iteration of a loop.
The structure of our for loop

Durchlaufen von Elementen in einer Liste

Neben der Dreiausdruck-Syntax können Sie auch das in -Schlüsselwort verwenden, um eine for-Schleife zu definieren. Diese alternative Syntax wird verwendet, um durch eine Reihe von Elementen zu iterieren.

Das einfachste Beispiel ist einfach die Liste der Elemente, die Sie durchlaufen möchten, nach dem in-Schlüsselwort aufzulisten, getrennt durch Leerzeichen. Zum Beispiel:

for i in 0 1 2 3 4 5 6 7 8 9 # space-separated list items
do
    echo $i
done

Sie können auch durch Elemente iterieren, die von einem Befehl ausgegeben werden:

for i in $(seq 0 1 9)

Die $()-Notation wird im Allgemeinen für die Befehlssubstitution verwendet – sie führt einen Befehl aus und dessen Ausgabe wird als Eingabe für den umgebenden übergeordneten Befehl verwendet.

Wenn Sie durch Ganzzahlen iterieren, ist es besser, die integrierte Bereichssyntax in Bash zu verwenden, die effizienter ist als der seq-Befehl. Diese Syntax ist jedoch nur in neueren Bash-Versionen verfügbar:

  • for i in {0..9}, verfügbar in Bash 3.
  • for i in {0..9..1}, verfügbar in Bash 4, wobei die letzte Zahl die Inkrementierung darstellt.

In ähnlicher Weise können Sie auch durch Zeichenfolgen iterieren:

for s in 'item1' 'item2' 'item3'

Verwendung von Globbing zum Abrufen von Dateien, die zu einem Muster passen

Einer der häufigsten Anwendungsfälle für die Schleifen, die im vorherigen Abschnitt besprochen wurden, ist die Iteration durch einzelne Dateien.

Um dies zu bewältigen, müssen wir zuerst die sogenannten/*glob expansions*/* behandeln. Dies ist eine Funktion in Bash, die es Ihnen ermöglicht, Dateinamen mit Musterabgleich anzugeben. Es gibt spezielle Zeichen namens Platzhalter, die Sie verwenden, um diese Muster zu definieren.

Bevor wir hier tiefer einsteigen, schauen wir uns ein paar spezifische Beispiele an:

  • echo *: Ein Befehl, der die Namen aller Dateien in Ihrem aktuellen Verzeichnis zurückgibt, außer den versteckten.
  • echo *.txt: Ein Befehl, der die Namen aller nicht versteckten Dateien mit einer .txt-Erweiterung in Ihrem aktuellen Verzeichnis zurückgibt.
  • echo ????: Ein Befehl, der alle Dateinamen mit vier Buchstaben in Ihrem aktuellen Verzeichnis zurückgibt.

Die hier verwendeten Platzhalter waren * und ?. Es gibt auch noch einen weiteren Platzhalter, den wir nicht verwendet haben. Hier ist ein Überblick:

  • Der Asterisk (*) repräsentiert eine beliebige Anzahl von Zeichen (einschließlich 0) in einem Datei- oder Verzeichnisnamen.
  • Das Fragezeichen (?) repräsentiert ein einzelnes Zeichen in einem Datei- oder Verzeichnisnamen.
  • Der doppelte Asterisk (**) repräsentiert eine beliebige Anzahl von Zeichen in einem vollen Dateipfad. Es ist eine Funktion in Bash 4 und höher und muss durch Ausführen von shopt -s globstar aktiviert werden.
  • Eckige Klammern ([]) werden verwendet, um ein Zeichen innerhalb einer Menge von Symbolen in einem Datei- oder Verzeichnisnamen darzustellen. Zum Beispiel würde [st]ake Dateien mit den Namen sake oder take finden, aber nicht stake.

Beachten Sie, dass alle versteckten Dateien (Dateien mit Namen, die mit einem Punkt . beginnen) bei der Verwendung der Globus-Erweiterung ignoriert werden.

Die eckige Klammer-Notation ermöglicht etwas mehr Komplexität, einschließlich:

  • Bereiche, die durch den ersten und den letzten Wert definiert sind — z. B. [1-8]
  • Eliminierung bestimmter Zeichen durch Verwendung von ! als erstes Zeichen innerhalb der Klammern — z. B. [!3]

Um eines dieser Sonderzeichen als normales Zeichen ohne Bedeutung zu behandeln, setzen Sie einfach einen Backslash davor — z. B. \?.

A few examples of globbing

Durchlaufen von Dateien mit einer for-Schleife

Jetzt, da wir die Grundlagen der Globus-Erweiterung behandelt haben, werfen wir einen Blick darauf, wie man sie verwendet, um Dateien zu durchlaufen.

Wir können die Globus-Operatoren einfach direkt in der for-Schleife verwenden. Hier ist ein einfaches Beispiel einer Schleife, die den Namen jeder Datei im aktuellen Verzeichnis ausgibt:

for f in *
do
    echo $f
done

Um die Namen jeder Datei im aktuellen Verzeichnis sowie in dessen Unterverzeichnissen auszugeben, überprüfen Sie, dass Sie Bash 4.0 oder höher ausführen, indem Sie bash --version ausführen, und dann können Sie den folgenden Befehl ausführen:

shopt -s globstar # enables using **
for f in **
do
    echo $f
done

Tipp: Wenn Sie eine ältere Version von Bash verwenden, können Sie Globbing mit einer for-Schleife dafür nicht verwenden. Ihre beste Vorgehensweise wäre der find-Befehl, aber darauf werden wir in diesem Artikel nicht eingehen.

Dies sind natürlich nur einige der einfachsten Schleifen, die du laufen lassen kannst, aber es gibt viel mehr, das du tun kannst. Zum Beispiel kannst du alle JPGs in einem Ordner umbenennen, um sie mit einer konsequenten fortlaufenden Dateinamen zu versehen. Du könntest folgenden Befehl laufen lassen:

i=1
for f in *.jpg
do
    mv -i -- "$f" "image_$i.jpg"
    let i=i+1
done
Checking the Bash version, then running our script

Schleife, während eine Bedingung wahr ist

Der for-Schleifentyp ist nicht der einzige, den wir in Bash verwenden können — wir haben auch while: Dieser Schleifentyp läuft solange eine bestimmte Bedingung wahr ist.

Die Syntax ähnelt der for-Schleifensyntax:

while CONDITION
do
    COMMANDS
done

Für ein praktisches Beispiel könnte dies so aussehen, wie du eine Datei Zeile für Zeile (ohne führende oder abschließende Leerzeichen) lesen kannst, bis du am Ende der Datei angelangst bist:

while read -r line
do
    echo "$line"
done < FILENAME # Replace FILENAME with the path to a text file you'd like to read
Using a while loop inside our script to have it print itself

Du kannst auch einen for-Schleifen mit einer while-Schleife ersetzen, z.B. um von 0 bis 9 zu iterieren:

i=0
while [ $i -lt 10 ]
do
    echo $i
    let i=i+1
done

Und du könntest auch theoretisch eine Schleife für immer laufen lassen. Hier ist ein Befehlsbeispiel:

while true
do
    echo "running forever"
done

Tipp: Um das Skript zu beenden, drücken Sie nur Strg+C.

Obwohl diese unendliche Schleife zunächst einmal vielleicht unbrauchbar erscheint, kann sie实际上是 recht nützlich sein, vor allem wenn sie mit dem break-Aussage kombiniert wird.

Aus einer Schleife herausbrechen

Die break-Anweisung wird verwendet, um aus einer Schleife herauszubrechen.

Dadurch kannst du eine unendliche Schleife laufen lassen und aus ihr herausbrechen, wenn irgendeine Abbruchbedingung auftritt.

Um ein einfaches Beispiel zu betrachten, kannst du unsere Schleife von 0 bis 9 mit einer unendlichen Schleife wie folgt replizieren:

i=0while true
do
    if [ $i -eq 10 ]
    then
        break
    fi
    echo $i
    let i=i+1
done

Wenn Sie mehrere verschachtelte while-Schleifen haben, können Sie eine Zahl nach der break-Anweisung hinzufügen, um anzugeben, aus welcher Schleifenebene Sie ausbrechen möchten: break 1 ist dasselbe wie break und beendet die am nächsten umgebende Schleife. break 2 wird aus der darüberliegenden Schleife ausbrechen usw.

Werfen wir einen kurzen Blick auf ein Beispiel, diesmal mit for-Schleifen, die durch jede vierbuchstabige Wortkombination iterieren, bis das Wort „bash“ erreicht ist:

for l4 in {a..z}
do
    for l3 in {a..z}
    do
        for l2 in {a..z}
        do
            for l1 in {a..z}
            do
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done

A related keyword that’s also worth a mention is continue, which skips to the next iteration of the loop. Just like break, it also takes an optional numeric argument that corresponds to the loop level.

Hier ist ein albernes Beispiel, bei dem wir alle Wörter mit „Es“ in unserer verkürzten Liste der vierbuchstabigen Wörter überspringen:

for l4 in {a..z}
do
    if [ $l4 = "e" ]
    then
        continue
    fi
    for l3 in {a..z}
    do
        if [ $l3 = "e" ]
        then
            continue
        fi
        for l2 in {a..z}
        do
            if [ $l2 = "e" ]
            then
                continue
            fi
            for l1 in {a..z}
            do
                if [ $l1 = "e" ]
                then
                    continue
                fi
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done

Wir könnten auch alle diese continue-Anweisungen auf der tiefsten Schleifenebene ausführen:

for l4 in {a..z}
do
    for l3 in {a..z}
    do
        for l2 in {a..z}
        do
            for l1 in {a..z}
            do
                if [ $l4 = "e" ]
                then
                    continue 4
                fi
                if [ $l3 = "e" ]
                then
                    continue 3
                fi
                if [ $l2 = "e" ]
                then
                    continue 2
                fi
                if [ $l1 = "e" ]
                then
                    continue
                fi
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done
Our script stops once it generates the word “bash”

So erhalten Sie Benutzereingaben in einem Shell-Skript

Manchmal möchten Sie, dass der Benutzer direkt mit Ihrem Skript interagiert, anstatt nur die anfänglichen Skriptargumente zu verwenden. Hier kommt der Befehl read ins Spiel.

Um Benutzereingaben zu erhalten und in eine Variable namens NAME zu speichern, verwenden Sie diesen Befehl:

read NAME 

Dies ist die einfachste Form des Befehls, der nur aus dem Befehlsnamen und der Variablen besteht, in die Sie die Eingabe speichern möchten.

Häufiger möchten Sie jedoch den Benutzer auffordern, damit dieser weiß, was eingegeben werden soll. Dies tun Sie mit dem Argument -p, nach dem Sie Ihre bevorzugte Benutzeranweisung schreiben.

Hier ist, wie Sie nach einem Namen fragen können und ihn der Variablen NAME zuweisen:

read -p "Your name: " NAME
echo "Your name is $NAME." # this line is here just to show that the name has been saved to the NAME variable
The script saves our input to a variable and then prints it

Drucken von Sonderzeichen in einem String

Es gibt eine Reihe von Zeichen in Bash, bei denen Sie vorsichtig sein müssen. Zum Beispiel Leerzeichen in Dateinamen, Anführungszeichen in Strings oder Backslashes fast überall.

Um Bash anzuweisen, ihre spezielle Bedeutung an bestimmten Stellen zu ignorieren, können Sie sie entweder „escapen“ oder in ein wörtliches Anführungszeichen einschließen.

Escapen“ eines Sonderzeichens bedeutet, Bash mitzuteilen, es als nur ein Zeichen ohne spezielle Bedeutung zu behandeln. Um dies zu tun, schreiben Sie einen Backslash vor diesem Zeichen.

Angenommen, wir haben eine Datei namens img \ 01 *DRAFT*. In Bash könnten wir darauf so verweisen:

img\ \\\ 01\ \*DRAFT\*

Hier ist eine unvollständige Liste von Sonderzeichen in Bash:

  • Leerzeichen: Leerzeichen, Tabulator, Leerzeile
  • Anführungszeichen: ”, “”
  • Klammern und Klammern: ( ), { }, [ ]
  • Rohre und Umleitungen: |, <, >
  • Platzhalter: *, ?
  • Verschiedenes: !, #, ;, =, &, ~, `
  • Das Escape-Zeichen selbst: \

Wenn Sie neu in Bash sind, könnte es jedoch mühsam sein, sich daran zu erinnern, welche Zeichen eine spezielle Bedeutung haben. Daher ist es in vielen Situationen möglicherweise einfacher, ein wörtliches Anführungszeichen zu verwenden: Umgeben Sie einfach den Text, der Sonderzeichen enthält, mit einfachen Anführungszeichen, und alle Sonderzeichen innerhalb dieser Anführungszeichen werden ignoriert.

Hier ist, wie das für unser Beispiel aussehen würde:

'img \ 01 *DRAFT*'

Was ist jedoch, wenn Sie ein Sonderzeichen verwenden möchten, aber die anderen escapen möchten? Sie könnten jedes zweite Zeichen mit einem Backslash escapen, aber Sie können sich auch die Mühe sparen und alles außer dem Sonderzeichen mit einfachen Anführungszeichen umgeben.

Zum Beispiel, nehmen wir an, Sie haben mehrere Dateien mit den Namen img \ 01 *v1 DRAFT*, img \ 01 *v2 DRAFT*, img \ 01 *ROUGH DRAFT*, usw., und Sie möchten eine Glob-Erweiterung verwenden, um all diese Dateinamen abzugleichen. Hier ist, was Sie schreiben könnten:

'img \ 01 *'*' DRAFT*'
This glob expansion finds all of our 3 oddly-named files

Wenn das, was Sie schreiben müssen, ein einfaches Anführungszeichen enthält — z.B. img \ 01 *’FINAL’* — können Sie eine ähnliche Strategie anwenden, indem Sie literale Zeichenfolgen und Escapes kombinieren:

'img \ 01 '\''FINAL'\'

Wie man Zeichenfolgen in Bash konkateniert

Angenommen, Sie haben zwei oder mehr Zeichenfolgenvariablen — zum Beispiel einen Vornamen und einen Nachnamen:

FIRST_NAME="Johnny"LAST_NAME="Appleseed"

Um diese Variablen in eine Zeichenfolge zu kombinieren, vielleicht mit einem benutzerdefinierten Trennzeichen, erstellen Sie einfach eine neue Zeichenfolge, die aus diesen beiden Variablen besteht:

NAME="$LAST_NAME"', '"$FIRST_NAME"

Sie können auch doppelte Anführungszeichen mit Inline-Variablen verwenden, indem Sie geschweifte Klammern verwenden, um Variablennamen vom umgebenden Text zu trennen:

NAME="${LAST_NAME}, ${FIRST_NAME}"

Bash ermöglicht auch die Verwendung des +=-Operators, um Text an eine Zeichenfolge anzuhängen, wie folgt:

NAME='Appleseed'NAME+=', 'NAME+='Johnny'
Examples of different ways of stringing together text

Ausführung von Befehlen innerhalb einer Zeichenfolge

Bash ermöglicht es Ihnen auch, die Ausgabe eines Befehls in einem String zu verwenden, auch bekannt als Befehlssubstitution. Umgeben Sie einfach Ihren Befehl mit $(). Zum Beispiel, um einen aktuellen Zeitstempel auszugeben, können Sie folgendes ausführen:

echo "Current timestamp: $(date)"
Using command substitution to print the current timestamp

Sie erinnern sich vielleicht auch an diese Syntax aus einem früheren Beispiel für eine Schleife mit for, als wir durch eine Sequenz von Ganzzahlen von 0 bis 9 iteriert haben:

for i in $(seq 0 1 9)
do
    echo $i
done

Der ersetzte Befehl wird in einer Unter-Shell ausgeführt. Das bedeutet, dass zum Beispiel Variablen, die während des Befehls erstellt werden, die Umgebung, in der Sie Ihr Skript ausführen, nicht beeinflussen.

Setzen und Rückgeben von Exit-Codes in einem Shellskript

Für ein komplexeres Skript ist es üblich, dass es einen exit Code zurückgibt — eine Zahl zwischen 0 und 255, die Personen mitteilt, ob das Skript erfolgreich ausgeführt wurde oder auf einen Fehler gestoßen ist.

Was die zu verwendenden Zahlen betrifft, gibt das offizielle Bash-Handbuch diese Spezifikationen an:

  • 0: Programm erfolgreich ausgeführt.
  • 2: Programm falsch verwendet (z.B. aufgrund ungültiger oder fehlender Argumente).
  • 1 und 3-124: Benutzerdefinierte Fehler.
  • 126: Befehl ist nicht ausführbar.
  • 127: Befehl wurde nicht gefunden.
  • 125 und 128-255: Fehlerzustände, die von der Shell verwendet werden. Wenn ein Prozess durch ein Signal N beendet wird, beträgt der Exit-Status 128 + N.

Wie du sehen kannst, deutet jede Zahl außer 0 auf eine Art von Fehler hin. Der Exit-Code 1 wird häufig für allgemeine Fehler verwendet. In den meisten Fällen musst du keinen Exit-Code über 2 verwenden.

Um einen Exit-Code aus deinem Skript zurückzugeben, verwende einfach das exit-Kommando. Zum Beispiel, um mit einem Code von 2 zu beenden, würdest du exit 2 schreiben.

Wenn du das exit-Kommando nicht in deinem Skript verwendest oder das Kommando ohne Angabe eines Codes verwendest, wird der Exit-Status des zuletzt ausgeführten Befehls in deinem Skript zurückgegeben.

Um den Exit-Code des zuletzt ausgeführten Befehls in deiner Shell zu erhalten, verwende die $?-Variable: echo $?.

Wie man eine Funktion aufruft

Wenn du ein längeres Skript oder eines mit sich wiederholenden Codeblöcken schreibst, möchtest du möglicherweise etwas Code in Funktionen auslagern. Es gibt zwei Formate, die du verwenden kannst, um Funktionen zu definieren: In beiden Fällen befindet sich der gesamte Funktionscode in geschweiften Klammern, und nur die Funktionsdeklaration unterscheidet sich.

Das kompaktere Format verwendet Klammern, die dem Funktionsnamen folgen, um eine Funktion zu deklarieren:

function_name () {
    echo "This is where your function code goes"
}

Das andere Format verwendet das function-Schlüsselwort vor einem Funktionsnamen:

function function_name {
    echo "This is where your function code goes"
}

Funktionen müssen deklariert werden, bevor sie in Ihrem Skript aufgerufen werden. Sie rufen eine Funktion genauso auf, wie Sie einen regulären Befehl ausführen, indem Sie den Funktionsnamen als Befehl verwenden:

function_name

Daten an eine Funktion mit Variablen übergeben

In Bash können Funktionen keine Argumente entgegennehmen. Um Informationen an eine Funktion zu senden, müssen Sie globale Variablen in Ihrem Skript verwenden.

Zum Beispiel:

is_your_name_defined () {
    if [ -z "$YOUR_NAME" ]
    then
        echo "It doesn't seem like I have your name."
    else
        echo "Is this your name: ${YOUR_NAME}?"
    fi
}
read -p "Your name: " YOUR_NAME

is_your_name_defined

Anders als in anderen Sprachen, sind die Variablen, die Sie innerhalb Ihrer Funktion definieren, global und für den Code außerhalb Ihres Skripts sichtbar. Um eine Variable nur lokal für Ihre Funktion zu definieren (was bedeutet, dass sie für jeden Code außerhalb unzugänglich ist), verwenden Sie das Schlüsselwort local: z.B. local i=0.

Wenn Sie Werte aus einer Funktion zurückgeben möchten, müssen Sie ebenfalls globale Variablen verwenden. In Bash können Funktionen nur Exit-Codes zurückgeben, indem sie das Schlüsselwort return verwenden. Schauen wir uns ein Beispiel an:

is_your_name_defined () {
    if [ -z "$YOUR_NAME" ]
    then
        MESSAGE="It doesn't seem like I have your name."
    else
        MESSAGE="Is this your name: ${YOUR_NAME}?"
    fi
}
read -p "Your name: " YOUR_NAME

is_your_name_defined

echo $MESSAGE
The output of our script depends on the values entered

Zusammenfassung

Das Bash-Skripting ermöglicht Ihnen eine Vielzahl von Möglichkeiten auf einem UNIX-basierten Betriebssystem. Dieser Artikel hat einige Grundlagen des Bash-Skriptings behandelt, darunter das Erstellen und Ausführen von Skripts, die Arbeit mit Zeichenketten und die Verwendung von Schleifen in Ihrem Code. Hoffentlich wird es ein guter Start für Ihre Reise beim Schreiben leistungsstarker Bash-Skripts sein, die Ihren Anforderungen entsprechen.

Es gibt noch viel mehr über Bash zu lernen, einschließlich einiger der nützlichsten Befehle, der Dateisystemnavigation und mehr. Lassen Sie uns in den Kommentaren wissen, über welche Themen wir als Nächstes berichten sollten.

Verwandter Artikel:

Source:
https://petri.com/shell-scripting-bash/