Das Einsteigerhandbuch zu Shell Scripting 2: Für Schleifen

Inhaltsverzeichnis:

Video: Das Einsteigerhandbuch zu Shell Scripting 2: Für Schleifen

Video: Das Einsteigerhandbuch zu Shell Scripting 2: Für Schleifen
Video: Kühler undicht ?! | Kühlwasserverlust beheben mit "Kühler Dichter" | DIY Tutorial 2023, November
Das Einsteigerhandbuch zu Shell Scripting 2: Für Schleifen
Das Einsteigerhandbuch zu Shell Scripting 2: Für Schleifen
Anonim
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 Schleifen für Uneingeweihte.
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 Schleifen 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, mit unseren variablen Referenzen umzugehen.

Arguments are space-separated in the bash shell, it will tokenize when there is a space in the resulted expanded command. In your script,

cp $1 $2.$date_formatted

funktioniert wie vorgesehen, solange die erweiterten Variablen keine Leerzeichen enthalten. Wenn Sie Ihr Skript auf diese Weise aufrufen:

datecp 'my old name' 'my new name'

Die Erweiterung führt zu diesem Befehl:

cp my new name my old 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 Zeile unseres Skripts von:

cp -iv $1 $2.$date_formatted

zu:

cp -iv “$1” “$2”.$date_formatted

behebt dieses Problem, wenn Sie das Skript für Dateien verwenden, 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 müssen, die sie häufig ersetzen. Wir werden auch mehr tun, um sicherzustellen, dass unser Code für das Kopieren und Einfügen besser 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:

tastyfile.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, wie er den Dateinamen auseinanderzieht.

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

cp -iv $1 $file_name-$date_formatted.$file_extension

Ich habe die Formatierung ein wenig 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 teilt er dem Befehl mit, dass das nächste Zeichen (nach einem Leerzeichen) das "Feldtrennzeichen" definiert. In diesem Fall ist dies eine Periode.

Nun sieht awk eine Datei mit dem Namen "tastyfile.mp3", die aus zwei Feldern zusammengesetzt ist: "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 anzeigt, 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, fügen dann ein Leerzeichen und die Dateierweiterung hinzu. Die Dateierweiterung wird automatisch hinzugefügt, da die Variable Zeile 2 referenziert

tastyfile.mp3

und verwandeln es in

tastyfile

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. Großartiger Job, 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:

./script

~/bin/script

Wenn Sie Ihre Skripts jedoch in ~ / bin / ablegen, können Sie deren Namen einfach von überall eingeben, damit sie ausgeführt werden können.

Die Kommentatoren haben einige Zeit darüber debattiert, wie richtig dies 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 ein bisschen 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.

Image
Image

Diese Datei wird von bash gelesen (sofern nicht.bash_profile im Home-Verzeichnis des Benutzers vorhanden ist). Am unteren Rand befindet sich ein Abschnitt, in dem der Ordner ~ / bin / der $ PATH-Variablen hinzugefügt wird, sofern sie vorhanden ist. 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, dass wir uns nicht wirklich mit der $ PATH-Variablen von Hand anlegen müssen, um die Dinge zum Laufen zu bringen.

Befehle mit Schleifen wiederholen

Kommen wir zu einem der nützlichsten Werkzeuge im Geek-Arsenal, um sich wiederholende Aufgaben zu bewältigen: Schleifen. Heute besprechen wir "für" Schleifen.

Die grundlegende Gliederung einer for-Schleife lautet wie folgt:

for VARIABLE in LIST; do command1 command2 … commandn done

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, d. H. 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 Titel "loopscript". Wenn Sie sich nicht 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:

for i in item1 item2 item3 item4 item5 item6; do echo “$i” done

Wenn Sie das Skript ausführen, sollten Sie diese Listenelemente nur als Ausgabe erhalten.
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:
Ganz einfach, richtig? Mal sehen, was passiert, wenn wir die Dinge ein bisschen ändern. Ändern Sie Ihr Skript so, dass es dies sagt:

for i in *; do echo “$i” done

Wenn Sie dieses Skript in einem Ordner ausführen, sollten Sie eine Liste der Dateien erhalten, die es als Ausgabe enthält.
Wenn Sie dieses Skript in einem Ordner ausführen, sollten Sie eine Liste der Dateien erhalten, die es als Ausgabe enthält.
Jetzt ä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!
Jetzt ä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!

for i in $@; do zip archive “$i” done

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.
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?
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 Argumente sehr einfach zum Erstellen einer Liste "on-the-fly" 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? Hinterlasse ein paar Kommentare und hilf anderen Scripting-Neulingen!

Empfohlen: