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

Hinzufügen von Argumenten und Optionen zu Ihren Bash-Skripten

Eines der wichtigsten Tools für die meisten Systemadministratoren ist die Automatisierung. Wir schreiben und pflegen Skripte, um die üblichen und häufigen Aufgaben zu automatisieren, die wir ausführen müssen.

Ich habe Dutzende von kurzen und langen Drehbüchern, die ich im Laufe der Jahre geschrieben und modifiziert habe. Einige meiner nützlichsten Skripte waren die Durchführung regelmäßiger Sicherungen jeden Morgens, die Installation aktualisierter Softwarepakete mit Korrekturen und Verbesserungen und das Upgrade von einer Version von Fedora auf die nächste. Ich habe vor ein paar Tagen alle meine persönlichen Hosts und Server mit einem ziemlich einfachen Skript auf Fedora 34 aktualisiert.

[ Das könnte Ihnen auch gefallen: Weitere dumme Bash-Tricks:Variablen, Suchen, Dateideskriptoren und Remote-Operationen]

Zwei der häufigsten Dinge, die ich für alle meine Skripte mache, sind das Erstellen einer Hilfefunktion und einer Funktion, die die GPL3-Lizenzerklärung anzeigt. Ich füge gerne ausführliche oder Testmodi hinzu, um bei der Problembestimmung in meinen Skripten zu helfen. In einigen Skripten übergebe ich auch Werte wie einen Benutzernamen, die Version von Fedora, auf die aktualisiert werden soll, Dateinamen und mehr.

Die Fähigkeit, Positionsparameter – auch bekannt als Argumente – zu verwenden, um Daten anzugeben, die als Werte für Variablen in den Skripten verwendet werden sollen, ist eine Methode, um dies zu erreichen. Ein weiterer Grund ist die Verwendung von Optionen und Optionsargumenten. Dieser Artikel untersucht diese beiden Methoden, um Daten in das Skript zu bekommen und den Ausführungspfad des Skripts zu steuern.

Positionsparameter

Bash verwendet ein Tool namens Positionsparameter, um Daten in ein Bash-Programm einzugeben, wenn es über die Befehlszeile aufgerufen wird. Es gibt zehn Positionsparameter, die von $0 ausgehen bis $9 , obwohl es Möglichkeiten gibt, dieses Limit zu umgehen.

Beginnend mit einem einfachen Skript, das einen eingegebenen Namen auf dem Bildschirm anzeigt. Erstellen Sie eine Datei namens script1.sh mit folgendem Inhalt und ausführbar machen.

#!/bin/bash
echo $0

Ich habe dieses Skript in meinem ~/bin directory abgelegt , wo persönliche ausführbare Dateien wie Skripte gespeichert werden sollen. Sehen Sie sich Ihren $PATH an Variable, die /home/username/bin enthält als eine Komponente. Wenn der ~/bin Verzeichnis nicht existiert, können Sie es erstellen. Oder Sie können diese Datei einfach an einer beliebigen Stelle ablegen und von dort aus verwenden.

Führen Sie dann das Skript ohne Parameter aus.

[student@testvm1 ~]$ script1.sh
/home/dboth/bin/script1.sh
[student@testvm1 ~]$

Die Ausgabe dieses Skripts ist der Name des Skripts. Die $0 Der Parameter ist reserviert und als Name des ausgeführten Skripts vordefiniert und kann nicht für andere Zwecke verwendet werden. Dies kann innerhalb eines Skripts praktisch sein, da Sie dem Skript nicht seinen eigenen Namen übergeben müssen, wenn es dies erfordert.

Ändern Sie also das Skript so, dass es $1 verwendet für die Positionsvariable und führen Sie sie erneut aus:

#!/bin/bash
echo $1

Führen Sie es erneut aus, diesmal mit einem einzigen Parameter:

[student@testvm1 ~]$ script1.sh help
help
[student@testvm1 ~]$

Was passiert, wenn der Parameter aus zwei Wörtern besteht?

[student@testvm1 ~]$ script1.sh help me
help
[student@testvm1 ~]$

Das sind eigentlich zwei Parameter, aber Sie können das mit Anführungszeichen beheben, wie hier zu sehen:

[student@testvm1 ~]$ script1.sh "help me"
help me
[student@testvm1 ~]$

Dies kann hilfreich sein, wenn die Eingabe eine Straßenadresse oder etwas mit mehreren Wörtern sein soll, wie hier:

