Przekaż argumenty, aby działały dokładnie tak, jak są

10

Mam następującą funkcję:

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

Wołam tę funkcję z innej funkcji foo. foosam nazywa się w następujący sposób:

foo "This is" a test

Chcę uzyskać następujące dane wyjściowe:

This is:a

Oznacza to, że barotrzymywane argumenty powinny być tymi samymi tokenami, które przekazuję foo.

Jak foonależy to zrealizować? Próbowałem następujących dwóch implementacji, ale żadna nie działa:

  • foo() { bar $*; }

    - wynik: this:is

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

    - wynik: this is a test:

Moje pytanie brzmi, w jaki sposób mogę zachować cytowanie argumentów. Czy to w ogóle jest możliwe?

Konrad Rudolph
źródło

Odpowiedzi:

14

Użyj "$@":

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

"$@"i "$*"mają specjalne znaczenie:

  • "$@"rozwija się do wielu słów bez wykonywania rozszerzeń dla słów (jak "$1" "$2" ...).
  • "$*" łączy parametry pozycyjne z pierwszym znakiem w IFS (lub spacją, jeśli IFS jest rozbrojony lub nic, jeśli IFS jest pusty).
Lri
źródło
Dzięki, nie wiedziałem, że $*to miało semantyczne - teraz jest logiczne. Myślę, że ta odpowiedź faktycznie rozwiązuje inny problem, który miałem podczas iteracji po tablicach…
Konrad Rudolph
6

Musisz użyć $@zamiast$*

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

foo() { bar "$@"; }

foo "This is" a test

wyjście

This is:a

Dlaczego to działa?

Ponieważ z $*, cały parametr jest postrzegany jako pojedyncze słowo , oznacza to, że przejdziesz This is a testdo barfunkcji. W tym przypadku pierwszy parametr przekazywany do paska funkcji to This, drugi to is.

Z $@każdym parametrem jest ciąg cytowany , co oznacza, że ​​przejdziesz 'This is' 'a' 'test'do barfunkcji. Zatem pierwszy parametr przekazywany do paska funkcji to This is, drugi to a.

Cuonglm
źródło