Passar argumentos para funcionar exatamente como está

10

Eu tenho a seguinte função:

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

Estou chamando essa função de outra função foo,. foopróprio é chamado da seguinte maneira:

foo "This is" a test

Eu quero obter a seguinte saída:

This is:a

Ou seja, os argumentos que barrecebem devem ser os mesmos tokens que eu transmito foo.

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

  • foo() { bar $*; }

    - resultado: this:is

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

    - resultado: this is a test:

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

Konrad Rudolph
fonte

Respostas:

14

Use "$@":

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

"$@"e "$*"tem significados especiais:

  • "$@"expande para várias palavras sem realizar expansões para as palavras (como "$1" "$2" ...).
  • "$*" une parâmetros posicionais com o primeiro caractere no IFS (ou espaço se o IFS estiver desativado ou nada se o IFS estiver vazio).
Lri
fonte
Obrigado, eu não sabia que $*tinha essa semântica - agora é lógico. Eu acho que esta resposta realmente resolve outro problema que eu tenho tido quando iteração sobre matrizes ...
Konrad Rudolph
6

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

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

foo() { bar "$@"; }

foo "This is" a test

saída

This is:a

Por que isso funciona?

Como com $*, todo parâmetro é visto como uma única palavra , significa que você passará This is a testpara a barfunção. Nesse caso, o 1º parâmetro passa para a barra de funções é Thisis.

Com $@, cada parâmetro é uma string entre aspas , significa que você passará 'This is' 'a' 'test'para a barfunção. Portanto, o 1º parâmetro passa para a barra de funções é o This is2º é a.

cuonglm
fonte