[student@testvm1 ~]$ script1.sh "80486 Intel St."
80486 Intel St.
[student@testvm1 ~]$

Manchmal benötigen Sie jedoch mehrere Parameter, z. B. mit Namen oder vollständigen Adressen.

Ändern Sie das Programm so, dass es wie folgt aussieht:

#!/bin/bash
echo "Name: $1"
echo "Street: $2"
echo "City: $3"
echo "State/Province/Territory: $4"
echo "Zip/Postal code: $5"

Und führen Sie es mit den Parametern wie gezeigt aus:

[student@testvm1 ~]$ script1.sh "David Both" "80486 Intel St." Raleigh NC XXXXX
Name: David Both
Street: 80486 Intel St.
City: Raleigh
State/Province/Territory: NC
Zip/Postal code: XXXXX

Natürlich gibt es viele Möglichkeiten, die Positionsparameter zu verwenden, nachdem Werte zugewiesen wurden, aber dieses kleine Programm macht es einfach zu sehen, was passiert. Es macht es auch einfach, auf sichere Weise zu experimentieren.

Versuchen Sie, die Parameter in eine andere Reihenfolge zu bringen, um zu sehen, wie das funktioniert. Diese Parameter sind positionell, und das ist eine wichtige Überlegung. Sie müssen berücksichtigen, wie viele Parameter benötigt werden, wie sich der Benutzer an sie erinnert und in welcher Reihenfolge sie platziert werden.

Sie brauchen eine Möglichkeit, die Reihenfolge der Parameter irrelevant zu machen und dennoch den Ausführungspfad zu ändern.

Optionen

Sie können diese beiden Dinge mit Befehlszeilenoptionen tun.

Ich finde, dass selbst einfache Bash-Programme eine Art Hilfsfunktion haben sollten, auch wenn sie ziemlich rudimentär ist. Viele der Bash-Shell-Programme, die ich schreibe, werden so selten verwendet, dass ich möglicherweise die genaue Syntax des Befehls vergesse, den ich ausgeben muss. Einige sind einfach so komplex, dass ich die erforderlichen Optionen und Argumente überprüfen muss, obwohl ich sie häufig verwende.

Mit einer integrierten Hilfefunktion können Sie diese Dinge anzeigen, ohne den Code selbst untersuchen zu müssen. Eine gute und vollständige Hilfefunktion ist auch ein Teil der Programmdokumentation.

Über Funktionen

Shell-Funktionen sind Listen von Bash-Programmanweisungen, die in der Umgebung der Shell gespeichert sind und wie jeder andere Befehl ausgeführt werden können, indem Sie ihren Namen in der Befehlszeile eingeben. Shell-Funktionen können auch als Prozeduren oder Subroutinen bezeichnet werden, je nachdem, welche andere Programmiersprache Sie verwenden.

Funktionen werden in Ihren Skripts oder über die Befehlszeile mithilfe ihrer Namen aufgerufen, genau wie bei jedem anderen Befehl. In einem CLI-Programm oder einem Skript werden die Befehle in der Funktion beim Aufruf ausgeführt. Dann kehrt die Abfolge des Programmablaufs zur aufrufenden Entität zurück, und die nächste Reihe von Programmanweisungen in dieser Entität wird ausgeführt.

Die Syntax einer Funktion ist:

Funktionsname(){Programmanweisungen}

Erstellen Sie eine einfache Funktion in der CLI. Die Funktion wird in der Shell-Umgebung für die Shell-Instanz gespeichert, in der sie erstellt wird. Sie werden eine Funktion namens hw erstellen , was für Hallo Welt steht . Geben Sie den folgenden Code an der CLI ein und drücken Sie Enter . Geben Sie dann hw ein wie Sie es mit jedem anderen Shell-Befehl tun würden.

[student@testvm1 ~]$ hw(){ echo "Hi there kiddo"; }
[student@testvm1 ~]$ hw
Hi there kiddo
[student@testvm1 ~]$

Ok, ich bin ein bisschen müde von dem Standard "Hallo Welt!" Ich beginne normalerweise mit. Listen Sie nun alle aktuell definierten Funktionen auf. Es gibt viele davon, also habe ich nur das neue hw gezeigt Funktion. Wenn sie von der Befehlszeile oder innerhalb eines Programms aufgerufen wird, führt eine Funktion ihre programmierte Aufgabe aus. Es wird dann beendet und gibt die Kontrolle an die aufrufende Entität, die Befehlszeile oder die nächste Bash-Programmanweisung in einem Skript nach der aufrufenden Anweisung zurück.

