Crie um script orientado por menu com loop e instrução case no bash

0

Estou tentando criar um script bash para criar arquivos json a partir de um arquivo txt no AWS. O script abaixo está falhando (acho) na primeira opção case . Eu acho que é porque eu tenho a variável $opt que é uma captura de todos. Basicamente eu quero que ele saia se você digitar o número de saída. Crie os arquivos para qualquer outro número válido e, com um número inválido, peça outra opção.

#!/bin/bash

clear

# define variables
NOW=$(date +%F-%a-%H.%M) # year-month-date-day-hour.minute format

# display region list menu
region=($(aws ec2 describe-regions | jq -r '.Regions[].RegionName'))
aws ec2 describe-security-groups --region $region | jq -r '.SecurityGroups[].GroupId' > $region.txt
PS3="Select Region number: "
select opt in "${region[@]}" "exit"
do
   case $opt in
       $opt)
          aws ec2 describe-security-groups --region $region | jq -r '.SecurityGroups[].GroupId' > $region.txt
       # read security groups file into array and create individual json files
       mkdir -p "$region"
       while read group; do
         echo "Processing group: $group"
          aws ec2 describe-security-groups --region $region --group-ids "$group" > "$region"/"$group-"$DATE".json"
       done < $region.txt
           break
          ;;
          "exit")
       echo "Exiting..."
          exit
          ;;
          *)
       echo "Invalid option, try again..."
   esac
done

# cleanup security group text file
rm $region.txt

O comportamento esperado é que você insira um número de 1 a 14 e os arquivos json do Grupo de segurança serão criados em um diretório do nome da região. Esta parte funciona. No entanto, se você digitar 15 para sair, isso acontece;

Select Region number: 15
Processing group: sg-4fec0526

Além disso, se você inserir um número incorreto, por exemplo, 16 as mesmas coisas acontecem com 15;

Select Region number: 16
Processing group: sg-4fec0526

O número 15 deve sair e qualquer coisa que não seja de 1 a 15 deve ser repetida como inválida ... e pedir que você digite outro número.

Por que é um menu? Quero agora um controle granular

    
por eekfonky 02.10.2017 / 11:11

1 resposta

1

O problema é sua declaração case , como você disse. Isso sempre será verdadeiro, já que qualquer variável, por definição, sempre coincide:

case $opt in
   $opt)
     . . . 

Portanto, independentemente do valor que você der, ele sempre executará o mesmo bloco case . Eu realmente não tenho certeza do que você está tentando fazer, mas eu acho que você estava apontando para algo assim:

#!/bin/bash

## Enable extended globbing for the +(...) pattern
shopt -s extglob
clear
# define variables
NOW=$(date +%F-%a-%H.%M) # year-month-date-day-hour.minute format

# display region list menu
region=($(aws ec2 describe-regions | 
    jq -r '.Regions[].RegionName'))
aws ec2 describe-security-groups --region "$region" | jq -r '.SecurityGroups[].GroupId' > "$region.txt"
PS3="Select Region number: "

## make a dummy array which includes the values
validOptions=${region[0]};
for ((i=1; i<${#region[@]}; i++)); do
        validOptions="$validOptions|${region[i]}"
done

select opt in "${region[@]}" "exit"
do
   case $opt in
        ## This uses bash's +(pat1|pat2) syntax which matches
        ## one or more of the |-separated strings.
        +($validOptions))
            echo "Valid!"
            aws ec2 describe-security-groups --region "$region" | 
                jq -r '.SecurityGroups[].GroupId' > "$region.txt"
        # read security groups file into array and create
        # individual json files
        mkdir -p "$region"
        while read group; do
            echo "Processing group: $group"
            aws ec2 describe-security-groups --region "$region" --group-ids "$group" > "${region}/${group}-${DATE}.json"
        done < "$region.txt"
        break
        ;;
    "exit")
        echo "Exiting..."
        exit
        ;;
    *)
        echo "Invalid option $opt, try again..."
   esac
done
    
por 02.10.2017 / 12:54