Der Anfängerleitfaden für Shell Scripting 2: For-Schleifen

Der Anfängerleitfaden für Shell Scripting 2: For-Schleifen

Beginner S Guide Shell Scripting 2

Wenn Sie Ihr Credo für Computerfreaks aufbauen möchten, besuchen Sie uns für den zweiten Teil unserer Shell-Scripting-Reihe. Wir haben ein paar Korrekturen, ein paar Verbesserungen am Skript der letzten Woche und eine Anleitung zum Loopen für Uneingeweihte.



Das datecp-Skript erneut besucht

Im erste Ausgabe unseres Shell-Scripting-Leitfadens , haben wir ein Skript erstellt, das eine Datei in ein Sicherungsverzeichnis kopiert, nachdem das Datum an das Ende des Dateinamens angehängt wurde.

Samuel Dionne-Riel wies in den Kommentaren darauf hin, dass es einen viel besseren Weg gibt, mit unseren variablen Referenzen umzugehen.

Argumente werden in der Bash-Shell durch Leerzeichen getrennt, sie wird tokenisiert, wenn im resultierenden erweiterten Befehl ein Leerzeichen vorhanden ist. In Ihrem Skript |_+_| funktioniert wie beabsichtigt, solange die erweiterten Variablen keine Leerzeichen enthalten. Wenn Sie Ihr Skript so aufrufen: |_+_| die Erweiterung führt zu diesem Befehl: |_+_| was eigentlich 6 Argumente hat.

Um dieses Problem richtig zu beheben, sollte die letzte Zeile des Skripts lauten: |_+_|

Wie Sie sehen können, ändern Sie die Zeile unseres Skripts von:

cp -iv .$date_formatted

zu:

cp -iv .$date_formatted

wird dieses Problem beheben, wenn das Skript für Dateien verwendet wird, deren Namen Leerzeichen enthalten. Samuel weist auch darauf hin, dass beim Kopieren und Einfügen von Code von dieser Site (oder dem Internet im Allgemeinen) die richtigen Bindestriche und Anführungszeichen durch die typografisch besseren ersetzt werden, die sie oft ersetzen. Wir werden auch mehr tun, um sicherzustellen, dass unser Code kopierfreundlicher ist. ;-)

Ein anderer Kommentator, Myles Braithwaite, beschloss, unser Skript so zu erweitern, dass das Datum vor der Dateierweiterung erscheint. Also statt

leckerfile.mp3.07_14_11-12.34.56

wir würden das bekommen:

leckerfile.07_14_11-12.34.56.mp3

Anzeige

was für die meisten Benutzer etwas bequemer ist. Sein Code ist verfügbar unter on seine GitHub-Seite . Schauen wir uns an, was er verwendet, um den Dateinamen auseinander zu ziehen.

date_formatted=$(Datum +%Y-%m-%d_%H.%M%S)
file_extension=$(echo ″|awk -F . ‘{print $NF}’)
file_name=$(Basisname .$file_extension)

cp -iv $file_name-$date_formatted.$file_extension

Ich habe die Formatierung etwas geändert, aber man sieht, dass Myles seine Datumsfunktion in Zeile 1 deklariert. In Zeile 2 verwendet er jedoch den echo-Befehl mit dem ersten Argument des Skripts, um den Dateinamen auszugeben. Er verwendet den Pipe-Befehl, um diese Ausgabe zu übernehmen und sie als Eingabe für den nächsten Teil zu verwenden. Nach der Pipe ruft Myles den Befehl awk auf, ein leistungsstarkes Programm zum Scannen von Mustern. Mit dem Flag -F teilt er dem Befehl mit, dass das nächste Zeichen (nach einem Leerzeichen) das Feldtrennzeichen definiert. In diesem Fall ist das ein Zeitraum.

Nun sieht awk eine Datei mit dem Namen schmackhaftfile.mp3 als aus zwei Feldern zusammengesetzt: schmackhaftfile und mp3. Schließlich verwendet er

