代码之家  ›  专栏  ›  技术社区  ›  user3541631

在菜单中循环,直到选择了条件或退出/注销选项

  •  1
  • user3541631  · 技术社区  · 6 年前

    为此,我已经创建了2个函数。

    • is_valid_name ,如果有效则返回0,如果无效则返回1
    • is_database ,如果存在具有用户引入的名称的数据库,则返回0;如果不存在,则返回1

    我想为用户提供一种可能性,在名称无效或数据库已经存在的情况下,添加一个不同的名称或取消/退出。

    Menu 有2个选项:

    1. 添加新数据库
    2. 出口

    -&燃气轮机; 答:

    echo Add a database
    read -r $database   # get the database name from the user
    check the entered name - `is_valid_name'
    

    分支机构1。

    • 如果名称无效, \u是有效的\u名称吗 -&燃气轮机; 第二:
    • 显示包含两个选项的菜单
    • 如果用户选择选项1(添加新数据库),请返回 A (见上文粗体部分)
    • 如果用户选择选项2(退出),则存在脚本

    分支2

    • is\U数据库

      • (见上文粗体部分)

      分支2.2

    while do loop 检查数据库的名称和名称是否都存在,如果两者都正常,则退出循环并继续代码或用户是否希望存在。

    2 回复  |  直到 6 年前
        1
  •  1
  •   David C. Rankin    6 年前

    首先,不要使用所有大写的变量名——它们通常是为系统使用而保留的。(不是你不能,只是形式不好)。对用户变量使用小写的变量名。

    虽然还不完全清楚脚本的其余部分应该做什么,但看起来似乎您正在尝试构建一个不使用重复项的列表 is_entity() 检查一下 'entity' 已存在并正在返回 0 如果有或者 1

    让我们这样看,要检查一个实体是否存在,必须在某个地方有它们的集合。对于bash来说,一系列的问题是有意义的。因此,要检查数组中是否已经存在实体,可以执行以下操作:

    declare -a entity   # declare an empty indexed array to hold entities
    logout=0            # a flag to handle your 'logout' entry
    
    ## check if first argument in entity array
    #  return 0 if it exists, 1 otherwise
    is_entity() {
    
        for i in "${entity[@]}"             # loop over array comparing entries
        do
            [ "$i" = "$1" ] && return 0     # if found, return 0
        done
    
        return 1    # otherwise return 1
    }
    

    entity 如果给定函数的第一个参数,则存在数组(如果没有给定参数,则留给您错误处理)

    如果要有一个实体数组,则需要一种添加它们的方法。再简单一点 add_entity() 函数可以调用 是\实体() return 0

    ## add entity to array
    #  return 0 if it exists, 1 otherwise
    add_entity () {
        local name
    
        printf "\nenter name: "     # prompt for new entity name
        read name
    
        is_entity "$name"           # check if it exists with is_entity
        if [ $? -eq '0' ]
        then
            return 0                # if so, return 0
        else
            entity+=( "$name" )     # otherwise add it to array
        fi
    
        return 1                    # and return 1
    }
    

    ( 使用 local 保险公司名称 name 变量仅限于函数的作用域,并且在函数返回时未设置)

    脚本的其余部分显示“Added”菜单或“Exists”菜单,其中有两个选项可以添加另一个(或选择另一个名称),可以用两个 case 基于 添加实体() . 基本上你会不断循环直到 logout 被选中,召唤 添加实体() 在循环开始时,然后使用 案例

    while [ "$logout" -eq '0' ]   ## main loop -- loop until logout -ne 0
    do
        add_entity      # prompt and check with add_entity/is_entity
        case "$?" in    # filter return with case
            0   )       # if the entered name already existed
            ## Existed Menu
            1   )       # if the entity did not exist, but was added to array
            ## Added Menu
        esac
    done
    

    在每种情况下,您的“已存在”或“已添加”菜单都可以使用一个简单的 select 循环,对你来说可能是下面这样的 "Exists"

                printf "\nEntity exists - '%s'\n" "${entity[$((${#entity[@]}-1))]}"
                select task in "use another name" "logout"  # display exists menu
                do
                    case "$task" in
                    "use another name"   )  # select menu matches string
                        break
                        ;;
                    "logout"   )
                        logout=1  # set logout flag to break outer loop
                        break;
                        ;;
                    ""  )   # warn on invalid input
                        printf "invalid choice\n" >&2
                        ;;
                    esac
                done
                ;;
    

    为了验证操作和实体是否被收集,可以在退出循环后简单地显示数组的内容,例如。

    printf "\nthe entities in the array are:\n"
    for ((i = 0; i < ${#entity[@]}; i++))
    do
        printf "  entity[%2d] %s\n" "$i" "${entity[i]}"
    done
    

    将拼图的所有部分放在一起,您可以处理您的逻辑并使用类似于以下脚本显示相应的菜单:

    #!/bin/bash
    
    declare -a entity   # declare an empty indexed array to hold entities
    logout=0            # a flag to handle your 'logout' entry
    
    ## check if first argument in entity array
    #  return 0 if it exists, 1 otherwise
    is_entity() {
    
        for i in "${entity[@]}"             # loop over array comparing entries
        do
            [ "$i" = "$1" ] && return 0     # if found, return 0
        done
    
        return 1    # otherwise return 1
    }
    
    ## add entity to array
    #  return 0 if it exists, 1 otherwise
    add_entity () {
        local name
    
        printf "\nenter name: "     # prompt for new entity name
        read name
    
        is_entity "$name"           # check if it exists with is_entity
        if [ $? -eq '0' ]
        then
            return 0                # if so, return 0
        else
            entity+=( "$name" )     # otherwise add it to array
        fi
    
        return 1                    # and return 1
    }
    
    while [ "$logout" -eq '0' ]   ## main loop -- loop until logout -ne 0
    do
        add_entity      # prompt and check with add_entity/is_entity
        case "$?" in    # filter return with case
            0   )       # if the entered name already existed
                printf "\nEntity exists - '%s'\n" "${entity[$((${#entity[@]}-1))]}"
                select task in "use another name" "logout"  # display exists menu
                do
                    case "$task" in
                    "use another name"   )  # select menu matches string
                        break
                        ;;
                    "logout"   )
                        logout=1  # set logout flag to break outer loop
                        break;
                        ;;
                    ""  )   # warn on invalid input
                        printf "invalid choice\n" >&2
                        ;;
                    esac
                done
                ;;
            1   )       # if the entity did not exist, but was added to array
                printf "\nEntity added - '%s'\n" "${entity[$((${#entity[@]}-1))]}"
                select task in "Add another" "logout"   # display added menu
                do
                    case "$task" in
                    "Add another"   )
                        break
                        ;;
                    "logout"   )
                        logout=1
                        break
                        ;;
                    ""  )
                        printf "invalid choice\n" >&2
                        ;;
                    esac
                done
                ;;
        esac
    done
    
    printf "\nthe entities in the array are:\n"
    for ((i = 0; i < ${#entity[@]}; i++))
    do
        printf "  entity[%2d] %s\n" "$i" "${entity[i]}"
    done
    

    运行脚本以验证菜单并测试脚本对不同输入的响应,您可以执行以下操作:

    $ bash ~/tmp/entity_exists.sh
    
    enter name: one
    
    Entity added - 'one'
    1) Add another
    2) logout
    #? 1
    
    enter name: one
    
    Entity exists - 'one'
    1) use another name
    2) logout
    #? crud!
    invalid choice
    #? 1
    
    enter name: two
    
    Entity added - 'two'
    1) Add another
    2) logout
    #? 1
    
    enter name: three
    
    Entity added - 'three'
    1) Add another
    2) logout
    #? 2
    
    the entities in the array are:
      entity[ 0] one
      entity[ 1] two
      entity[ 2] three
    

    仔细检查一下,如果你还有其他问题,请告诉我。告诉你怎么检查有点困难

        2
  •  2
  •   Arkadiusz Drabczyk    6 年前

    #!/usr/bin/env bash
    
    function is_entity()
    {
        # fill in to do what you want
        printf "%s\n" "$1"
    }
    
    while true
    do
        echo Add New Entity:
        read -r entity
        if is_entity "$entity"; then
        select TASK in 'Entity exist, use another name' 'Logout'
        do
            case "$REPLY" in
            1)
                continue 2
                ;;
            2)
                printf "Bye\n"
                exit 0
                ;;
            esac
        done
        fi
    done