Alles, was Sie über Bash For Loops unter Linux wissen müssen

Bash-Skripte sind ein hocheffizientes Mittel zur Automatisierung von Aufgaben, insbesondere von Aufgaben, die andere vorhandene Programme nutzen. Diese Automatisierung erfordert häufig das mehrmalige Wiederholen eines ähnlichen Vorgangs. Genau hier setzt die for-Schleife an .

Linux- und Mac-Systemadministratoren sind normalerweise mit Skripten über das Terminal vertraut, aber auch Windows-Benutzer können mit dem Windows-Subsystem für Linux in die Aktion einsteigen .

So funktionieren Bash-Skripte

Ein Bash-Skript ist einfach eine reine Textdatei, die eine Reihe von Befehlen enthält, die die Bash-Shell lesen und ausführen kann. Bash ist die Standard-Shell in MacOS vor Catalina und den meisten Linux-Distributionen.

Wenn Sie noch nie mit einem Shell-Skript gearbeitet haben, sollten Sie mit dem absolut einfachsten Fall beginnen. Auf diese Weise können Sie Schlüsselkonzepte üben, einschließlich der Erstellung des Skripts und seiner Ausführung.

Erstellen Sie zunächst die folgende Datei an einem geeigneten Ort (im Idealfall öffnen Sie ein Terminal und navigieren Sie zuerst zum gewünschten Verzeichnis):

 #!/bin/bash
echo "Hello, World"

In der ersten Zeile erfahren Sie, wie dieses Programm ausgeführt wird (dh mit dem Bash-Interpreter). Der zweite ist nur ein Befehl wie jeder andere, den Sie in die Befehlszeile eingeben können. Speichern Sie diese Datei als hello_world.sh , dann:

 $ chmod +x hello_world.sh
$ ./hello_world.sh

Der Befehl chmod in der ersten Zeile macht die Datei ausführbar, was bedeutet, dass sie wie in der zweiten Zeile durch Eingabe ihres Namens ausgeführt werden kann.

Wenn die Wörter "Hallo, Welt" in einer Zeile in Ihrem Terminal angezeigt werden, funktioniert alles wie erforderlich.

So funktionieren For-Loops

In der allgemeinen Programmierung gibt es zwei Haupttypen von for-Schleifen: numerisch und foreach . Der numerische Typ ist traditionell der gebräuchlichste, aber bei der Verwendung von Bash ist er normalerweise umgekehrt.

Numerische for-Schleifen konzentrieren sich normalerweise auf eine einzelne Ganzzahl, die bestimmt, wie viele Iterationen ausgeführt werden, zum Beispiel:

 for (i = 0; i < 100; i++) {
/* statements to execute repeatedly */
}

Dies ist eine vertraute for-Schleife, die genau 100 Mal iteriert, es sei denn, i wird innerhalb der Schleife geändert oder eine andere Anweisung bewirkt, dass die Ausführung der for-Schleife angehalten wird.

Im Gegensatz dazu arbeiten Foreach-Schleifen in der Regel mit Strukturen wie Listen oder Arrays und iterieren für jedes Element in dieser Sammlung:

 people = [ "Peter", "Paul", "Mary" ]
foreach (people as person) {
if (person == "Paul") {
...
}
}

Einige Sprachen verwenden eine etwas andere Syntax, die die Reihenfolge von Sammlung und Artikel vertauscht:

 people = [ "Peter", "Paul", "Mary" ]
for (person in people) {
if (person == "Paul") {
...
}
}

Für in Schleifen

In Bash ist die foreach- oder for- Schleife häufiger. Die grundlegende Syntax lautet einfach:

 for arg in [list]
do
/* statements to execute repeatedly */
/* the value of arg can be obtained using $arg */
done

So durchlaufen Sie beispielsweise drei explizit benannte Dateien:

 for file in one.c two.c three.c
do
ls "$file"
done

Wenn solche Dateien im aktuellen Verzeichnis vorhanden sind, lautet die Ausgabe dieses Skripts:

 one.c
two.c
three.c

Anstelle eines festen Satzes von Dateien kann die Liste über ein Glob-Muster abgerufen werden (eines mit Platzhaltern – Sonderzeichen, die andere Zeichen darstellen). Im folgenden Beispiel durchläuft die for-Schleife alle Dateien (im aktuellen Verzeichnis), deren Namen mit ".xml" enden:

 for file in *.xml
do
ls -l "$file"
done

Hier einige Beispielausgaben:

 $ -rw-r--r-- 1 bobby staff 2436 3 Nov 2019 feed.xml
$ -rw-r--r-- 1 bobby staff 6447 27 Oct 16:24 sitemap.xml

Dies mag sehr nach einer langwierigen Vorgehensweise aussehen:

 $ ls -l *.xml

Es gibt jedoch einen signifikanten Unterschied: Die for-Schleife führt das ls- Programm zwei Mal separat aus, wobei jedes Mal ein einzelner Dateiname an das Programm übergeben wird. Im separaten ls-Beispiel stimmt das Glob-Muster (* .xml) zuerst mit den Dateinamen überein und sendet dann alle als einzelne Befehlszeilenparameter an eine Instanz von ls .