[student@testvm1 ~]$ declare -f | less
<snip>
hw ()
{
    echo "Hi there kiddo"
}
<snip>

Entfernen Sie diese Funktion jetzt, da Sie sie nicht mehr benötigen. Das geht mit unset Befehl, etwa so:

[student@testvm1 ~]$ unset -f hw ; hw
bash: hw: command not found
[student@testvm1 ~]$

Das hello.sh-Skript

Erstellen Sie ein neues Bash-Shell-Skript, ~/bin/hello.sh , und machen Sie es ausführbar. Fügen Sie den folgenden Inhalt hinzu und halten Sie ihn für den Anfang einfach:

#!/bin/bash
echo "hello world!"

Führen Sie es aus, um zu überprüfen, ob es "hello world!" ausgibt.

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$

Ich weiß – ich kann mir nicht helfen, also bin ich zurück zu „Hallo Welt!“ gegangen.

Erstellen der Hilfefunktion

Fügen Sie die Hilfe hinzu unten gezeigte Funktion zum Code des Hello-Programms. Platzieren Sie die Hilfe Funktion zwischen den beiden Anweisungen, die Sie bereits haben. Diese Hilfe Die Funktion zeigt eine kurze Beschreibung des Programms, ein Syntaxdiagramm und eine kurze Beschreibung jeder verfügbaren Option an. Sie fügen auch einen Aufruf zur Hilfe hinzu Funktion zum Testen und einige Kommentarzeilen, die eine visuelle Abgrenzung zwischen den Funktionen und dem Hauptteil des Programms bieten.

Das Programm sieht jetzt so aus.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################

Help
echo "Hello world!"

Die in dieser Hilfe beschriebenen Optionen Funktion könnte typisch für die Programme sein, die ich schreibe, obwohl noch keine im Code vorhanden sind. Führen Sie das Programm aus, um es zu testen.

[student@testvm1 ~]$ hello.sh
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

Hello world!
[student@testvm1 ~]$

Da Sie keine Logik hinzugefügt haben, um die Hilfe bei Bedarf anzuzeigen, zeigt das Programm die Hilfe immer an. Sie wissen jedoch, dass die Funktion korrekt funktioniert, also können Sie etwas Logik hinzufügen, um nur die Hilfe anzuzeigen, wenn Sie ein -h verwenden Option beim Befehlszeilenaufruf des Programms.

Handhabungsoptionen

Die Fähigkeit eines Bash-Skripts, Befehlszeilenoptionen wie -h zu verarbeiten Hilfe anzuzeigen gibt Ihnen einige mächtige Möglichkeiten, das Programm zu lenken und zu modifizieren, was es tut. Im Fall Ihres -h Option möchten Sie, dass das Programm den Hilfetext in der Terminalsitzung ausgibt und dann beendet wird, ohne den Rest des Programms auszuführen. Die Fähigkeit, an der Befehlszeile eingegebene Optionen zu verarbeiten, kann dem Bash-Skript mithilfe von while hinzugefügt werden Befehl in Verbindung mit getops und case Befehle.

Die getops Der Befehl liest alle in der Befehlszeile angegebenen Optionen und erstellt eine Liste dieser Optionen. Das while Der Befehl durchläuft die Liste der Optionen, indem er die Variable $options setzt für jeden im Code unten. Der case -Anweisung wird verwendet, um nacheinander jede Option auszuwerten und die Anweisungen in der entsprechenden Strophe auszuführen. Das while Die Anweisung wertet die Liste der Optionen weiter aus, bis sie alle verarbeitet wurden oder eine Exit-Anweisung auftritt, die das Programm beendet.

Achten Sie darauf, die Hilfe zu löschen Funktionsaufruf kurz vor dem Echo "Hallo Welt!" -Anweisung, sodass der Hauptteil des Programms jetzt so aussieht.

############################################################
############################################################
# Main program                                             #
############################################################
############################################################
############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
   esac
done

echo "Hello world!"

Beachten Sie das doppelte Semikolon am Ende der Exit-Anweisung in der case-Option für -h . Dies ist für jede Option erforderlich. Fügen Sie dieser Case-Anweisung hinzu, um das Ende jeder Option abzugrenzen.

Das Testen ist jetzt etwas komplexer. Sie müssen Ihr Programm mit mehreren verschiedenen Optionen – und ohne Optionen – testen, um zu sehen, wie es reagiert. Stellen Sie zunächst sicher, dass ohne Optionen "Hello world!" wie es sein sollte.

