Variação de variáveis em loop custom definable

2

Eu tenho uma pergunta com variáveis de intervalo em loops for. Em loops for eu sei que você pode usar {..} para definir um intervalo. Mas eu quero que seja definível pelo cliente. Então, o script pede um valor de intervalo e eu quero que ele seja flexível. assim:

#!/bin/bash
while true; 
    do
    echo "Some explenation..."
    read -p "Possible values are: ALL or RANGE (to define a specific range):" answer
    case $answer in
            #ALL
            [aA][lL][lL] )
            echo "ALL is selected, 1 to 250"
            RANGE="{1..250}"
            break
            ;;
            #RANGE
            [rR][aA][nN][gG][eE] )
            echo "Range is selected, please define a custom range. Notation should be like: <start>..<stop>"
            echo "or: <single> <single>"
            echo "or a combination of both. Like: 1..23 28 29 101..145 180 212"
            read RANGE
            break
            ;;
            #OTHERS
            * )
            echo "Typo error!! Not correct, type again ALL, PRI, SEC or 
RANGE"
            ;;
    esac
    done
echo ""
echo "Range for this execution is set to:"
echo "$RANGE"
for NEXI in $RANGE
    do
    sleep 0.2
    echo "Nexus number: $NEXI"
    done
echo ...

Mas o resultado quando eu digito {1..10} 52 54 {120..128} é:

Nexus number: {1..10}
Nexus number: 52
Nexus number: 54
Nexus number: {120..128}

enquanto esperava que fosse assim:

Nexus number: 1
Nexus number: 2
Nexus number: 3
Nexus number: 4
Nexus number: 5
Nexus number: 6
Nexus number: 7
Nexus number: 8
Nexus number: 9
Nexus number: 10
Nexus number: 52
Nexus number: 54
Nexus number: 120
Nexus number: 121
... etc.

totalmente escrito.

O que posso mudar para conseguir isso?

Obrigado.

    
por SHLelieveld 27.09.2017 / 13:23

2 respostas

2

O problema é que a expansão de chaves acontece antes da expansão de variáveis. Conforme explicado em man bash :

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

Isso significa que quando você tem algo como $var que contém {1..3} e echo "$var" , o shell procura por possíveis expansões de chaves antes expandindo a variável para seu valor. Como as chaves estão na variável, isso significa que, nesse ponto, o shell não vê chaves, portanto, nenhuma expansão de chave é executada.

Uma solução alternativa seria eval da variável, se for um intervalo. Adicione estas linhas antes do seu for loop:

if [[ $RANGE =~ ^[0-9]+\.\.[0-9]+$ ]]; then
        RANGE=$(eval echo {$RANGE})
fi

Agora, em uma nota mais geral, geralmente é uma boa idéia evitar o uso de nomes de variáveis CAPITAL em scripts de shell. Variáveis de ambiente geralmente são capitalizadas e isso pode levar a misturas se você usar o mesmo nome de uma variável env definida. Portanto, use nomes de variáveis de letras minúsculas para estar no lado seguro.

Além disso, este é um programa muito chato para depurar e igualmente irritante de usar. Não solicite ao seu usuário informações em tempo de execução! Em vez disso, altere seu script e faça com que ele leve argumentos. A digitação de valores é difícil, irritante, propensa a erros e não pode ser automatizada.

    
por 27.09.2017 / 14:20
-1

Defina seu shell como ksh e esse código deve funcionar.

#!/usr/bin/ksh

    
por 27.09.2017 / 13:48