Hier ist ein Beispiel, das das Programm wc (Word Count) verwendet, um den Unterschied deutlicher zu machen:

 $ wc -l *.xml
44 feed.xml
231 sitemap.xml
275 total

Das wc- Programm zählt die Anzahl der Zeilen in jeder Datei separat und druckt dann eine Gesamtanzahl über alle Zeilen. Im Gegensatz dazu, wenn wc innerhalb einer for-Schleife arbeitet:

 for file in *.xml
do
wc -l $file
done

Sie sehen immer noch die Anzahl für jede Datei:

 44 feed.xml
231 sitemap.xml

Es gibt jedoch keine Gesamtübersicht, da wc bei jeder Iteration der Schleife isoliert ausgeführt wird.

Wenn eine Liste keine Liste ist

Es gibt einen sehr einfachen und häufigen Fehler beim Umgang mit for-Schleifen, da bash mit Argumenten / Zeichenfolgen in Anführungszeichen umgeht. Das Durchlaufen einer Liste von Dateien sollte folgendermaßen erfolgen:

 for file in one.c two.c

So nicht:

 for file in "one.c two.c"

Das zweite Beispiel enthält Dateinamen in doppelten Anführungszeichen, was zu einer Liste mit nur einem einzigen Parameter führt. Die for-Schleife wird nur einmal ausgeführt. Dieses Problem kann durch die Verwendung einer Variablen in folgenden Fällen vermieden werden:

 FILES="one.c two.c"
for file in $FILES
do
...
done

Beachten Sie, dass die Variablendeklaration selbst ihren Wert in doppelte Anführungszeichen setzen muss!

Für ohne Liste

Da nichts durchlaufen werden muss, verarbeitet eine for-Schleife alle Befehlszeilenargumente, die dem Skript beim Aufrufen zur Verfügung gestellt wurden. Wenn Sie beispielsweise ein Skript mit dem Namen args.sh haben , das Folgendes enthält:

 #!/bin/sh
for a
do
echo $a
done

Wenn Sie dann args.sh ausführen, erhalten Sie Folgendes:

 $ ./args.sh one two three
one
two
three

Bash erkennt diesen Fall und behandelt für ein Do das Äquivalent für ein in $ @ do, wobei $ @ eine spezielle Variable ist, die Befehlszeilenargumente darstellt.

Emulieren einer traditionellen numerischen For-Schleife

Bash-Skripte verarbeiten häufig Listen von Dateien oder Ausgabezeilen von anderen Befehlen, daher ist die Schleife vom Typ for in üblich. Die traditionelle Operation im C-Stil wird jedoch weiterhin unterstützt:

 for (( i=1; i<=5; i++ ))
do
echo $i
done

Dies ist die klassische Form mit drei Teilen, in denen:

  1. Eine Variable wird initialisiert (i = 1), wenn die Schleife zum ersten Mal angetroffen wird
  2. Die Schleife wird fortgesetzt, solange die Bedingung (i <= 5) erfüllt ist
  3. Jedes Mal um die Schleife wird die Variable inkrementiert (i ++)

Das Iterieren zwischen zwei Werten ist häufig genug, um eine kürzere, etwas weniger verwirrende Alternative zu finden:

 for i in {1..5}
do
echo $i
done

Die Klammererweiterung, die stattfindet, übersetzt die obige for-Schleife effektiv in:

 for i in 1 2 3 4

Feinere Schleifensteuerung mit Pause und Weiter

Komplexere Schleifen erfordern häufig eine Möglichkeit, die Hauptschleife vorzeitig zu beenden oder sofort mit dem nächsten Wert neu zu starten. Zu diesem Zweck leiht bash die in anderen Programmiersprachen üblichen break and continue-Anweisungen aus. In diesem Beispiel wird beides verwendet, um die erste Datei mit mehr als 100 Zeichen zu finden:

 #!/bin/bash
for file in *
do
if [ ! -f "$file" ]
then
echo "$file is not a file"
continue
fi
num_chars=$(wc -c < "$file")
echo $file is "$num_chars characters long"
if [ $num_chars -gt 100 ]
then
echo "Found $file"
break
fi
done

Die for-Schleife funktioniert hier für alle Dateien im aktuellen Verzeichnis. Wenn die Datei keine reguläre Datei ist (z. B. wenn es sich um ein Verzeichnis handelt), wird die continue-Anweisung verwendet, um die Schleife mit der nächsten Datei nacheinander neu zu starten. Wenn es sich um eine reguläre Datei handelt, bestimmt der zweite bedingte Block, ob er mehr als 100 Zeichen enthält. In diesem Fall wird die break-Anweisung verwendet, um die for-Schleife sofort zu verlassen (und das Ende des Skripts zu erreichen).

Fazit

Ein Bash-Skript ist eine Datei, die eine Reihe von Anweisungen enthält, die ausgeführt werden können. Mit einer for-Schleife kann ein Teil eines Skripts viele Male wiederholt werden. Mit der Verwendung von Variablen, externen Befehlen und den Anweisungen break und continue können Bash-Skripte komplexere Logik anwenden und eine Vielzahl von Aufgaben ausführen.