#bash #shell #goto
#bash #оболочка #переход
Вопрос:
У меня есть скрипт bash, который печатает заголовок и проверяет значение «Y» или «N».
Когда кто-то вводит текст, который не равен «Y» или «N», я хотел бы отправить их обратно в начало скрипта, чтобы он снова напечатал заголовок и вопрос.
Я знаю, что вы можете сделать это с помощью goto, но мне было интересно, есть ли другой способ, потому что я слышал, что многие люди говорят, что вам не следует использовать goto или что он устарел. Верно это или нет, я хотел бы посмотреть, есть ли у кого-нибудь еще способ решить эту проблему.
Заранее спасибо.
Ответ №1:
Вы могли бы реализовать это в цикле:
while [ !$exit_loop ]
do
echo "enter choice - "
read -n 1 input
case "$input" in
y|Y) $exit_loop = 1;;
n|N) $exit_loop = 1;;
*) echo "invalid choice";;
esac
done
Лично я не нахожу разницы между использованием перехода / цикла или любых других средств. Я бы всегда говорил использовать то, что наиболее подходит для данной ситуации — для вашей я бы использовал goto .
например, если у вас есть несколько отступов, охватывающих много строк, и вам нужно вернуться к началу функции, я бы использовал goto — это намного проще понять в его контексте.
Комментарии:
1. Вы можете упростить с
while true; do
case
помощью оператора and, который заменит на простойif
, и, если совпадет, будетbreak
. Так что вам не нужна переменная plus ($exit_loop
) .2. Очень верно. Увы, не зная, что op хотел сделать в цикле, я просто собрал это вместе 🙂
Ответ №2:
В качестве прямого ответа на ваш вопрос вы можете использовать exec
для замены текущего процесса другим процессом или, в зависимости от обстоятельств, другой новой копией текущего процесса.
read -p "Yes? Or no? " yn
case $yn in
[YyNn]) ;;
*) exec "$0" "$@"
esac
Ответ №3:
Если вам нужен более структурированный подход, вы можете использовать цикл while или until .
Ответ №4:
Ниже приведен пример (слегка упрощенный) с использованием предложения @Michael. Условие выхода находится в цикле while, но пользователь также может выполнить промежуточное действие, чтобы решить, какое действие предпринять:
while [[ ! "${action-}" =~ ^[SsRr]$ ]]
do
echo "What do you want to do?"
read -n 1 -p $'[d]iff, [s]kip, [S]kip all, [r]eplace, [R]eplace all: n' action
if [[ "${action-}" =~ ^[Dd]$ ]]
then
diff "$target_path" "$source_path"
fi
done
Комментарии:
1. Я не видел ничего подобного раньше, [[ ! «$ {action-}» = ~ ^[SsRr] $ ]], аккуратно.
Ответ №5:
echo "Hello User, are you ready to learn some Linux?"
while true; do
echo "Please enter y/n:"
read a
bfunc() {
if [ "$a" == "y" ]
then
echo "That is great, lets get started!"
echo "This Script is under construction, functionality coming soon"
exit 0
elif [ "$a" == "n" ]
then
echo "That is too bad, see you next time!"
echo "You are now exiting the script"
exit 0
else [ "$a" != "y||n" ]
echo "Please only enter y or n!"
fi
}
bfunc
done
Комментарии:
1. Извините, я не знал, что для создания кода нужны 4 пробела, но это работает!
2. Нет, на самом деле это не так; в частности,
else [ "$a" != "y||n" ]
это не синтаксическая ошибка, но и совсем не то, что вы думаете. Определение функции внутри цикла также довольно … оригинально.3. Это мой первый bash-скрипт, и он работает так, как я предполагал. Можете ли вы объяснить, почему это неправильно?