GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bash Scripting – Funktionen mit Beispielen erklärt

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:

  1. Versuchen Sie, eine beliebige Syntax zu wählen und dabei konsistent zu sein.
  2. 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

Linux
  1. So schreiben Sie ein Bash-Skript mit Beispielen

  2. Bash-Funktionen

  3. Shell-Scripting Teil V:Funktionen in Bash

  4. Funktionen in Shell-Variablen?

  5. Bash-If-Else-Anweisung mit Beispielen

Tr-Befehl in Linux mit Beispielen erklärt

Bash-Scripting Teil 6 – Erstellen und Verwenden von Bash-Funktionen

Bash-Scripting Teil 2 – For- und While-Schleifen mit Beispielen

Bash Scripting Einführungstutorial mit 5 praktischen Beispielen

Tutorial zu Bash-Shell-Funktionen mit 6 praktischen Beispielen

Bash-Skript für Schleife mit Beispielen erklärt