bash cita o quebra-cabeça de expansão

2

Meu script parece:

opts="-x ''"
curl http://somepage $opts

Eu quero a string em $opts anexada ao comando. Eu uso bash -x test.sh para verificar a expansão e ver que as aspas simples são removidas.

Se eu alterá-lo para:

opts="-x \'\'"

Após a expansão, existem 4 aspas simples.

    
por davidshen84 09.05.2011 / 11:44

2 respostas

5

O que exatamente você vê? Com o script

opts="-x ''"
echo curl http://somepage $opts
opts="-x \'\'"
echo curl http://somepage $opts

Com o bash 3.2.39 ou 4.1.5, vejo

+ opts='-x '\'''\'''
+ echo curl http://somepage -x ''\'''\'''
curl http://somepage -x ''
+ opts='-x \'\''\'\'''
+ echo curl http://somepage -x '\'\''\'\'''

A primeira chamada para curl (well, echo curl ) tem um último argumento que consiste em dois caracteres '' . O rastreio escapa caracteres especiais: ' aparece como '\'' (um idioma comum para “escapar” aspas simples entre aspas simples). Formalmente, ''\'''\''' consiste em uma string com aspas simples vazias '' seguida pelo caractere com aspas invertidas \' , depois novamente '' , novamente \' e uma% final''. (Ksh mostra isso como um pouco mais legível $'\'\'' .) A segunda chamada passa quatro caracteres \'\' .

Nas regras normais de análise sh, você não pode criar um argumento vazio expandindo uma variável sem aspas. A divisão de palavras só é cortada quando há um caractere não citações ou espaço em branco.

Como você está usando o bash, você pode colocar várias opções em um array. Isso também funciona em ksh e zsh.

opts=(-x "")
curl http://somepage "${opts[@]}"

Para este caso em particular, você pode substituir a variável de ambiente.

http_proxy= curl http://somepage
    
por 09.05.2011 / 13:53
2

Isso porque o que você deseja é passar uma string literal literal para curl , mas o que você obtém é um conjunto de aspas literais, já que elas já foram citadas. Uma referência aponta para outro que simplesmente recomenda usar uma função:

download(){
    curl http://somepage "$@"
}
download -x ''

Se você quiser observar o que seu script realmente está fazendo, tente executar set -x antes dele.

    
por 09.05.2011 / 13:22

Tags