‘{print $NF}’

um das letzte Feld anzuzeigen. Falls Ihre Datei mehrere Punkte hat – wodurch awk mehrere Felder sieht – wird nur der letzte angezeigt, der die Dateierweiterung ist.

In Zeile 3 erstellt er eine neue Variable für den Dateinamen und verwendet den Befehl basename, um auf alles in . zu verweisen außer die Dateierweiterung. Dies geschieht, indem basename verwendet und als Argument angegeben wird, dann ein Leerzeichen und die Dateierweiterung hinzugefügt werden. Die Dateierweiterung wird aufgrund der Variable, die auf Zeile 2 verweist, automatisch hinzugefügt. Was dies tun würde, ist Folgendes:

leckerfile.mp3

und verwandle es in

leckerfile

Dann hat Myles in der letzten Zeile den Befehl zusammengestellt, der alles in der richtigen Reihenfolge ausgibt. Beachten Sie, dass es keinen Verweis auf gibt, ein zweites Argument für das Skript. Dieses spezielle Skript kopiert stattdessen die Datei in Ihr aktuelles Verzeichnis. Tolle Arbeit, Samuel und Myles!

Ausführen von Skripten und $PATH

Wir erwähnen auch in unserem Grundlagenartikel, dass Skripte standardmäßig nicht als Befehle referenziert werden dürfen. Das heißt, Sie müssen auf den Pfad des Skripts zeigen, um es auszuführen:

./Skript

~/bin/script

Anzeige

Aber indem Sie Ihre Skripte in ~/bin/ platzieren, können Sie ihre Namen einfach von überall eingeben, damit sie ausgeführt werden.

Kommentatoren verbrachten einige Zeit damit, darüber zu diskutieren, wie richtig dies war, da keine moderne Linux-Distribution dieses Verzeichnis standardmäßig erstellt. Darüber hinaus fügt es auch niemand standardmäßig der Variablen $PATH hinzu, was erforderlich ist, damit Skripte wie Befehle ausgeführt werden. Ich war etwas verwirrt, weil die Kommentatoren Recht hatten, nachdem ich meine $PATH-Variable überprüft hatte, aber das Aufrufen von Skripten funktionierte immer noch für mich. Ich habe herausgefunden, warum: Viele moderne Linux-Distributionen erstellen eine spezielle Datei im Home-Verzeichnis des Benutzers – .profile.

Punktprofil

Diese Datei wird von der bash gelesen (es sei denn, .bash_profile ist im Home-Verzeichnis des Benutzers vorhanden) und unten gibt es einen Abschnitt, der den Ordner ~/bin/ zur $PATH-Variablen hinzufügt, falls vorhanden. Damit ist dieses Geheimnis gelüftet. Für den Rest der Serie werde ich weiterhin Skripte im Verzeichnis ~/bin/ platzieren, da es sich um Benutzerskripte handelt und von Benutzern ausgeführt werden können sollten. Und es scheint, dass wir nicht wirklich mit der Variablen $PATH herumspielen müssen, um die Dinge zum Laufen zu bringen.

Wiederholen von Befehlen mit Schleifen

Kommen wir zu einem der nützlichsten Tools im Geek-Arsenal für den Umgang mit sich wiederholenden Aufgaben: Schleifen. Heute besprechen wir for-Schleifen.

Die grundlegende Gliederung einer for-Schleife sieht wie folgt aus:

für VARIABLE in LISTE; tun
Befehl1
Befehl2
...
Befehl
fertig

VARIABLE kann eine beliebige Variable sein, obwohl meistens das kleine i gemäß Konvention verwendet wird. LIST ist eine Liste von Elementen; Sie können mehrere Elemente angeben (durch Leerzeichen getrennt), auf eine externe Textdatei verweisen oder ein Sternchen (*) verwenden, um eine beliebige Datei im aktuellen Verzeichnis zu kennzeichnen. Die aufgeführten Befehle sind gemäß Konvention eingerückt, sodass Verschachtelungen leichter zu erkennen sind – Schleifen in Schleifen einfügen (damit Sie Schleifen während der Schleife ausführen können).

