如何在bash中调用函数,同时将数组作为参数传递,并让函数返回值



我正在尝试创建一个简单的bash脚本,告诉用户输入一个字符。用户只能输入有限数量的可能选项。如果他在分配的选项中输入了正确的选项,那么该选项将从函数返回。如果没有,则要求用户输入正确的选项。

这是我写的脚本:

#receive from the user an input and verify that it is a valid option. If not, try again. 
#input1: The number of valid options
#input2: array of valid inputs (can be single characters or strings).
# EXAMPLE:
# ARRAY=("a" "b")
# ReceiveValidInput 2 "${ARRAY[@]}" # there are TWO valid options. Valid options are ${ARR[0]}="a", ${ARR[1]}="b"
function ReceiveValidInput()
{
echo "testing"
InputNum=$1 #get the first input1
shift       # Shift all arguments to the left (original $1 gets lost)
ARRin=("$@")    #get the second input2 in the form of an array
ProperInputFlag="false"
while [[ "$ProperInputFlag" == "false" ]]; do
echo "enter input and then press enter" 
read UserInput
index=0
while [[ $index < $InputNum ]]; do
if [[ "${ARRin[index]}" == "$UserInput" ]]; then
echo $UserInput #we do echo because this is how it is returned back (see https://stackoverflow.com/a/17336953/4441211)
ProperInputFlag="true"  #this will cause the while loop to break and exit the function 
fi
index=$((index+1))
done
if [[ "$ProperInputFlag" == "false" ]]; then
echo "Invalid input. Please enter one of these options:"
index=0
while [[ $index < $InputNum ]]; do
echo "Option1 $((index+1)): " ${ARRin[index]}
index=$((index+1))
done
fi
done
}

我是这样使用这个功能的:

ARRAY=("a" "b")
testing=$(ReceiveValidInput 2 "${ARRAY[@]}")
echo "Received: "$testing
read -p "press enter to exit"
exit 1

但它不起作用。这种语法testing=$(ReceiveValidInput 2 "${ARRAY[@]}")只是导致脚本被卡住,什么也没发生。

然而,如果我运行ReceiveValidInput 2 "${ARRAY[@]}",那么函数就会被调用,除了我无法捕获";返回";价值

任何关于如何正确编写调用函数的语法的想法,以便我可以获得";返回";技术上得到回应的价值

@GordonDavisson已经解决了当前函数调用被卡住并且似乎什么都没做的问题。

那么,如何进行函数调用(而不会"卡住"(并为调用过程提供"返回值"呢?

假设函数返回的值是UserInput变量(即echo $UserInput(中的值,则可以使用函数调用不调用子进程的事实,这反过来意味着父/调用进程可以使用函数中的变量赋值。

注意:$(..)中封装函数调用将调用子进程,这反过来意味着父进程/调用进程将无法访问函数调用中分配的值

这里有一个的例子

$ myfunc () {
x=5 
}
$ x=6
$ myfunc             # call the function; no subprocess involved
$ echo "${x}"
5                    # value set by the function is available to the parent
$ x=9
$ y=$(myfunc)        # call the function in a subprocess
$ echo "${x}"
9                    # x=5, set by the function, is not available to the parent

将此信息拉入当前代码集:

$ function ReceiveValidInput() { .... }      # no changes to the function definition
$ ARRAY=("a" "b")                            # same array assignment
$ ReceiveValidInput 2 "${ARRAY[@]}"          # call the function
$ echo "Received: ${UserInput}"              # reference 'UserInput' value that was set within the function call


如果需要让父/调用进程知道存在问题,则函数可以向父/调用过程return一个整数。

调用myfunc()函数(如上所述(:

$ myfunc
$ rc=$?
$ echo $rc
0                     # default return code when the last command
# executed by the function is successful

我们可以让函数通过return命令传递非零返回码($?(,例如:

$ myfunc2 () {
x=9
return 3              # simple example that will always return '3'; this
# can be made dynamic with 'return ${SomeVariable}'
}
$ myfunc2
$ rc=$?
$ echo $rc
3

Veeringway偏离主题,指出您在某种程度上正在重新发明轮子,bash有一个内置命令,用于从一组固定选项中获取交互式输入:

select testing in a b; do [[ $testing ]] && break; done

这将显示一个菜单,让用户按数字选择一个值,并重复,直到做出有效的选择。

最新更新