Que bash expandirá {1 .. $ VAR} da mesma maneira que o zsh faz

6

Em resposta a um comentário meu a esta questão sobre SF, o OP afirma que

for i in {1..$NUM}

se expande corretamente no bash. Eu tenho acesso ao bash 4.0.33 (Ubuntu), 3.2.25 (Centos) e 3.00.16 (1) (solaris 10). Nenhum deles expandirá o {1 .. $ NUM}.

Alguém sabe quais versões do bash fazem a expansão? Se não é bash o que é isso? Eu sei que o zsh fará a expansão mas no script do OP o shebang deve remover a possibilidade de um pseudônimo?

    
por Iain 24.02.2011 / 17:34

3 respostas

5

Tenho certeza de que a pessoa que fez a pergunta no servidor está errada. Eles estão deixando de fora alguns detalhes intencionalmente ou não estão cientes de alguma configuração estranha na máquina (/ bin / bash como um link para outra coisa). Eu experimentei o release 4.2 do bash de duas semanas, sobre o bash 3.2 do CentOS 5, e sobre o bash 2.05a (de 2001) que eu mesmo construí para tentar.

A fonte mais antiga em ftp.gnu.org é 1.14, mas isso não é feito corretamente, e eu Não tenho certeza se vale a pena tentar. A documentação desse release contém exatamente as mesmas frases-chave da documentação moderna:

 The order of expansions is: brace  expansion,  tilde  expan-
 sion, parameter, variable, command, and arithmetic substitu-
 tion (done in a left-to-right fashion), word splitting,  and
 pathname expansion.

Mas, na verdade, agora que penso nisso, não faz sentido, já que a sintaxe "{x..y}} era adicionado no bash 3.0 , fazendo com que olhar antes desse inútil.

Então, deixe-me tentar o 3.0 ... certo. Mesmo comportamento.

Então sim. Eu sou extremamente cético. Algo não se soma.

(mais tarde ...)

Aha! O questionador de falha do servidor admite " Desculpe, meu erro. número real em i em {1..10}, então funcionou bem. "Então, lá vai você.

A resposta para esta pergunta é "nenhuma versão do bash funciona assim". :)

    
por 24.02.2011 / 20:11
2

Para expandir isso, você teria que usar eval :

$ echo {1..5}
1 2 3 4 5
$ NUM=5
$ echo {1..$NUM}
{1..5}
$ eval "echo {1..$NUM}"
1 2 3 4 5

Tenha muito, muito cuidado com eval ! Certifique-se de verificar se é realmente um número antes de executar algo assim se estiver aceitando a entrada do usuário. Como meu colega observou: " eval é malvado!"

    
por 24.02.2011 / 18:02
1

A expansão de chave não expande as variáveis, porque a expansão de chave é o primeiro passo da expansão do shell e as variáveis são expandidas posteriormente.

Na página do bash man:

Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces.

Então:

NUM=4
for i in {1..$NUM}
do
    echo $i
done

imprime

{1..4}
    
por 24.02.2011 / 17:57

Tags