在 bash 中使用 do 循环和 case 语句创建菜单驱动脚本

在 bash 中使用 do 循环和 case 语句创建菜单驱动脚本

我正在尝试创建一个 bash 脚本来从 AWS 中的 txt 文件创建 json 文件。下面的脚本在第一个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正如你所说,问题在于你的陈述。这总是正确的,因为根据定义,任何变量总是与自身匹配:

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

相关内容