Shell-Skripte werden in der UNIX-Welt häufig verwendet. Sie eignen sich hervorragend, um sich wiederholende Aufgaben zu beschleunigen und komplexe Ausführungslogiken zu vereinfachen. Sie können so einfach sein wie eine Reihe von Befehlen oder sie können komplexe Aufgaben orchestrieren. In diesem Lernprogramm erfahren Sie mehr über die Bash-Skriptsprache, indem Sie Schritt für Schritt ein Beispielskript schreiben.
Eine der besten Möglichkeiten, eine neue Sprache zu erlernen, ist ein Beispiel. Beginnen wir mit einem.
Das Fizz-Buzz-Problem ist sehr einfach. Es wurde berühmt, nachdem ein Programmierer namens Imran es als Interviewtest verwendet hatte. Es stellt sich heraus, dass 90-99,5% der Kandidaten für einen Programmierjob einfach nicht in der Lage sind, das einfachste Programm zu schreiben. Imran nahm dieses einfache Fizz-Buzz-Spiel und bat die Kandidaten, es zu lösen. Viele folgten dem Beispiel von Imran, und heute ist es eine der am häufigsten gestellten Fragen für einen Programmierjob. Wenn Sie einstellen und 90% der Kandidaten durchforsten möchten, ist dies ein großes Problem.
Hier sind die Regeln:
Das ist alles dazu. Ich bin mir sicher, dass die meisten von euch die zwei oder drei bereits visualisieren können ob
Aussagen zu lösen. Lassen Sie uns dies mit der Skriptsprache Bash durcharbeiten.
Ein Shebang bezieht sich auf die Kombination von Hash- und Ausrufezeichen: #!
. Der Programmlader sucht in der ersten Zeile des Skripts nach einem Shebang und verwendet den darin angegebenen Interpreter. Ein Shebang besteht aus der folgenden Syntax: #!Interpreter [Parameter]
. Der Interpreter ist das Programm, das zur Interpretation unserer Sprache verwendet wird. Für Bash-Scripting wäre das so / bin / bash
. Wenn Sie beispielsweise ein Skript in PHP erstellen und in der Konsole ausführen möchten, möchten Sie dies wahrscheinlich verwenden / usr / bin / php
(oder den Pfad zur ausführbaren PHP-Datei auf Ihrem Computer) als Interpreter.
#! / usr / bin / phpJa, das geht tatsächlich! Ist es nicht einfach Stellen Sie sicher, dass Ihre Datei zuerst ausführbar ist. Sobald Sie dies tun, gibt dieses Skript Ihre PHP-Informationen wie erwartet aus.
Spitze: Um sicherzustellen, dass Ihr Skript auf so vielen Systemen wie möglich funktioniert, können Sie verwenden
/ bin / env
im Shebang. Als solche statt/ bin / bash
, Du könntest benutzen/ bin / env bash
, Dies funktioniert auf Systemen, auf denen sich die ausführbare bash-Datei nicht befindet/Behälter
.
Text ausgeben
Die Ausgabe eines Skripts entspricht erwartungsgemäß dem, was von Ihrem Befehl ausgegeben wird. Wenn wir jedoch ausdrücklich etwas auf den Bildschirm schreiben möchten, können wir dies verwenden
Echo
.#! / bin / bash echo "Hello World"Beim Ausführen dieses Skripts wird "Hello World" in der Konsole gedruckt.
csaba @ csaba ~ $ ./helloWorld.sh Hallo Welt csaba @ csaba ~ $
Variablen einführen
Wie in jeder Programmiersprache können Sie beim Schreiben von Shellskripten Variablen verwenden.
#! / bin / bash message = "Hallo Welt" echo $ messageDieser Code erzeugt genau die gleiche "Hello World" -Meldung. Um einer Variablen einen Wert zuzuweisen, geben Sie einfach ihren Namen ein - schließen Sie das Dollarzeichen vor der Variablen aus. Seien Sie auch vorsichtig mit Leerzeichen; Zwischen dem Variablennamen und dem Gleichheitszeichen dürfen keine Leerzeichen stehen. So
message = "Hallo"
anstattmessage = "Hallo"
Wenn Sie eine Variable verwenden möchten, können Sie den Wert genauso wie wir in der Variablen verwenden
Echo
Befehl. Vorbereiten eines$
an den Namen der Variablen wird der Wert zurückgegeben.Spitze: Semikolons sind für das Bash-Scripting nicht erforderlich. Sie können sie in den meisten Fällen verwenden, aber seien Sie vorsichtig: Sie haben möglicherweise eine andere Bedeutung als Sie erwarten.
Drucken der Zahlen zwischen 1 und 100
Um unser Demo-Projekt fortzusetzen, müssen wir alle Zahlen zwischen 1 und 100 durchlaufen. Dazu benötigen wir eine
zum
Schleife.#! / bin / bash für die Nummer in 1… 100; Echo $ number doneIn diesem Beispiel gibt es einige neue Dinge, die es zu beachten gilt - wobei übrigens alle Zahlen von 1 bis 100 einzeln gedruckt werden.
zum
Syntax in Bash ist: für VARIABLE in RANGE; erledige den Befehl
.1… 100
in einem Bereich in unserem Beispiel. Sie werden auch in anderen Zusammenhängen verwendet, die wir in Kürze überprüfen werden.tun
und zum
sind eigentlich zwei getrennte Befehle. Wenn Sie zwei Befehle in einer Zeile platzieren möchten, müssen Sie sie irgendwie trennen. Eine Möglichkeit ist, Semikolon zu verwenden. Alternativ können Sie den Code auch ohne Semikolon durch Verschieben schreiben tun
in die folgende Zeile.#! / bin / bash für Nummer in 1… 100 echo $ number done
Da wir nun wissen, wie alle Zahlen zwischen 1 und 100 gedruckt werden sollen, ist es an der Zeit, unsere erste Entscheidung zu treffen.
#! / bin / bash für die Nummer in 1… 100; tun, wenn [$ ((Nummer% 3)) -eq 0]; dann Echo "Fizz" sonst Echo $ Nummer fi getan
In diesem Beispiel wird "Fizz" für durch 3 teilbare Zahlen ausgegeben. Wieder müssen wir uns mit etwas neuer Syntax auseinandersetzen. Nehmen wir sie einzeln auf.
wenn… dann… sonst… fi
- Dies ist die klassische Syntax für ein ob
Aussage in Bash. Natürlich die sonst
Teil ist optional - aber in diesem Fall für unsere Logik erforderlich.wenn BEFEHL-RÜCKGABEWERT; dann…
- ob
wird ausgeführt, wenn der Rückgabewert des Befehls Null ist. Ja, die Logik in Bash basiert auf Null, was bedeutet, dass Befehle, die erfolgreich ausgeführt werden, mit einem Code von 0 beendet werden. Wenn etwas schief geht, wird dagegen eine positive Ganzzahl zurückgegeben. Um die Dinge zu vereinfachen, wird alles andere als 0 berücksichtigt falsch
.$ ((Nummer% 3))
gibt den verbleibenden Wert der Division der Variablen zurück, Nummer
, bis 3. Bitte beachten Sie, dass wir nicht verwendet haben $
in der Klammer - nur vor ihnen.Sie fragen sich vielleicht, wo der Befehl in unserem Beispiel steht. Gibt es nicht nur eine Klammer mit einem merkwürdigen Ausdruck darin? Nun, das stellt sich heraus [
ist eigentlich ein ausführbarer Befehl. Probieren Sie die folgenden Befehle in Ihrer Konsole aus, um damit herumzuspielen.
csaba @ csaba ~ $ welche [/ usr / bin / [csaba @ csaba ~ $ [0-eq 1] csaba @ csaba ~ $ echo $? 1 csaba @ csaba ~ $ [0-eq 0] csaba @ csaba ~ $ echo $? 0
Spitze: Der Exit-Wert eines Befehls wird immer in die Variable zurückgegeben,
?
(Fragezeichen). Sie wird nach der Ausführung jedes neuen Befehls überschrieben.
Bis jetzt geht es uns gut. Wir haben "Fizz"; Lassen Sie uns jetzt den "Buzz" -Teil ausführen.
#! / bin / bash für die Nummer in 1… 100; tun, wenn [$ ((Nummer% 3)) -eq 0]; dann Echo "Fizz" elif [$ ((number% 5)) -eq 0]; dann echo "Buzz" sonst echo $ number fi fertig
Oben haben wir mit 5 eine weitere Bedingung für die Teilbarkeit eingeführt: die elif
Aussage. Das bedeutet natürlich zu sonst wenn, und wird ausgeführt, wenn der folgende Befehl zurückgegeben wird wahr
(oder 0
). Wie Sie sehen können, sind die Bedingungsanweisungen darin enthalten []
werden normalerweise mit Hilfe von Parametern wie z -Gl
, das steht für "gleich".
Für die Syntax,
arg1 OP arg2
,OP
ist einer von-Gl
,-ne
,-Es ist
,-le
,-gt
, oder-ge
. Diese arithmetischen Binäroperatoren werden zurückgegebenwahr
obarg1
gleich, nicht gleich, kleiner als, kleiner oder gleich, größer als oder größer als oder gleich istarg2
, beziehungsweise.arg1
undarg2
kann positive oder negative ganze Zahlen sein. - Bash Manual
Wenn Sie versuchen, Zeichenfolgen zu vergleichen, können Sie die bekannten verwenden ==
Zeichen, oder sogar ein einzelnes Gleichheitszeichen reicht aus. !=
kehrt zurück wahr
wenn die Saiten unterschiedlich sind.
Bisher läuft der Code, aber die Logik stimmt nicht. Wenn die Zahl sowohl durch 3 als auch durch 5 teilbar ist, wird unsere Logik nur "Fizz" wiedergeben. Lassen Sie uns unseren Code ändern, um die letzte Anforderung von FizzBuzz zu erfüllen.
#! / bin / bash für die Nummer in 1… 100; tun, wenn [$ ((Nummer% 3)) -eq 0]; dann Ausgabe = "Fizz" fi wenn [$ ((Anzahl% 5)) -eq 0]; dann output = "$ output Buzz" fi wenn [-z $ output]; dann echo $ number sonst echo $ ausgabe; fi fertig
Wieder mussten wir eine Handvoll Änderungen vornehmen. Am bemerkenswertesten ist die Einführung einer Variablen und gegebenenfalls die Verkettung von "Buzz". Strings in Bash werden normalerweise zwischen Anführungszeichen (") definiert. Es können auch einfache Anführungszeichen verwendet werden. Um die Verkettung zu vereinfachen, sind Doubles jedoch die bessere Wahl. Innerhalb dieser Anführungszeichen können Sie Variablen referenzieren: etwas text $ variable etwas anderes text
" wird ersetzen $ variable
mit seinem Inhalt. Wenn Sie Variablen mit Zeichenfolgen ohne Leerzeichen verketten möchten, können Sie den Namen der Variablen lieber in geschweifte Klammern setzen. In den meisten Fällen, wie zum Beispiel PHP, ist dies nicht unbedingt erforderlich, aber es ist sehr hilfreich, wenn es um die Lesbarkeit des Codes geht.
Spitze: Sie können leere Zeichenfolgen nicht vergleichen. Das würde einen fehlenden Parameter zurückgeben.
Weil die Argumente drinnen sind []
werden als Parameter behandelt, z "["
, Sie müssen sich von einer leeren Zeichenfolge unterscheiden. Daher wird dieser Ausdruck, auch wenn er logisch ist, einen Fehler ausgeben: [$ output! = ""]
. Deshalb haben wir verwendet [-z $ Ausgabe]
, die zurückkehrt wahr
wenn der String eine Länge von Null hat.
Eine Möglichkeit, unser Beispiel zu verbessern, besteht darin, den mathematischen Ausdruck aus den Funktionen in Funktionen zu extrahieren ob
Aussagen wie folgt:
#! / bin / bash-Funktion isDivisibleBy return $ (($ 1% $ 2)) für Zahl in 1… 100; do wenn isDivisibleBy $ number 3; dann output = "Fizz" fi wenn isDivisibleBy $ number 5; dann output = "$ output Buzz" fi wenn [-z $ output]; dann echo $ number sonst echo $ ausgabe; fi fertig
Wir haben die Ausdrücke genommen, die den Rest mit Null verglichen, und sie in eine Funktion verschoben. Darüber hinaus haben wir den Vergleich mit Null aufgehoben, weil Null für uns wahr ist. Wir müssen nur den Wert aus dem mathematischen Ausdruck zurückgeben - sehr einfach!
Spitze: Die Definition einer Funktion muss vor dem Aufruf stehen.
In Bash können Sie eine Methode als definieren Funktion func_name befehle;
. Optional gibt es eine zweite Syntax zum Deklarieren von Funktionen: func_name () befehle;
. So können wir die Zeichenfolge löschen, Funktion
und hinzufügen "()
nach dem Namen Ich persönlich bevorzuge diese Option, wie im obigen Beispiel veranschaulicht. Es ist expliziter und ähnelt traditionellen Programmiersprachen.
Sie müssen die Parameter für eine Funktion in Bash nicht angeben. Das Senden von Parametern an eine Funktion erfolgt durch einfaches Aufzählen nach dem Funktionsaufruf, getrennt durch Leerzeichen. Setzen Sie beim Funktionsaufruf keine Kommas oder Klammern - es funktioniert nicht.
Empfangene Parameter werden den Variablen automatisch nach Nummer zugewiesen. Der erste Parameter geht an 1 US-Dollar
, die zweite zu 2 $
, und so weiter. Die spezielle Variable, $ 0
verweist auf den Dateinamen des aktuellen Skripts.
#! / bin / bash function exampleFunc echo $ 1 echo $ 0 IFS = "X" echo "$ @" echo "$ *" beispielFunc "eins" "zwei" "drei"
Dieser Code erzeugt die folgende Ausgabe:
csaba @ csaba ~ $ ./parametersExamples.sh eins ./parametersExamples.sh eins zwei drei oneXtwoXthre
Analysieren wir die Quelle Zeile für Zeile.
$ @
. Es stellt alle Parameter als ein Wort dar, genau wie im Funktionsaufruf angegeben.$ *
. Es stellt alle Parameter einzeln dar und wird mit dem ersten Buchstaben der IFS-Variablen verkettet. Deshalb ist das Ergebnis oneXtwoXthre
.Wie bereits erwähnt, können Funktionen in Bash nur Ganzzahlen zurückgeben. Als solches schreiben Gib "eine Zeichenfolge" zurück
wäre ungültiger Code. In vielen Situationen benötigen Sie jedoch mehr als nur eine Null oder Eins. Wir können unser FizzBuzz-Beispiel so umgestalten, dass in der zum
Anweisung, machen wir einfach einen Funktionsaufruf.
#! / bin / bash Funktion isDivisibleBy return $ (($ 1% $ 2)) Funktion fizzOrBuzz wenn isDivisibleBy $ 1 3; dann output = "Fizz" fi wenn isDivisibleBy $ 1 5; dann output = "$ output Buzz" fi wenn [-z $ output]; dann echo $ 1 sonst echo $ ausgabe; fi für die Nummer in 1… 100; fizzOrBuzz $ number erledigt
Nun, das ist der erste Schritt. Wir haben einfach den gesamten Code in eine Funktion extrahiert, genannt fizzOrBuzz
, und dann ersetzt $ number
mit 1 US-Dollar
. Die gesamte Ausgabe erfolgt jedoch im fizzOrBuzz
Funktion. Wir möchten aus dem ausgeben zum
Schleife mit einem Echo
Anweisung, damit wir jeder Zeile einen anderen String voranstellen können. Wir müssen das erfassen fizzOrBuzz
Funktionsausgabe.
# […] Für Nummer in 1… 100; do echo "-'fizzOrBuzz $ number" "fizzBuzzer = $ (fizzOrBuzz $ number) echo" - $ fizzBuzzer "fertig
Wir haben unsere aktualisiert zum
Nur ein wenig schleifen (keine anderen Änderungen). Wir haben jetzt alles zweimal auf zwei verschiedene Arten wiederholt, um die Unterschiede zwischen den beiden Lösungen für dasselbe Problem zu veranschaulichen.
Die erste Lösung zum Erfassen der Ausgabe einer Funktion oder eines anderen Befehls ist die Verwendung von Backticks. In 99% der Fälle wird dies gut funktionieren. Sie können eine Variable innerhalb von Backticks einfach anhand ihrer Namen referenzieren, wie wir es mit getan haben $ number
. Die ersten Zeilen der Ausgabe sollten jetzt so aussehen:
csaba @ csaba ~ / Personal / Programmieren / NetTuts / Grundlagen von BASH-Skripterstellung / Quellen $ ./fizzBuzz.sh -1 -1 -2 -2 -Fizz -Fizz -4 -4 -Buzz -Buzz -Fizz -Fizz -7 -7
Wie Sie sehen, ist alles doppelt vorhanden. Gleiche Ausgabe.
Für die zweite Lösung haben wir uns entschieden, den Rückgabewert zuerst einer Variablen zuzuweisen. In dieser Aufgabe haben wir verwendet $ ()
, In diesem Fall fälscht das Skript das Skript, führt den Code aus und gibt seine Ausgabe zurück.
Erinnerst du dich, dass wir hier und da Semikolon verwendet haben? Sie können verwendet werden, um mehrere Befehle auszuführen, die in derselben Zeile geschrieben sind. Wenn Sie sie durch Semikolons voneinander trennen, werden sie einfach ausgeführt.
Ein komplexerer Fall ist zu verwenden &&
zwischen zwei Befehlen. Ja, das ist ein logisches UND. Dies bedeutet, dass der zweite Befehl nur ausgeführt wird, wenn der erste Befehl zurückkehrt wahr
(es endet mit 0). Das ist hilfreich. wir können das vereinfachen ob
Anweisungen in diesen Abkürzungen:
#! / bin / bash-Funktion isDivisibleBy return $ (($ 1% $ 2)) Funktion fizzOrBuzz isDivisibleBy $ 1 3 && output = "Fizz" isDivisibleBy $ 1 5 && output = "$ output Buzz", wenn [-z $ ausgeben ]; dann echo $ 1 sonst echo $ ausgabe; fi für die Nummer in 1… 100; mache echo "-'fizzOrBuzz $ number" "fertig
Als unsere Funktion, isDivisibleBy
gibt einen korrekten Rückgabewert zurück, den wir dann verwenden können &&
um die gewünschte Variable einzustellen. Was ist danach? &&
wird nur ausgeführt, wenn die Bedingung erfüllt ist wahr
. In gleicher Weise können wir verwenden ||
(Double Pipe-Zeichen) als logisches ODER. Hier ist ein kurzes Beispiel.
csaba @ csaba ~ $ echo "bubu" || echo "bibi" bubu csaba @ csaba ~ $ echo false || echo "bibi" false csaba @ csaba ~ $
Das macht es also für dieses Tutorial! Ich hoffe, dass Sie eine Handvoll neuer Tipps und Techniken für das Schreiben Ihrer eigenen Bash-Skripts erhalten haben. Vielen Dank für das Lesen und bleiben Sie dran für weiterführende Artikel zu diesem Thema.