[student@testvm1 ~]$ hello.sh
Hello world!

Das funktioniert, also testen Sie jetzt die Logik, die den Hilfetext anzeigt.

[student@testvm1 ~]$ hello.sh -h
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|t|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

Das funktioniert wie erwartet. Probieren Sie jetzt einige Tests aus, um zu sehen, was passiert, wenn Sie einige unerwartete Optionen eingeben.

[student@testvm1 ~]$ hello.sh -x
Hello world!
[student@testvm1 ~]$ hello.sh -q
Hello world!
[student@testvm1 ~]$ hello.sh -lkjsahdf
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|t|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

[student@testvm1 ~]$

Umgang mit ungültigen Optionen

Das Programm ignoriert einfach die Optionen, für die Sie keine spezifischen Antworten erstellt haben, ohne Fehler zu generieren. Obwohl im letzten Eintrag mit dem -lkjsahdf Optionen, weil es ein "h" in der Liste gibt, hat das Programm es erkannt und den Hilfetext ausgegeben. Tests haben gezeigt, dass eine Sache fehlt, ist die Fähigkeit, mit falschen Eingaben umzugehen und das Programm zu beenden, wenn eine erkannt wird.

Sie können der case-Anweisung eine weitere Case-Strophe hinzufügen, die mit jeder Option übereinstimmt, für die es keine explizite Übereinstimmung gibt. Dieser allgemeine Fall stimmt mit allem überein, für das Sie keine spezifische Übereinstimmung bereitgestellt haben. Der Fall Anweisung sieht jetzt so aus.

while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done

Dieses Stück Code verdient eine Erklärung, wie es funktioniert. Es scheint komplex zu sein, ist aber ziemlich einfach zu verstehen. Der während – fertig Die Struktur definiert eine Schleife, die einmal für jede Option in der getopts – Option ausgeführt wird Struktur. Das ":h" string – der die Anführungszeichen erfordert – listet die möglichen Eingabeoptionen auf, die vom case – esac ausgewertet werden Struktur. Jede aufgelistete Option muss eine entsprechende Strophe in der case-Anweisung haben. In diesem Fall sind es zwei. Eines ist das h) Strophe, die die Hilfeprozedur aufruft. Nach Abschluss der Hilfeprozedur kehrt die Ausführung zur nächsten Programmanweisung zurück, exit;; die das Programm verlässt, ohne weiteren Code auszuführen, selbst wenn einer vorhanden ist. Die Optionsverarbeitungsschleife wird ebenfalls beendet, sodass keine weiteren Optionen geprüft werden.

Beachten Sie den Catch-All-Match von \? als letzte Strophe in der Case-Anweisung. Wenn Optionen eingegeben werden, die nicht erkannt werden, gibt diese Zeile eine kurze Fehlermeldung aus und beendet das Programm.

Alle zusätzlichen Sonderfälle müssen dem abschließenden Auffangverfahren vorangehen. Ich ordne die Strophen für Fälle gerne in alphabetischer Reihenfolge an, aber es gibt Umstände, unter denen Sie sicherstellen möchten, dass ein bestimmter Fall vor bestimmten anderen bearbeitet wird. Die case-Anweisung ist sequenzsensitiv, seien Sie sich dessen also bewusst, wenn Sie Ihre erstellen.

Die letzte Anweisung jeder Strophe im case-Konstrukt muss mit dem doppelten Semikolon enden (;; ), die verwendet wird, um das Ende jeder Strophe explizit zu markieren. Dies erlaubt jenen Programmierern, die gerne explizite Semikolons für das Ende jeder Anweisung anstelle von impliziten verwenden, dies weiterhin für jede Anweisung innerhalb jeder Case-Strophe zu tun.

Testen Sie das Programm erneut mit den gleichen Optionen wie zuvor und sehen Sie, wie es jetzt funktioniert.

Das Bash-Skript sieht jetzt so aus.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################
############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done


echo "hello world!"

Testen Sie diese Version Ihres Programms unbedingt gründlich. Verwenden Sie zufällige Eingaben und sehen Sie, was passiert. Sie sollten auch versuchen, gültige und ungültige Optionen zu testen, ohne den Bindestrich zu verwenden (- ) vor.

Optionen zur Dateneingabe verwenden

Fügen Sie zuerst eine Variable hinzu und initialisieren Sie sie. Fügen Sie die beiden fett gedruckten Zeilen in das unten gezeigte Segment des Programms ein. Dadurch wird $Name initialisiert Variable auf "world" als Standard.

