Übergeben Sie Argumente so, dass sie genau so funktionieren, wie sie sind

10

Ich habe folgende Funktion:

bar() { echo $1:$2; }

Ich rufe diese Funktion von einer anderen Funktion auf foo. fooselbst heißt wie folgt:

foo "This is" a test

Ich möchte folgende Ausgabe erhalten:

This is:a

Das heißt, die Argumente, die barempfangen werden, sollten die gleichen Token sein, an die ich weitergebe foo.

Wie muss foodies umgesetzt werden? Ich habe die folgenden zwei Implementierungen ausprobiert, aber keine funktioniert:

  • foo() { bar $*; }

    - Ausgabe: this:is

  • foo() { bar "$*"; }

    - Ausgabe: this is a test:

Meine Frage ist effektiv, wie ich das Zitieren von Argumenten bewahren kann. Ist das überhaupt möglich?

Konrad Rudolph
quelle

Antworten:

13

Verwendung "$@":

$ bar() { echo "$1:$2"; }
$ foo() { bar "$@"; }
$ foo "This is" a test
This is:a

"$@"und "$*"haben besondere Bedeutungen:

  • "$@"wird auf mehrere Wörter erweitert, ohne Erweiterungen für die Wörter (wie "$1" "$2" ...) durchzuführen .
  • "$*" Verbindet Positionsparameter mit dem ersten Zeichen in IFS (oder Leerzeichen, wenn IFS nicht gesetzt ist, oder nichts, wenn IFS leer ist).
Lri
quelle
Danke, mir war nicht bewusst, dass $*diese Semantik vorhanden war - jetzt ist es logisch. Ich denke, diese Antwort löst tatsächlich ein anderes Problem, das ich beim Durchlaufen von Arrays hatte ...
Konrad Rudolph
6

Sie müssen $@anstelle von verwenden$*

bar() { echo "$1:$2"; }

foo() { bar "$@"; }

foo "This is" a test

Ausgabe

This is:a

Warum funktioniert es?

Da mit $*alle Parameter als ein einzelnes Wort betrachtet werden , bedeutet dies, dass Sie This is a testzur barFunktion übergehen . In diesem Fall ist der erste Parameter, der an die Funktionsleiste übergeben wird This, der zweite is.

Mit $@jedem Parameter ist ein String in Anführungszeichen , bedeutet es , dass Sie passieren 'This is' 'a' 'test'zu barfuntion. Der erste Parameterübergang zur Funktionsleiste ist also der This iszweite a.

cuonglm
quelle