我正在编写一个bash脚本,用户可以在其中添加新数据库。
脚本需要检查用户输入的名称是否有效,以及是否已经存在具有相同名称的数据库。
为此,我已经创建了2个函数。
is_valid_name
,如果有效则返回0,如果无效则返回1 is_database
,如果存在一个由用户介绍的名称的数据库,则返回0;否则,则返回在名称无效或数据库已存在的情况下,我想为用户提供添加其他名称或取消/退出的可能性。
我想使用带有两个选项的Menu
来做到这一点:
伪代码:
-> A:
echo Add a database
read -r $database # get the database name from the user
check the entered name - `is_valid_name'
分支1。
is_valid_name
将显示错误并返回1
-> B: 第2分行
如果名称有效,请检查数据库是否存在,is_database
2.1版
2.2版
我正在考虑使用while do loop
来检查数据库的名称和是否都存在,并且如果两者都可以并继续执行代码或者用户想要存在,则退出循环。
我不知道如何设置(不作为语法)循环来捕获这两个条件
答案 0 :(得分:2)
如果我正确理解,将可以完成以下任务:
#!/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
答案 1 :(得分:1)
首先,请勿使用全大写的变量名,这些变量名通常保留供系统使用。 (不是您不能,这只是错误的形式)。为用户变量使用小写的变量名。
虽然还不能100%地了解脚本的其余部分应该做什么,但是看起来您似乎正在尝试使用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()
函数可以调用您的is_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
变量仅限于函数范围,并且在函数返回时未设置)>
您可以使用两个case
语句来实现脚本的其余部分,以显示“添加的”菜单或“存在的”菜单以及两个选择来添加另一个(或选择另一个名称)。 add_entity()
的回报。本质上,您将连续循环直到选择了logout
,然后在循环开始时调用add_entity()
,然后根据返回值使用case
语句来确定要显示的菜单。逻辑概要如下:
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
仔细检查一下,如果还有其他问题,请告诉我。仅告诉您如何检查is_entity()
而不知道如何存储它们有点困难,但是这里的逻辑可以适应多种不同的情况。