Ich versuche, eine Funktion zu erstellen, und glaube, ich habe ein gut funktionierendes Beispiel gefunden, aber ich verstehe nicht die gesamte Logik dahinter.
Konkreter: Könnte mir jemand erklären, was Test in der „while“-Zeile ist und macht? Was ist $# (ist # nicht ein Kommentarzeichen?) und woher kommt der Parameter -gt 0? Ich konnte ihn auf der Manpage von „while“ nicht finden.
Hier ist das Beispiel:
function my_function()
{
while test $# -gt 0
do
$
echo "$1"
shift
done
}
Danke schön.
Antwort1
Während #
es für sich allein genommen definitiv ein Kommentar ist, $#
enthält es die Anzahl der an Ihre Funktion übergebenen Parameter.
test
ist ein Programm, mit dem Sie verschiedene Tests durchführen können, z. B. ob eine Zahl größer als eine andere Zahl ist (wenn Ihr Operator ist -gt
; es gibt viele andere Operatoren, siehe man test
). Es gibt Erfolg zurück, wenn der Test erfolgreich ist (in diesem Fall, wenn the number of parameters
größer als 0 ist).
Der shift
Befehl wirft den ersten Parameter weg. Außerdem verringert er$#
Der Code als Ganzes kann wie folgt betrachtet werden: Machen Sie etwas mit einem Parameter (in diesem Fall, indem Sie ihn auf dem Bildschirm anzeigen), verwerfen Sie ihn dann und wiederholen Sie dies, bis keine Parameter mehr übrig sind.
Wenn Sie alle verbleibenden Parameter sehen möchten, die für das Debuggen nützlich sind, überprüfen Sie den Inhalt von$@
Antwort2
$#
==> Skriptparameter übergeben
test
==> Befehl zur Bedingungsauswertung
-gt
==> steht fürgrößer als
test a -gt b
==> wahr, wenn a größer als b ist, andernfalls falsch
Alles zusammen:
while test $# -gt 0
==> während mehr Parameter übergeben werden (der Grund für die Änderung ist die Verschiebung)
Was die Sache knifflig macht, liegt shift
im Hauptteil der While-Schleife.
$1
==> stellt immer den ersten Parameter dar
Um dies konkreter zu machen, nehmen wir an, Sie übergeben die Parameter a
und .b
c
$1
==> stellt dar a
, dass dies Ihr erster Parameter ist
durch den Aufruf von jetzt shift
ist a
weg und Ihre Parameterliste ist jetzt b
und c
daher $1
ist es, wenn Sie jetzt aufrufen b
, da dies jetzt der erste Parameter in der Liste ist. Wenn Sie shift
noch einmal aufrufen, ist Ihre Parameterliste jetzt nur c
, daher $1
ist jetzt c
. shift
Ein weiterer Aufruf lässt die Parameterliste leer, daher wird die while-Bedingung nicht erfüllt (da die Parameterliste nicht mehr größer als 0 ist, da sie jetzt die Größe Null hat), was dazu führt, dass die while-Schleife beendet wird.
Welche Vorteile bietet die Verwendung shift
und Bezugnahme auf den aktuellen Parameter als $1
?
Es gibt Ihnen die Flexibilität, in Ihrem Skript nicht im Voraus zu wissen, wie viele Parameter im Skript übergeben werden, und diese trotzdem einzeln zu durchlaufen, wobei Sie innerhalb der while-Schleife immer auf den aktuellen Parameter verweisen, da $1
dies den Kopf der Parameterliste bedeutet. Durch shift
ing wird die Parameterliste schließlich leer sein, daher ist es wichtig, die while-Bedingung zu haben, um zu prüfen, ob sie größer als Null ist, um zu beenden und nicht in eine Endlosschleife zu geraten.
Antwort3
Führen Sie das folgende Skript aus, um zu verstehen, was die Variablen bedeuten. Speichern Sie das Skript unter somescript.sh
und rufen Sie es mit einigen Eingabeparametern auf.
#!/bin/bash
echo "I display the total parameters passed to this script from commandline"
echo $#
echo "I display all the parameter values"
echo "Input: $@"
echo "I display the first parameter value"
echo "$1"
shift
echo "After shift: $@"
Antwort4
Wenn Sie mir verzeihen, dass ich die Antworten etwas wiederverwende, ich denke, Sie könnten dies nützlich finden.
_fn() { set -- "$@" $(cat)
while ${1+:} false ; do
echo "$1" && [ "$1" = "arg2" ] && echo "$1"
$YOUR_CHK
shift
done
}
echo "arg2" | _fn "arg1"
AUSGABE
arg1
arg2
arg2
Dies verarbeitet sowohl Befehlszeilenargumente als auch stdin
. Es führt die while
Schleife nur aus, um sie zu überprüfen, während Sie noch mindestens ein Argument in Ihrem Parameterarray gespeichert haben. Es verwirft jedes überprüfte Argument, daher $YOUR_CHK
sollte ein Teil davon das Speichern von Informationen sein, die Sie auf die eine oder andere Weise für wertvoll halten.
_fn
würde sich genauso verhalten, wenn sein Inhalt der Hauptteil eines Skripts wäre oder in der Form einer Shell-Funktion vorliegen würde.
_fn
Griffe stdin
- in diesem Fall "arg2" echo
ed über die |pipe
- in der ersten Zeile durch set
ting seines Positionsparameter-Shell- $@
Arrays auf alles, was auf der Kommandozeile übergeben wird - oder "$@"
- UND alles cat
wird über ausgespuckt $(comand substitution)
.
while _fn's $1
Der erste Parameter ist, dass ${set+}
wir das eingebaute Shell-Element ersetzen, :true
um die while
Schleifenbedingung zu erfüllen. Sobald $1
nicht gesetzt ist, dass die Ersetzung fehlschlägt, wird die Bedingung ausgewertet false
und die while
Schleife wird abgebrochen.
Für jede Iteration der while
Schleife _fn() echo
wird der $1
erste Parameter &&
bei Erfolg ( echo
iststetserfolgreich), [ tests ]
um zu sehen, ob es $1
der Zeichenfolge entspricht "arg2"
&&
, wenn es erneut [ test ]
erfolgreich ist ._fn() echo
$1
$YOUR_CHK
ist ein Null-Op – es handelt sich um eine nicht gesetzte Variable, die nichts ergibt, bevor die Shell überhaupt Code ausführt.
Bei jeder Iteration der while
Schleife shift
entfernen wir den $1
ersten Parameter. Bei Iteration 1 "$@"
sieht das also so aus:
arg1 arg2
Aber nach shift
dem ersten Mal sieht es so aus:
arg2
Und nachdem wir shift
das letzte Mal dabei waren, sieht es so aus:
Damit kommen wir wieder zurück zu ${1+:} false
- da $1
nun nicht mehr gesetzt ist, wird die Shell nicht ersetzen :true
und stattdessen nur false
ausgewertet, was die while
Schleife unterbricht und die_fn().