このコードがありますが、何らかの理由でプログラムを再起動しても、入力は「はい」として認識されません。続けて「もう一度注文しますか?」と聞いてみますね。何が問題のようですが(おそらく簡単なことかもしれませんが)よくわかりません。
#!/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"
。
もう1つの問題は、を使用してこのスクリプト(スクリプトbash
)を実行することです/bin/sh
。 /bin/sh
POSIX シェル標準へのいくつかの拡張を理解していないかもしれませんが、幸運かもしれませんbash
。これを使用するには、最初の行を変更してくださいbash
。
シェルスクリプトの文字列比較は、以下を使用して実行できます。
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
また、単に文字列をと比較することもできます=
。