Startseite » wie man » Das Einsteigerhandbuch zu Shell Scripting 2 für Schleifen

    Das Einsteigerhandbuch zu Shell Scripting 2 für Schleifen

    Wenn Sie Ihr Geek-Gutachten aufbauen möchten, nehmen Sie an der zweiten Ausgabe unserer Shell-Skriptserie teil. Wir haben ein paar Korrekturen, ein paar Verbesserungen am Skript der letzten Woche und einen Leitfaden zum Looping für Uneingeweihte.

    Das Datecp-Skript wurde erneut aufgerufen

    In der ersten Installation unseres Shell-Scripting-Handbuchs 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, um mit unseren variablen Referenzen umzugehen.

    Die Argumente sind in der Bash-Shell durch Leerzeichen getrennt. Sie werden als Token formatiert, wenn der resultierende erweiterte Befehl ein Leerzeichen enthält. In deinem Skript, cp $ 1 $ 2. $ date_formatted funktioniert wie vorgesehen, solange die erweiterten Variablen keine Leerzeichen enthalten. Wenn Sie Ihr Skript auf diese Weise aufrufen: datecp "mein alter name" "mein neuer name" Die Erweiterung führt zu diesem Befehl: cp mein neuer name mein alter name.the_date das hat eigentlich 6 Argumente.

    Um dieses Problem richtig anzugehen, sollte die letzte Zeile des Skripts lauten: cp "$ 1" "$ 2. $ date_formatted"

    Wie Sie sehen, ändern Sie die Skriptzeile von:

    cp -iv $ 1 $ 2. $ date_formatted

    zu:

    cp -iv "$ 1" "$ 2". $ date_formatted

    Dieses Problem wird bei der Verwendung des Skripts für Dateien mit Leerzeichen im Namen behoben. 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 müssen, die sie oft ersetzen. Wir werden auch mehr tun, um sicherzustellen, dass unser Code mehr zum Kopieren / Einfügen geeignet ist. ;-)

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

    tastyfile.mp3.07_14_11-12.34.56

    wir würden das bekommen:

    deliciousfile.07_14_11-12.34.56.mp3

    was für die meisten Benutzer etwas bequemer ist. Sein Code ist auf seiner GitHub-Seite verfügbar. 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 "$ 1" | awk -F. 'print $ NF')
    Dateiname = $ (Basisname $ 1. $ Dateierweiterung)

    cp -iv $ 1 $ Dateiname- $ Datum_formatiert. $ Dateierweiterung

    Ich habe die Formatierung etwas geändert, aber Sie können sehen, dass Myles seine Datumsfunktion in Zeile 1 deklariert. In Zeile 2 verwendet er jedoch den Befehl "echo" mit dem ersten Argument des Skripts, um den Dateinamen auszugeben. Er verwendet den Pipe-Befehl, um diese Ausgabe zu übernehmen und als Eingabe für den nächsten Teil zu verwenden. Nach der Pipe ruft Myles den Befehl "awk" auf, ein leistungsfähiges Muster-Scanprogramm. Mit dem -F-Flag sagt er dem Befehl, dass das nächste Zeichen (nach einem Leerzeichen) das "Feldtrennzeichen" definiert. In diesem Fall ist das eine Periode.

    Nun sieht awk, dass eine Datei mit dem Namen "tastyfile.mp3" aus zwei Feldern besteht: "tastyfile" und "mp3". Zuletzt benutzt er

    'print $ NF'

    um das letzte Feld anzuzeigen. Falls Ihre Datei mehrere Punkte enthält, so dass awk mehrere Felder anzeigen kann, wird nur der letzte angezeigt, dh die Dateierweiterung.

    In Zeile 3 erstellt er eine neue Variable für den Dateinamen und verwendet den Befehl "basename", um auf alles in $ 1 zu verweisen außer die Dateierweiterung. Dazu verwenden Sie basename und geben ihm $ 1 als Argument. Anschließend fügen Sie ein Leerzeichen und die Dateierweiterung hinzu. Die Dateierweiterung wird automatisch hinzugefügt, da die Variable Zeile 2 referenziert

    leckerdatei.mp3

    und verwandeln es in

    leckere Datei

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

    Skripts und $ PATH ausführen

    In unserem Basics-Artikel wird auch erwähnt, dass Skripts 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

    Wenn Sie Ihre Skripte in ~ / bin / platzieren, können Sie deren Namen einfach von überall eingeben, um sie zum Laufen zu bringen.

    Die Kommentatoren haben einige Zeit darüber debattiert, wie richtig das ist, da keine moderne Linux-Distribution dieses Verzeichnis standardmäßig erstellt. Außerdem fügt es niemand standardmäßig der Variablen $ PATH hinzu. Dies ist erforderlich, damit Skripts wie Befehle ausgeführt werden können. Ich war etwas verwirrt, denn nachdem ich meine $ PATH-Variable überprüft hatte, waren die Kommentatoren richtig, aber das Aufrufen von Skripts funktionierte immer noch für mich. Ich habe herausgefunden warum: Viele moderne Linux-Distributionen erstellen eine spezielle Datei im Home-Verzeichnis des Benutzers - .profile.

    Diese Datei wird von bash gelesen (sofern nicht .bash_profile im Home-Verzeichnis des Benutzers vorhanden ist). Unten befindet sich ein Abschnitt, der den Ordner ~ / bin / der $ PATH-Variablen hinzufügt, falls vorhanden. Dieses Rätsel ist also geklärt. Für den Rest der Serie werde ich weiterhin Skripts im Verzeichnis ~ / bin / ablegen, da es sich um Benutzerscripts handelt, die von Benutzern ausgeführt werden können. Es scheint so, als müssten wir uns nicht wirklich mit der $ PATH-Variablen beschäftigen, damit alles funktioniert.

    Befehle mit Schleifen wiederholen

    Kommen wir zu einem der nützlichsten Werkzeuge im Geek-Arsenal für den Umgang mit sich wiederholenden Aufgaben: Schleifen. Heute werden wir über "for" -Schleifen sprechen.

    Die grundlegende Gliederung einer for-Schleife lautet wie folgt:

    für VARIABLE in LISTE; tun
    Befehl1
    Befehl2

    commandn
    erledigt

    VARIABLE kann eine beliebige Variable sein. Meistens wird jedoch das Kleinbuchstabe „i“ verwendet. LIST ist eine Liste von Elementen. Sie können mehrere Elemente angeben (durch ein Leerzeichen trennen), auf eine externe Textdatei zeigen oder ein Sternchen (*) verwenden, um eine beliebige Datei im aktuellen Verzeichnis zu kennzeichnen. Die aufgeführten Befehle sind durch Konventionen eingerückt, so dass es einfacher ist, Verschachtelungen zu sehen - Schleifen in Schleifen zu setzen (damit Sie während der Schleife eine Schleife bilden können)..

    Da Listen Leerzeichen als Trennzeichen verwenden, dh ein Leerzeichen bedeutet, dass zum nächsten Element in der Liste gewechselt wird, sind Dateien mit Leerzeichen im Namen nicht besonders freundlich. Lassen Sie uns zunächst mit Dateien ohne Leerzeichen arbeiten. Beginnen wir mit einem einfachen Skript, um die Namen der Dateien im aktuellen Verzeichnis anzuzeigen. Erstellen Sie in Ihrem ~ / bin / -Ordner ein neues Skript mit dem Namen "loopscript". Wenn Sie sich nicht daran erinnern, wie Sie dies tun (einschließlich der Markierung als ausführbar und Hinzufügen des Hash-Knall-Hacks), lesen Sie unseren Bash-Skriptartikel.

    Geben Sie darin den folgenden Code ein:

    für i in item1 item2 item3 item4 item5 item6; tun
    Echo "$ i"
    erledigt

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

    Ganz einfach, richtig? Mal sehen, was passiert, wenn wir die Dinge ein bisschen ändern. Ändern Sie Ihr Skript so, dass es dies sagt:

    für i in *; tun
    Echo "$ i"
    erledigt

    Wenn Sie dieses Skript in einem Ordner ausführen, sollten Sie eine Liste der Dateien erhalten, die es als Ausgabe enthält.

    Nun ändern wir den Befehl echo in etwas nützlicheres, beispielsweise den Befehl zip. Wir fügen nämlich Dateien zu einem Archiv hinzu. Und lasst uns einige Argumente in die Mischung bekommen!

    für i in $ @; tun
    Zip-Archiv "$ i"
    erledigt

    Da ist etwas Neues! „$ @“ Ist eine Abkürzung für „$ 1 $ 2 $ 3… $ n“. Mit anderen Worten, es ist die vollständige Liste aller von Ihnen angegebenen Argumente. Nun sehen Sie sich an, was passiert, wenn ich das Skript mit mehreren Eingabedateien ausführe.

    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 gezippten Archiv mit dem Namen "archive.zip" hinzugefügt. Einfach richtig?

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


    Die Verwendung von for-loops macht es einfach, eine Reihe von Aktionen für alle Dateien in einem Verzeichnis auszuführen. Sie können eine Vielzahl von Befehlen zusammen stapeln und sehr einfach Argumente zum Erstellen von Listen verwenden. Dies ist nur die Spitze des Eisbergs.

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