Anzeige

Da Listen Leerzeichen als Trennzeichen verwenden – d. h. ein Leerzeichen bedeutet einen Wechsel zum nächsten Element in der Liste – sind Dateien mit Leerzeichen im Namen nicht sehr benutzerfreundlich. Bleiben wir vorerst bei der Arbeit mit Dateien ohne Leerzeichen. Beginnen wir mit einem einfachen Skript, um die Namen der Dateien im aktuellen Verzeichnis anzuzeigen. Erstellen Sie in Ihrem Ordner ~/bin/ ein neues Skript mit dem Namen loopscript. Wenn Sie sich nicht daran erinnern, wie dies zu tun ist (einschließlich der Markierung als ausführbar und des Hinzufügens des Hash-Bang-Hack), lesen Sie unsere Artikel zu den Grundlagen der Bash-Skripterstellung .

Geben Sie darin den folgenden Code ein:

für i in item1 item2 item3 item4 item5 item6; tun
echo $i
fertig

Echoliste

Wenn Sie das Skript ausführen, sollten Sie nur diese Listenelemente als Ausgabe erhalten.

Echoliste raus

Ziemlich einfach, oder? Mal sehen, was passiert, wenn wir die Dinge ein wenig ändern. Ändern Sie Ihr Skript so, dass es Folgendes sagt:

für ich in *; tun
echo $i
fertig

echo Dateinamen

Wenn Sie dieses Skript in einem Ordner ausführen, sollten Sie eine Liste der darin enthaltenen Dateien als Ausgabe erhalten.

echo Dateinamen aus

Lassen Sie uns nun den echo-Befehl in etwas Nützlicheres ändern – sagen wir, den Zip-Befehl. Wir fügen nämlich Dateien zu einem Archiv hinzu. Und lassen Sie uns einige Argumente in die Mischung bringen!

für i in $@; tun
ZIP-Archiv $i
fertig

zip-Argumente

Es gibt was Neues! $@ ist eine Abkürzung für … $n. Mit anderen Worten, es ist die vollständige Liste aller von Ihnen angegebenen Argumente. Beobachten Sie nun, was passiert, wenn ich das Skript mit mehreren Eingabedateien ausführe.

zippen Argumente aus

Anzeige

Sie können sehen, welche Dateien sich in meinem Ordner befinden. Ich habe den Befehl mit sechs Argumenten ausgeführt und jede Datei wurde einem komprimierten Archiv namens archive.zip hinzugefügt. Einfach richtig?

spotify, wie man die Warteschlange leert

For-Schleifen sind ziemlich wunderbar. Jetzt können Sie Stapelfunktionen für Dateilisten ausführen. Sie können beispielsweise alle Argumente Ihres Skripts in ein komprimiertes Archiv kopieren, die Originale in einen anderen Ordner verschieben und automatisch sichere Kopie diese ZIP-Datei auf einen Remote-Computer. Wenn Sie Schlüsseldateien mit SSH einrichten, müssen Sie nicht einmal Ihr Passwort eingeben und können das Skript sogar anweisen, die ZIP-Datei nach dem Hochladen zu löschen!


Die Verwendung von for-Schleifen macht es einfach, eine Reihe von Aktionen für alle Dateien in einem Verzeichnis auszuführen. Sie können eine Vielzahl von Befehlen stapeln und Argumente sehr einfach verwenden, um eine On-the-Fly-Liste zu erstellen, und dies ist nur die Spitze des Eisbergs.

Bash-Scripter, habt ihr Vorschläge? Haben Sie ein nützliches Skript erstellt, das Schleifen verwendet? Möchten Sie Ihre Gedanken zur Serie teilen? Hinterlassen Sie ein paar Kommentare und helfen Sie anderen Scripting-Neulingen!

WEITER LESEN