Bei der Bash-Shell-Skripterstellung sind Funktionen Möglichkeiten, den Satz von Anweisungen zu gruppieren, um ein bestimmtes Ergebnis zu erzielen. Sie können sich Funktionen wie ein Miniskript vorstellen. Funktionen werden in einigen Programmiersprachen auch Prozeduren und Methoden genannt. Funktionen sind eine großartige Möglichkeit, Modularität und Wiederverwendbarkeit zu erreichen.
In diesem Artikel werde ich anhand von Beispielen erklären, wie Sie Funktionen in Bash-Skripten unter Linux verwenden. Am Ende dieses Artikels werden Sie mit der Verwendung von Bash-Funktionen ziemlich vertraut sein.
Wie man Funktionen in Bash definiert
Es gibt zwei wichtige Dinge, die Sie verstehen müssen, wenn Sie mit Funktionen arbeiten.
- Funktion definieren,
- Aufruf der Funktion.
Ähnlich wie Sie Bash-Skripte erstellen und ausführen, sollten Sie die Funktion definieren und aufrufen, damit die Funktion ausgeführt wird.
Es gibt zwei syntaktische Möglichkeiten, eine Funktion in Bash zu definieren. Die erste Möglichkeit besteht darin, das in Bash integrierte Schlüsselwort "function"
zu verwenden gefolgt vom Namen der Funktion. Der Codeblock wird in geschweifte Klammern {}
geschrieben .
function [name] {
Block of code
}
Die zweite Möglichkeit besteht darin, eine Funktion ohne das Schlüsselwort "function"
zu erstellen . Beginnen Sie mit dem Funktionsnamen gefolgt von Klammern.
[name](){
Block of Code
}
Welche soll man wählen? Nun, es ist immer eine persönliche Entscheidung. Die Wahl eines gegenüber dem anderen hat keine Nachteile.
Sie können auch einzeilige Funktionen schreiben, die als kompakte Funktionen bezeichnet werden . In kompakten Funktionen wird jede Codezeile innerhalb der geschweiften Klammern durch ein Semikolon (;
getrennt ) .
Starten Sie Ihr Terminal und schreiben Sie eine mehrzeilige Funktion. Drücken Sie nun die Pfeiltaste nach oben und Sie werden sehen, was Sie mehrzeilig geschrieben haben, wird in kompakte Funktionen umgewandelt.
[name](){ first_line; second_line; }
BEWÄHRTE VERFAHREN:
- Versuchen Sie, eine beliebige Syntax zu wählen und dabei konsistent zu sein.
- Wenn Sie in einer kollaborativen Umgebung arbeiten, ist es wichtig, dass alle beim Programmieren denselben Standard beibehalten.
Namenskonvention
Wenn Sie eine Funktion erstellen, müssen Sie Ihrer Funktion einen Namen geben. Der Funktionsname sollte aussagekräftig sein und versuchen, Namen zu vermeiden, die bereits von anderen Funktionen, Variablen, Konstanten usw. verwendet werden. "Snake Case" ist die bevorzugte Art, die Funktion zu benennen. Im Schlangenfall werden die Wörter durch Unterstriche getrennt.
Schauen Sie sich das folgende Beispiel an. Ich habe eine Funktion namens "hello_world"
im Snake-Case-Stil, der einfach Hallo Welt auf stdout (Terminal) ausgibt.
hello_world() { echo "Running Simple Hello World Function" } hello_world
Wie man eine Funktion in Bash aufruft
Lassen Sie uns eine einfache Bereinigungsfunktion namens "log_cleanup"
erstellen . Der Zweck dieser Funktion ist das Entfernen von ".log"
Dateien, die älter als 30 Tage sind.
log_cleanup(){ echo "Running Cleanup On Older Logs - 30 days" find /home/karthick/Documents/Projects/logs/ -name "*.log" -type f -mtime +30 -delete echo "Cleanup Completed" }
Die Funktion ist definiert, aber reicht das aus, damit die Funktion ihre Aufgabe erfüllt? Absolut nicht. Sie müssen die Funktion aufrufen, damit die Funktion ausgeführt werden kann.
Um die Funktion aufzurufen, geben Sie einfach den Funktionsnamen nach der Funktionsdefinition ein:
#!/usr/bin/env bash #### FUNCTION DEFINITION #### log_cleanup(){ echo "Running Cleanup On Older Logs - 30 days" find /home/karthick/Documents/Projects/logs -name "*.log" -type f -mtime +30 -delete echo "Cleanup Completed" } # Calling the function log_cleanup
Wenn Sie versuchen, die Funktion vor der Funktionsdefinition aufzurufen, erhalten Sie die folgende Fehlermeldung.
line 3: log_cleanup: command not found
Warum so? Wenn Sie das Skript ausführen, wird der Code Zeile für Zeile von oben nach unten interpretiert. Es liest die Funktion und lädt sie in die Bash-Umgebung (Speicher). Aber hier rufen Sie die Funktion auf, bevor der Interpreter die Funktion überhaupt liest und in seine Umgebung lädt.
Wenn Sie eine Funktion innerhalb einer anderen Funktion aufrufen, kann Ihre Funktionsdefinition außer der ersten Funktion in beliebiger Reihenfolge sein. Schauen Sie sich das folgende Bild an. Funktion func2 wird von func1 aufgerufen und func3 wird von func2 aufgerufen vor ihrer Definition. Aber funktion1 wird zuerst definiert und dann aufgerufen. Zum Zeitpunkt func1 heißt alle Funktionsdefinitionen sind bereits Interpretiert und in die Umgebung geladen.
Ausgangsstatus &Rückgabewert
Jeder Linux-Befehl gibt einen Exit-Status (0-255) zurück. Null soll erfolgreich sein und der Rest der Exit-Codes soll Fehler mit unterschiedlichen Bedeutungen sein. In ähnlicher Weise wird beim Ausführen einer Funktion auch ein Exit-Status des letzten Ausführungsbefehls in der Funktion zurückgegeben.
Lassen Sie mich dieselbe "Aufräum"-Funktion noch einmal ausführen. Aber ich habe einen Pfad angegeben, der auf meiner Maschine nicht verfügbar ist, also find
Befehl wird fehlschlagen. Ich verwende $?
um den Exit-Status innerhalb des Skripts zu erhalten, wie im Bild gezeigt.
Running Cleanup On Older Logs - 30 days find: '/home/karthick/Documents/Projectss/logs': No such file or directory Cleanup Completed Exit status of function log_cleanup is ⇒ 0
Der von der Funktion zurückgegebene Exit-Status stammt von echo
Befehl, der als letzter Befehl innerhalb der Funktion ausgeführt wurde. Dies ist nicht das erwartete Verhalten.
Um dieses Verhalten zu umgehen, können Sie das in Bash eingebaute "return"
verwenden Aussage.
$ type -a return
return is a shell builtin
Return akzeptiert einen ganzzahligen [N]-Wert und beendet die Funktionen und gibt den Rückgabewert an seinen Aufrufer (Funktion). Bevor Sie die return-Anweisung verwenden, müssen Sie einige Regeln zur Verwendung der return-Anweisung verstehen. Wie bereits erwähnt, akzeptiert return ganzzahlige Werte von 0-255. Eine return-Anweisung verwendet den Exit-Status des zuletzt ausgeführten Befehls, wenn kein Argument (Ganzzahlwert) übergeben wird oder der Wert 255 überschreitet.
Lassen Sie mich die Rückgabe verwenden, um die "cleanup"
zu beheben Funktionsverhalten. Hier verwende ich bedingte Anweisungen zusammen mit dem Return-Befehl.
#!/usr/bin/env bash #### FUNCTION DEFINITION #### log_cleanup(){ echo "[ INFO ] - Running Cleanup On Older Logs - 30 days" if [[ -d "/home/karthick/Documents/Projectss/logs" ]] then find -name "*.log" -type f -mtime +30 -delete echo "[ SUCCESS] - Cleanup Completed" else echo "[ ERROR ] - Directory path wrong... Cleanup has not happened..." return 1 fi } # Calling the function log_cleanup echo "++ Exit status of log_cleanup function is ==> $?"
Sehen Sie sich die Ausgabe unten an. Die Funktion gibt Exit-Code 1 zurück aus der return-Anweisung.
[ INFO ] - Running Cleanup On Older Logs - 30 days
[ ERROR ] - Directory path wrong… Cleanup has not happened…
++ Exit status of log_cleanup function is ==> 1
Argumente an eine Funktion übergeben
Ähnlich wie beim Übergeben von Argumenten an Ihre Bash-Skripte akzeptieren auch Funktionen Argumente. Der verwirrende Teil ist, dass Funktionen denselben $1
verwenden …$9
spezielle Variablen für den Zugriff auf Argumente, was der Übergabe des Arguments an das Skript entspricht. Sie müssen verstehen, was passiert, wenn Sie diese spezielle Variable innerhalb und außerhalb der Funktion verwenden.
cat > arg_test.sh #!/bin/bash echo "Value passed in \$1 is = $1" howdy(){ echo "value of \$1 inside function is = $1" } howdy # Function Call
Kopieren Sie das obige Snippet und führen Sie es aus, um den Unterschied zu sehen. Die Zeichenfolge "Howdy"
wird als erstes Argument an das Skript übergeben.
$ ./arg_test.sh howdy
Value passed in $1 is = howdy
value of $1 inside function is =
In der Ausgabe sehen Sie $1
Innerhalb der Funktion wird ein leerer Wert ausgegeben, weil $1
innerhalb der Funktion unterscheidet sich von $1
außerhalb der Funktion, obwohl sie denselben Namen haben.
Um Argumente an die Funktion zu übergeben, lassen Sie nach dem Funktionsnamen ein Leerzeichen und übergeben Sie Ihre Argumente wie im folgenden Bild gezeigt. Jedem durch Leerzeichen getrennten Argument wird die entsprechende Variable $1
zugewiesen …$N
und Sie können diese Variable innerhalb der Funktion verwenden, um die Argumente zu verarbeiten.
log_cleanup $1 $2 ….. $N
Wie Sie im obigen Screenshot sehen, übergebe ich den Verzeichnisnamen und die Anzahl der Tage als Argumente.
Variabler Umfang für eine Funktion
Wenn Sie eine Variable innerhalb oder außerhalb der Funktion erstellen, kann global darauf zugegriffen werden. Standardmäßig werden Variablen im globalen Geltungsbereich erstellt.
Schauen Sie sich das folgende Beispiel an. Wenn Sie versuchen, auf die Variable outside_function
zuzugreifen und inside_function
, ihre Werte sind zugänglich. Das bedeutet, dass die innerhalb der Funktion erstellte Variable global zugänglich ist, obwohl die Funktion ausgeführt und beendet wurde.
#!/bin/bash outside_function="This variable is from outside the function" func1(){ inside_function="This variable is from inside the func1" } func1 echo $outside_function echo $inside_function
In einigen Programmiersprachen ist dies möglicherweise nicht das Verhalten und die innerhalb der Funktion erstellten Variablen sind während der Laufzeit der Funktion verfügbar. Aber in Bash ist das Verhalten anders.
Um Variablen lokal für die Funktion zu machen, können Sie das in Bash eingebaute "local"
verwenden Stichwort. Das Schlüsselwort local schränkt den Geltungsbereich der Variablen von global auf lokal ein und auf die Variable kann nur während der Laufzeit der Funktion zugegriffen werden.
#!/bin/bash outside_function="This variable is from outside the function" func1(){ local inside_function="This variable is from inside the func1" } func1 echo $outside_function echo $inside_function
Empfohlene Lektüre:
- Bash-Scripting – Variablen mit Beispielen erklärt
Wenn das Schlüsselwort local verwendet wird, können Sie dieselben Variablennamen in verschiedenen Funktionen verwenden.
Vorsicht: Sie sollten immer versuchen, die Verwendung von Bezeichnern zu vermeiden, die bereits als Variablen, Funktionen oder Bash-Schlüsselwörter verwendet werden. Das obige Beispiel wird nur gezeigt, um das Verhalten zu verstehen.
Modularität und Resubaility
Verstehen und Schreiben von Funktionen können in kürzester Zeit durchgeführt werden. Aber das Schreiben guter Funktionen braucht Zeit mit einem besseren Verständnis der Umgebung. Wie bereits im Einführungsabschnitt erwähnt, können Sie mit Bash-Funktionen ein hohes Maß an Modularität und Wiederverwendbarkeit erreichen.
Nehmen wir ein Beispiel. Sie haben 20 Skripte erstellt und in jedem Skript den log_cleanup
eingefügt Funktion, die wir in den vorherigen Abschnitten gesehen haben, um Haushaltsaufgaben durchzuführen. Anstatt diese Funktion in alle 20 Skripte aufzunehmen, können Sie eine einzige Funktionsdefinition erstellen und sie in 20 Skripte importieren. So erreichen Sie Modularität sowie wiederverwendbare Funktionen. Dies ähnelt dem Importieren Anweisungen in Python, include Anweisungen in C usw.
Schauen Sie sich das folgende Bild an. Ich habe zwei Skripte mit dem Namen script1.sh
erstellt und script2.sh
und die log_cleanup
Funktion wird in eine separate Datei namens cleanup.sh
geschrieben .
Ich importiere die Funktion, indem ich source
ausführe Befehl. Die source
Der Befehl führt die als Argument übergebene Datei aus und lädt die Variable oder Funktionen in die aktuelle Bash-Sitzung. Auf diese Weise, wenn Sie log_cleanup
ausführen aus einer anderen Skriptdatei ist die Funktion bereits in die aktuelle Umgebung geladen und zugänglich.
Aus dem obigen Bild können Sie verstehen, wie hilfreich die Argumente sind. Es gibt nur eine Funktionsdefinition und je nach Anwendungsfall kann ich die Funktion ändern, um verschiedene Argumente und in verschiedenen Skripten zu akzeptieren.
Vorsicht: Sie können Ihre Shell-Skripte auch mit source
ausführen Befehl, der das Skript in der aktuellen Shell ausführt, anstatt eine Subshell zum Ausführen des Skripts zu erstellen.
Schlussfolgerung
In diesem Handbuch haben wir über Bash-Funktionen und das Definieren und Aufrufen einer Funktion in Skripten mit Beispielen gesprochen. Um sich mit Funktionen vertraut zu machen, müssen Sie die Funktionen mit verschiedenen Anwendungsfällen üben. Wenn Sie Fragen oder Feedback haben, können Sie uns dies gerne über den Kommentarbereich unten mitteilen.
Verwandte Lektüre:
- Bash-Skripting – For-Schleife mit Beispielen erklärt
- Bash-Skripting – While- und Until-Schleife mit Beispielen erklärt
- Unterschied zwischen der Definition von Bash-Variablen mit und ohne Export
- Bash-Echo-Befehl mit Beispielen in Linux erklärt
- Bash Heredoc-Tutorial für Anfänger
- Bash-Umleitung mit Beispielen erklärt