Pase argumentos para funcionar exactamente como está

10

Tengo la siguiente función:

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

Estoy llamando a esta función desde otra función foo,. fooen sí se llama de la siguiente manera:

foo "This is" a test

Quiero obtener el siguiente resultado:

This is:a

Es decir, los argumentos que barrecibe deben ser los mismos tokens que paso foo.

¿Cómo foodebe implementarse para lograr esto? He intentado las siguientes dos implementaciones, pero ninguna funciona:

  • foo() { bar $*; }

    - salida: this:is

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

    - salida: this is a test:

Mi pregunta es efectivamente cómo puedo preservar la cita de argumentos. ¿Es esto posible en absoluto?

Konrad Rudolph
fuente

Respuestas:

14

Uso "$@":

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

"$@"y "$*"tienen significados especiales:

  • "$@"se expande a varias palabras sin realizar expansiones para las palabras (como "$1" "$2" ...).
  • "$*" une parámetros posicionales con el primer carácter en IFS (o espacio si IFS no está configurado o nada si IFS está vacío).
Lri
fuente
Gracias, no sabía que $*tenía esta semántica, ahora es lógico. Creo que esta respuesta en realidad resuelve otro problema que he tenido al iterar sobre matrices ...
Konrad Rudolph
6

Debe usar $@, en lugar de$*

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

foo() { bar "$@"; }

foo "This is" a test

salida

This is:a

Por que funciona

Porque con $*todos los parámetros se ven como una sola palabra , significa que pasará This is a testa barfuncionar. En este caso, el paso del primer parámetro a la barra de funciones es This, el segundo es is.

Con $@cada parámetro es una cadena entre comillas , significa que pasará 'This is' 'a' 'test'a la barfunción. Entonces, el primer parámetro pasado a la barra de funciones es This is, el segundo es a.

Cuonglm
fuente