do 루프와 Case 문을 사용하여 Bash에서 메뉴 기반 스크립트 만들기

do 루프와 Case 문을 사용하여 Bash에서 메뉴 기반 스크립트 만들기

AWS의 txt 파일에서 json 파일을 생성하기 위해 bash 스크립트를 생성하려고 합니다. 아래 스크립트는 case첫 번째 옵션에서 실패합니다. $opt포괄 변수가 있기 때문인 것 같습니다 . 기본적으로 종료번호를 입력하면 종료되도록 하고 싶습니다. 다른 유효한 번호에 대한 파일을 생성합니다. 해당 번호가 유효하지 않은 경우 추가 옵션을 묻는 메시지가 표시됩니다.

#!/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

예상되는 동작은 1-14 사이의 숫자를 입력하고 보안 그룹 json 파일이 영역 이름이 있는 디렉터리에 생성되는 것입니다. 이 부분은 작동합니다. 그러나 종료하기 위해 15를 입력하면 이런 일이 발생합니다.

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

또한 16과 같이 잘못된 숫자를 입력하면 15에서도 동일한 현상이 발생합니다.

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

숫자 15가 종료되어야 하며, 1-15가 아닌 숫자는 Invalid...라는 메시지를 표시하고 다른 숫자를 입력하라는 메시지를 표시해야 합니다.

왜 메뉴인가요? 이제는 세밀한 제어를 원한다

답변1

case말씀하신 대로 문제는 진술입니다. 정의에 따라 모든 변수는 항상 자신과 일치하므로 이는 항상 true입니다.

case $opt in
   $opt)
     . . . 

따라서 어떤 값을 지정하더라도 항상 동일한 case블록을 실행합니다. 당신이 무엇을 하고 싶은지 잘 모르겠지만, 나는생각하다귀하의 목표는 다음과 같습니다.

#!/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

관련 정보