Jeder Systemadministrator hat wahrscheinlich eine Fähigkeit, die er im Laufe der Jahre gelernt hat, auf die er zeigen und sagen kann:"Das hat meine Welt verändert." Diese Fähigkeit oder diese Information oder diese Technik hat einfach verändert, wie ich Dinge mache. Für viele von uns ist das eine Schleife in Basch. Es gibt andere Ansätze zur Automatisierung, die sicherlich robuster oder skalierbarer sind. Die meisten von ihnen sind nicht vergleichbar mit der Einfachheit und leichten Verwendbarkeit von for
Schleife, obwohl.
Wenn Sie die Konfiguration von Tausenden von Systemen automatisieren möchten, sollten Sie wahrscheinlich Ansible verwenden. Wenn Sie jedoch versuchen, tausend Dateien umzubenennen oder denselben Befehl mehrmals auszuführen, wird der for
loop ist definitiv das richtige Werkzeug für diesen Job.
[Das könnte Ihnen auch gefallen: Loops mit Jinja-Vorlagen in Ansible meistern]
Wenn Sie bereits Programmier- oder Scripting-Hintergrund haben, sind Sie wahrscheinlich damit vertraut, was for
ist Schleifen tun. Wenn nicht, werde ich versuchen, es für Sie in einfachem Englisch aufzuschlüsseln.
Das Grundkonzept ist:FÜR eine bestimmte Menge von Gegenständen, TUN eine Sache.
Der angegebene Satz von Elementen kann ein wörtlicher Satz von Objekten sein oder irgendetwas, das Bash in eine Liste extrapolieren kann. Beispielsweise aus einer Datei abgerufener Text, die Ausgabe eines anderen Bash-Befehls oder über die Befehlszeile übergebene Parameter. Auch die Umwandlung dieser Schleifenstruktur in ein Bash-Skript ist trivial. In diesem Artikel zeigen wir Ihnen einige Beispiele dafür, wie ein for
Schleife kann Sie wie einen Befehlszeilenhelden aussehen lassen, und dann nehmen wir einige dieser Beispiele und fügen sie in ein strukturierteres Bash-Skript ein.
Grundstruktur der for-Schleife
Lassen Sie uns zunächst über die grundlegende Struktur eines for
sprechen -Schleife, und dann kommen wir zu einigen Beispielen.
Die grundlegende Syntax eines for
Schleife ist:
for <variable name> in <a list of items>;do <some command> $<variable name>;done;
Der Variablenname wird die Variable sein, die Sie in do
angeben Abschnitt und enthält das Element in der Schleife, in der Sie sich gerade befinden.
Die Liste der Elemente kann alles sein, was ein Leerzeichen oder eine durch Zeilenumbrüche getrennte Liste zurückgibt.
Hier ist ein Beispiel:
$ for name in joey suzy bobby;do echo $name;done
Das ist ungefähr so einfach wie es nur geht und dort ist nicht viel los, aber es hilft Ihnen beim Einstieg. Die Variable $name enthält das Element in der Liste, an dem die Schleife gerade arbeitet, und einmal den Befehl (oder die Befehle) in do
Abschnitt ausgeführt werden, springt die Schleife zum nächsten Element. Sie können auch mehr als eine Aktion pro Schleife ausführen. Alles zwischen do
und done
wird durchgeführt. Neue Befehle brauchen nur einen ;
sie abzugrenzen.
$ for name in joey suzy bobby; do echo first $name;echo second $name;done;
first joey
second joey
first suzy
second suzy
first bobby
second bobby
Nun zu etwas echtem Beispiele.
Dateien umbenennen
Diese Schleife nimmt die Ausgabe des Bash-Befehls ls *.pdf
und führt eine Aktion für jeden zurückgegebenen Dateinamen aus. In diesem Fall fügen wir das heutige Datum am Ende des Dateinamens hinzu (aber vor der Dateierweiterung).
for i in $(ls *.pdf); do
mv $i $(basename $i .pdf)_$(date +%Y%m%d).pdf
done
Führen Sie diese Schleife zur Veranschaulichung in einem Verzeichnis aus, das diese Dateien enthält:
file1.pdf
file2.pdf
...
fileN.pdf
Die Dateien werden wie folgt umbenannt:
file1_20210210.pdf
file2_20210210.pdf
...
fileN_20210210.pdf
In einem Verzeichnis mit Hunderten von Dateien spart Ihnen diese Schleife viel Zeit beim Umbenennen aller Dateien.
Extrapolieren von Artikellisten
Stellen Sie sich vor, Sie haben eine Datei, die Sie scp
möchten auf mehrere Server. Denken Sie daran, dass Sie for
kombinieren können Schleife mit anderen Bash-Funktionen, wie z. B. der Shell-Erweiterung, die es Bash ermöglicht, eine Liste von Elementen zu erweitern, die sich in einer Reihe befinden. Dies kann für Buchstaben und Zahlen funktionieren. Zum Beispiel:
$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10
Angenommen, Ihre Server sind nach einem Muster wie web0 benannt , web1 , web2 , web3 , können Sie Bash die Reihe von Zahlen wie folgt iterieren lassen:
$ for i in web{0..10};do scp somefile.txt ${i}:;done;
Dies wird durch web0 iterieren , web1 , web2 , web3 , und so weiter, indem Sie Ihren Befehl für jedes Element ausführen.
Sie können auch einige Iterationen definieren. Zum Beispiel:
$ for i in web{0..10} db{0..2} balance_{a..c};do echo $i;done
web0
web1
web2
web3
web4
web5
web6
web7
web8
web9
web10
db0
db1
db2
balance_a
balance_b
balance_c
Sie können Iterationen auch kombinieren. Stellen Sie sich vor, Sie haben zwei Rechenzentren, eines in den Vereinigten Staaten, das andere in Kanada, und die Namenskonvention des Servers gibt an, in welchem Rechenzentrum ein Server-HA-Paar lebte. Beispiel:web-us-0 wäre der erste Webserver im US-Rechenzentrum, während web-ca-0 wären Web 0 Gegenstück im CA-Rechenzentrum. Um etwas auf beiden Systemen auszuführen, können Sie eine Sequenz wie diese verwenden:
$ for i in web-{us,ca}-{0..3};do echo $i;done
web-us-0
web-us-1
web-us-2
web-us-3
web-ca-0
web-ca-1
web-ca-2
web-ca-3
Falls Ihre Servernamen nicht einfach zu durchlaufen sind, können Sie for
eine Liste mit Namen bereitstellen Schleife:
$ cat somelist
first_item
middle_things
foo
bar
baz
last_item
$ for i in `cat somelist`;do echo "ITEM: $i";done
ITEM: first_item
ITEM: middle_things
ITEM: foo
ITEM: bar
ITEM: baz
ITEM: last_item
Verschachtelung
Sie können einige dieser Ideen auch für komplexere Anwendungsfälle kombinieren. Stellen Sie sich beispielsweise vor, Sie möchten eine Liste von Dateien auf Ihre Webserver kopieren, die der nummerierten Namenskonvention folgen, die Sie im vorherigen Beispiel verwendet haben.
Sie können dies erreichen, indem Sie eine zweite Liste basierend auf Ihrer ersten Liste durch verschachtelte Schleifen durchlaufen. Dies wird ein wenig schwer nachzuvollziehen, wenn Sie es als Einzeiler tun, aber es kann definitiv getan werden. Ihr verschachtelter for
Schleife wird bei jeder Iteration des übergeordneten for
ausgeführt Schleife. Achten Sie darauf, für jede Schleife unterschiedliche Variablennamen anzugeben.
Zum Kopieren der Dateiliste file1.txt, file2.txt, und file3.txt zu den Webservern verwenden Sie diese verschachtelte Schleife:
$ for i in file{1..3};do for x in web{0..3};do echo "Copying $i to server $x"; scp $i $x; done; done
Copying file1 to server web0
Copying file1 to server web1
Copying file1 to server web2
Copying file1 to server web3
Copying file2 to server web0
Copying file2 to server web1
Copying file2 to server web2
Copying file2 to server web3
Copying file3 to server web0
Copying file3 to server web1
Copying file3 to server web2
Copying file3 to server web3
Mehr kreative Umbenennung
Möglicherweise gibt es andere Möglichkeiten, dies zu erreichen, aber denken Sie daran, dass dies nur ein Beispiel für Dinge ist, die Sie machen können tun mit einem for
Schleife. Was ist, wenn Sie einen Berg von Dateien mit dem Namen FILE002.txt haben? , und Sie möchten FILE ersetzen mit so etwas wie TEXT . Denken Sie daran, dass Ihnen neben Bash selbst auch andere Open-Source-Tools wie sed
zur Verfügung stehen , grep
, und mehr. Sie können diese Tools mit for
kombinieren Schleife wie folgt:
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ for i in $(ls FILE*.txt);do mv $i `echo $i | sed s/FILE/TEXT/`;done
$ ls FILE*.txt
ls: cannot access 'FILE*.txt': No such file or directory
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
Hinzufügen einer for-Schleife zu einem Bash-Skript
Ausführen von for
Schleifen direkt auf der Befehlszeile ist großartig und spart Ihnen bei einigen Aufgaben viel Zeit. Zusätzlich können Sie for
einfügen Schleifen als Teil Ihrer Bash-Skripte für mehr Leistung, Lesbarkeit und Flexibilität.
Beispielsweise können Sie das Beispiel einer verschachtelten Schleife einem Bash-Skript hinzufügen, um dessen Lesbarkeit zu verbessern, wie folgt:
$ vim copy_web_files.sh
# !/bin/bash
for i in file{1..3};do
for x in web{0..3};do
echo "Copying $i to server $x"
scp $i $x
done
done
Wenn Sie dieses Skript speichern und ausführen, ist das Ergebnis das gleiche wie beim Ausführen des Beispiels für eine verschachtelte Schleife oben, aber es ist besser lesbar und außerdem einfacher zu ändern und zu warten.
$ bash copy_web_files.sh
Copying file1 to server web0
Copying file1 to server web1
... TRUNCATED ...
Copying file3 to server web3
Sie können auch die Flexibilität und Wiederverwendbarkeit Ihres for
erhöhen Schleifen, indem Sie sie in Bash-Skripte einfügen, die Parametereingaben zulassen. Beispielsweise zum Umbenennen von Dateien wie im Beispiel Mehr kreative Umbenennung oben, damit der Benutzer das Namensuffix angeben kann, verwenden Sie dieses Skript:
$ vim rename_files.sh
# !/bin/bash
source_prefix=$1
suffix=$2
destination_prefix=$3
for i in $(ls ${source_prefix}*.${suffix});do
mv $i $(echo $i | sed s/${source_prefix}/${destination_prefix}/)
done
In diesem Skript stellt der Benutzer das Präfix der Quelldatei als ersten Parameter, das Dateisuffix als zweiten und das neue Präfix als dritten Parameter bereit. Zum Beispiel, um alle Dateien umzubenennen, die mit FILE beginnen , vom Typ .txt zu TEXT , führen Sie das Skript wie folgt aus:
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ bash rename_files.sh FILE txt TEXT
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
Dies ähnelt dem ursprünglichen Beispiel, aber jetzt können Ihre Benutzer andere Parameter angeben, um das Skriptverhalten zu ändern. Zum Beispiel, um alle Dateien umzubenennen, die jetzt mit TEXT beginnen zu NEU , verwenden Sie Folgendes:
$ bash rename_files.sh TEXT txt NEW
$ ls NEW*.txt
NEW0.txt NEW10.txt NEW1.txt NEW2.txt NEW3.txt NEW4.txt NEW5.txt NEW6.txt NEW7.txt NEW8.txt NEW9.txt
[ Ein kostenloser Kurs für Sie:Virtualization and Infrastructure Migration Technical Overview. ]
Schlussfolgerung
Hoffentlich haben diese Beispiele die Leistungsfähigkeit eines for
demonstriert Schleife in der Bash-Befehlszeile. Mit Schleifen können Sie wirklich viel Zeit sparen und Aufgaben weniger fehleranfällig ausführen. Sei einfach vorsichtig. Ihre Schleifen werden tun, worum Sie sie bitten, selbst wenn Sie sie versehentlich bitten, etwas Zerstörerisches zu tun, wie das Erstellen (oder Löschen) logischer Volumes oder virtueller Laufwerke.
Wir hoffen, dass Bash for
Schleifen verändern Ihre Welt genauso wie sie unsere verändert haben.