Como evito que o $ @ entre em conflito com aspas duplas no bash?

1

O exemplo a seguir retorna "a b" em vez do esperado "a b c":

test() { bash -c "testargs() { echo \$@; }; testargs $@"; }
test "a b" c

Parece que é um problema de citação. Como posso resolvê-lo sem usar "$ *"?

    
por glarry 04.10.2015 / 00:55

2 respostas

2

$@ deve ser usado apenas no formulário "$@" , sozinho em uma palavra. Quando "stuff$@" é expandido, isso resulta em uma lista que consiste no primeiro parâmetro posicional com stuff prefixado e, em seguida, os outros parâmetros posicionais. Por exemplo, se os parâmetros posicionais forem foo e bar , você obterá duas palavras: stufffoo e bar . Esse é um dos seus problemas.

Outro problema é que, com sh -c , o primeiro argumento não-opcional se torna o nome do script que está disponível como $0 . Argumentos subseqüentes de não-opção se tornam parâmetros posicionais. Por isso, sh -c 'echo "$@"' foo bar qux imprime bar qux - foo está em $0 , bar em $1 e qux em $2 .

Para passar os argumentos da função para o script, use $@ no script (não, como você fez, na função - "stuff$@" é expandido no shell que executa a função, devido às aspas duplas ). E conta para $0 .

test() { bash -c 'testargs() { echo "$@"; }; testargs "$@"' myscript "$@"; }
    
por 04.10.2015 / 01:19
1

$ @ entre aspas duplas se expande para várias palavras. bash -c aceita string como parâmetro, mas pode ser seguido por outras palavras que são então atribuídas a parâmetros posicionais começando com $ 0.

Você pode, portanto, enviar os parâmetros para o código dentro de bash -c da seguinte forma:

Test () { bash -c 'echo $@' -- "$@" ; }
Test "a b" c

Isso também funciona para você:

Test () { bash -c 'testargs() { echo $@ ; } ; testargs $@' -- "$@" ; }
Test "a b" c

Se você quiser manter os parâmetros multiword, adicione aspas duplas:

Test () {
    bash -c 'testargs() {
                 for a in "$@" ; do
                     echo "$a"
                 done
             }
             testargs "$@"' \
        -- "$@"
}
Test "a b" c

Eu usei Test , já que test existe e pode confundir os leitores.

    
por 04.10.2015 / 01:13

Tags