<snip>
############################################################
############################################################
# Main program                                             #
############################################################
############################################################

# Set variables
Name="world"

############################################################
# Process the input options. Add options as needed.        #
<snip>

Ändern Sie die letzte Zeile des Programms, das echo Befehl, dazu.

echo "hello $Name!"

Fügen Sie gleich die Logik zur Eingabe eines Namens hinzu, aber testen Sie das Programm zunächst erneut. Das Ergebnis sollte genau dasselbe sein wie zuvor.

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$
# Get the options
while getopts ":hn:" option; do
   case $option in
      h) # display Help
         Help
         exit;;
      n) # Enter a name
         Name=$OPTARG;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done

$OPTARG ist immer der Variablenname, der für jedes neue Optionsargument verwendet wird, egal wie viele es sind. Sie müssen den Wert in $OPTARG zuweisen zu einem Variablennamen, der im Rest des Programms verwendet wird. Diese neue Strophe hat keine Exit-Anweisung. Dadurch wird der Programmablauf so geändert, dass nach Verarbeitung aller gültigen Optionen in der case-Anweisung die Ausführung mit der nächsten Anweisung nach dem case-Konstrukt fortfährt.

Testen Sie das überarbeitete Programm.

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$ hello.sh -n LinuxGeek46
hello LinuxGeek46!
[dboth@david ~]$ hello.sh -n "David Both"
hello David Both!
[dboth@david ~]$

Das fertige Programm sieht so aus.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################

# Set variables
Name="world"

############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":hn:" option; do
   case $option in
      h) # display Help
         Help
         exit;;
      n) # Enter a name
         Name=$OPTARG;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done


echo "hello $Name!"

Testen Sie unbedingt die Hilfefunktion und wie das Programm auf ungültige Eingaben reagiert, um sicherzustellen, dass seine Fähigkeit, diese zu verarbeiten, nicht beeinträchtigt wurde. Wenn das alles so funktioniert, wie es sollte, dann haben Sie erfolgreich gelernt, Optionen und Optionsargumente zu verwenden.

[ Holen Sie sich dieses kostenlose E-Book:Verwalten Ihrer Kubernetes-Cluster für Dummies. ]

Abschluss

In diesem Artikel haben Sie Positionsparameter verwendet, um während des Aufrufs über die Befehlszeile Daten in das Bash-Programm einzugeben, und Sie haben Optionen verwendet, um den Programmfluss zu lenken und Daten in das Programm einzugeben. Sie haben eine Hilfefunktion und die Möglichkeit hinzugefügt, Befehlszeilenoptionen zu verarbeiten, um die Hilfe selektiv anzuzeigen. Und Sie haben ein optionales Argument hinzugefügt, das die Eingabe eines Namens in der Befehlszeile ermöglicht.

Dieses kleine Testprogramm ist einfach aufgebaut, so dass Sie leicht selbst damit experimentieren können, um diese Eingabemethode selbst zu testen. Überarbeiten Sie als Übung das Programm, um einen Vornamen und einen Nachnamen zu verwenden. Versuchen Sie, die Optionen für Vor- und Nachnamen in umgekehrter Reihenfolge einzugeben, um zu sehen, was passiert.

Ressourcen

  • Programmieren mit Bash:Syntax und Tools
  • Programmieren mit Bash:Logische Operatoren und Shell-Erweiterungen
  • Wie man mit Bash programmiert:Schleifen

Linux
  1. Wann soll in Bash ein Alias, wann ein Skript und wann eine Funktion geschrieben werden?

  2. Befehlszeilenargumente an Bash-Skript übergeben?

  3. Wie werden Parameter eingestellt, wenn Bash-Skript an Bash übergeben wird?

  4. Hinzufügen zu $PYTHONPATH mit Bash-Skript

  5. Unterschied zwischen Befehlen im Bash-Skript und Befehlen im Terminal

Bash-it – Bash-Framework zur Kontrolle Ihrer Skripte und Aliase

So debuggen Sie Bash-Skripte in Linux und Unix

Bash-Skripting – Analysieren Sie Argumente in Bash-Skripten mithilfe von getopts

Bash-Anfängerserie Nr. 1:Erstellen Sie Ihr erstes Bash-Shell-Skript und führen Sie es aus

Bash-Anfängerserie Nr. 3:Übergabe von Argumenten an Bash-Skripte

Pycharm- und sys.argv-Argumente