Passar argumentos para funcionar exatamente como está

8

Eu tenho a seguinte função:

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

Eu estou chamando essa função de outra função, foo . foo em si é chamado da seguinte forma:

foo "This is" a test

Eu quero obter a seguinte saída:

This is:a

Ou seja, os argumentos que bar recebe devem ser os mesmos tokens que eu passo para foo .

Como o foo precisa ser implementado para conseguir isso? Eu tentei as duas implementações a seguir, mas nenhuma delas funciona:

  • foo() { bar $*; }

    - output: this:is

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

    - output: this is a test:

Minha pergunta é efetivamente como posso preservar a citação de argumentos. Isso é possível?

    
por Konrad Rudolph 06.06.2013 / 17:51

2 respostas

11

Use "$@" :

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

"$@" e "$*" têm significados especiais:

  • "$@" expande para várias palavras sem executar expansões para as palavras (como "$1" "$2" ... ).
  • "$*" une parâmetros posicionais com o primeiro caractere no IFS (ou espaço se o IFS não estiver definido ou nada se o IFS estiver vazio).
por 06.06.2013 / 18:15
6

Você deve usar $@ , em vez de $*

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

foo() { bar "$@"; }

foo "This is" a test

ouput

This is:a

Por que isso funciona?

Como em $* , todos os parâmetros são vistos como única palavra , isso significa que você passará a função This is a test para bar . Nesse caso, o 1º parâmetro passa para a barra de funções é This , o segundo é is .

Com $@ , cada parâmetro é uma string entre aspas , significa que você passará 'This is' 'a' 'test' para bar funtion. Portanto, o primeiro parâmetro a passar para a barra de funções é This is , o segundo é a .

    
por 06.06.2013 / 18:13