Passa gli argomenti per funzionare esattamente così come sono


10

Ho la seguente funzione:

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

Sto chiamando questa funzione da un'altra funzione foo,. foosi chiama come segue:

foo "This is" a test

Voglio ottenere il seguente output:

This is:a

Cioè, gli argomenti che barriceve dovrebbero essere gli stessi token in cui passo foo.

Come foodeve essere implementato per raggiungere questo obiettivo? Ho provato le seguenti due implementazioni, ma nessuna delle due funziona:

  • foo() { bar $*; }

    - produzione: this:is

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

    - produzione: this is a test:

La mia domanda è effettivamente come posso preservare la citazione degli argomenti. Ciò è effettivamente possibile?


Risposte:


14

Utilizzare "$@":

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

"$@"e "$*"hanno significati speciali:

  • "$@"si espande in più parole senza eseguire espansioni per le parole (come "$1" "$2" ...).
  • "$*" unisce i parametri posizionali con il primo carattere in IFS (o lo spazio se IFS non è impostato o nulla se IFS è vuoto).

Grazie, non sapevo che $*avesse questo semantico - ora è logico. Penso che questa risposta risolva effettivamente un altro problema che ho avuto durante l'iterazione sugli array ...
Konrad Rudolph,

6

Devi usare $@, invece di$*

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

foo() { bar "$@"; }

foo "This is" a test

ouput

This is:a

Perché funziona

Perché con $*, tutto il parametro è visto come una singola parola , significa che passerai This is a testalla barfunzione. In questo caso, il primo parametro passa alla barra delle funzioni è This, il secondo è is.

Con $@, ogni parametro è una stringa tra virgolette , significa che passerai 'This is' 'a' 'test'alla barfunzione. Quindi il primo parametro passa alla barra delle funzioni è This is, il secondo è a.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.