我有这段代码,由于某种原因,它没有注意到输入为“是”以重新启动程序。它只是不断询问“您想再次订购吗”。似乎是什么问题(可能很简单),但我不知道。
#!/bin/sh
read -rp 'Fish or chicken? ' protein
read -rp 'Beans or rice? ' starch
read -rp 'Broccoli or asparagus? ' veggie
read -rp 'Beer or beer? ' drink
echo "You have ordered the $protein with a side of $starch and $veggie, and to drink you will have $drink"
while true; do
read -rp 'Would you like to order again? ' order
if echo "order" | grep -iq 'yes'; then
exec $0
elif echo "order" | grep -iq 'no'; then
exit 0
fi
done
另外,我如何让它识别答案是否不是“是”或“否”,并且它会打印出一行指出正确的答案。
答案1
脚本的主要问题是您测试文字字符串order
是否存在yes
。你可能是说"$order"
。
另一个问题是您运行此脚本(这是一个bash
脚本),使用/bin/sh
. /bin/sh
您可能不理解 POSIX shell 标准的一些扩展bash
,但您也可能只是幸运。更改第一行以便bash
使用它。
shell 脚本中的字符串比较可以使用
if [ "$order" = "yes" ]; then ...; fi
这比调用“更便宜”并且更容易阅读grep
。
您还可以使用case ... esac
:
case "$order" in
yes) ... ;;
no) ... ;;
esac
重新执行脚本以再次执行是脆弱且非常不传统的。例如,如果脚本被调用为bash script.sh
.最好引入一个循环,如果用户不想再尝试一次,则可以打破该循环。
bash
还有一个select
循环,您可以像这样使用:
echo 'Please select protein from this menu:'
select protein in "beans" "lentils" "tofu" "cheese"; do
if [ -z "$protein" ]; then
echo 'Invalid choice' >&2
else
printf 'You picked %s as protein\n' "$protein"
break
fi
done
这使您可以更好地控制用户的输入。
读取用户的交互式输入然后询问是否退出的一般方法:
while true; do
read -p 'Enter data: ' -r data
# use "$data" here for something
read -p 'Again? [Y/n] ' answer
case "$answer" in
[Nn]*) break ;;
esac
done
在这里,您有一个外循环来提出问题并进行一些处理。然后它会询问用户是否想再去一次。如果他们回答“否”(以N
或开头的任何内容n
),我们就break
退出循环。
最后的测试也可能是对 的验证$data
。如果用户在第一次中输入了无效的输入read
,您可能需要再次询问,直到给出有效的输入。
这样做的好处是$data
(或您读到的任何内容)在输入循环之后仍然存在并且可用,因此$data
您可以稍后再进行处理,而不是在循环内部进行处理。
伪代码:
input-loop:
read-data
validate-data
if-valid exit input-loop
goto input-loop
main-code:
use-validated-data
答案2
您忘记在前面加上order
以$
取消引用它:
#!/bin/sh
echo $0
read -rp 'Fish or chicken? ' protein
read -rp 'Beans or rice? ' starch
read -rp 'Broccoli or asparagus? ' veggie
read -rp 'Beer or beer? ' drink
echo "You have ordered the $protein with a side of $starch and $veggie, and to drink you will have $drink"
while true; do
read -rp 'Would you like to order again? ' order
if echo "$order" | grep -iq 'yes'; then
exec $0
elif echo "$order" | grep -iq 'no'; then
exit 0
fi
done
另请注意,您可以简单地将字符串与 进行比较=
。