在一组 if/elif/else/fi 语句中,我让“else”向用户显示错误消息,但我也希望它让用户回到 if/else 语句之前提出的问题,以便他们可以尝试再次回答这个问题。
如何将用户带回到上一行代码?或者,如果这是不可能的,是否有其他方法可以做到这一点?
答案1
我认为最简单的方法是将提示代码包装到一个函数中,然后将其放入until
循环中。
由于您真正需要的只是调用该函数直到成功,因此您可以将 noop 命令“ :
”放在until 循环中。
像这样的东西:
#!/bin/bash
getgender() {
read -p "What is the gender of the user? (male/female): " gender
case "$gender" in
m|M)
grouptoaddto="boys"
return 0
;;
f|F)
grouptoaddto="girls"
return 0
;;
*)
printf %s\\n "Please enter 'M' or 'F'"
return 1
;;
esac
}
until getgender; do : ; done
sudo usermod -a -G "$grouptoaddto" "$username"
这里的重点是用 调用的函数until
,所以会反复调用,直到成功。函数内的大小写开关只是一个示例。
更简单的示例,不使用函数:
while [ -z "$groupname" ]; do
read -p "What gender is the user?" answer
case "$answer" in
[MmBb]|[Mm]ale|[Bb]oy) groupname="boys" ;;
[FfGg]|[Ff]emale|[Gg]irl) groupname="girls" ;;
*) echo "Please choose male/female (or boy/girl)" ;;
esac
done
sudo usermod -a -G "$groupname" "$username"
在最后一个示例中,我使用-z
切换到[
(测试)命令,只要“groupname”变量的长度为零,就继续循环。
关键是使用while
or until
。
将最后一个示例转换为人类可读的伪代码:
While groupname is empty,
ask user for gender.
If he answers with one letter "m" or "B",
or the word "Male" or "boy",
set the groupname as "boys".
If she answers with one letter "F" or "g",
or the word "female" or "Girl",
set the groupname as "girls".
If he/she answers anything else, complain.
(And then repeat, since groupname is still empty.)
Once you have groupname populated,
add the user to that group.
另一个没有groupname
变量的例子:
while true; do
read -p "What gender is the user?" answer
case "$answer" in
[MmBb]|[Mm]ale|[Bb]oy)
sudo usermod -a -G boys "$username"
break
;;
[FfGg]|[Ff]emale|[Gg]irl)
sudo usermod -a -G girls "$username"
break
;;
*) echo "Please choose male/female (or boy/girl)" ;;
esac
done
答案2
flag=1
while [ ${flag} -eq 1 ]
do
read -p "Please answer B or G " bg
if [ "${bg}" = B ] || [ "${bg}" = b ]
then
flag=0
groupname=boys
else
if [ "${bg}" = G ] || [ "${bg}" = g ]
then
flag=0
groupname=girls
fi
fi
done
sudo usermod -a -G ${groupname} $username
这是我能想到的最简单的方法,同时清楚地显示了发生的情况。