2016-08-17 7 views
1

У меня проблема с моим скриптом Bash, сам скрипт отлично работает, но я пытаюсь его убрать, но я не могу найти/думать о методе как о команде «goto», и да, я очень новичок в Linux Bash.Linux Bash goto команда?

Мой код:

echo "What is the street road?" 
read road 
echo "What is the address ?" 
read address 
echo "User is set as: $road" 
echo "Address has been set as: $address" 


while true; do 
    read -p "Is this correct? " yn 
    case $yn in 
     [Yy]*) break;; 
     [Nn]*) exit;; 
     *) break;; 
    esac 
done 

Когда пользователь вводит «п» сценарий будет просто выйти из себя, но я пытаюсь привести в порядок его так, он будет просто повторно петлю себя здесь. Поэтому, если пользователь вводит «n», он просто повторно запрашивает их снова для дороги и адреса.

Я знаю, что в .bat вы можете сделать : A Гото: A (или что-то подобное!) Но в Bash не уверен, как это сделать?

Спасибо всем!

+4

Вообще, если вы найдете самостоятельно используя 'goto' в скрипте, вы что-то сделали не так. 'bash' имеет (ограниченную) функцию поддержки, которая поможет вам достичь того, чего вы хотите. –

+0

См.: [Есть ли инструкция «goto» в bash?] (Http://stackoverflow.com/q/9639103/3776858) – Cyrus

+0

См. Также http://stackoverflow.com/a/38873157/874188 – tripleee

ответ

0

Я бы переписать сценарий, как это:

ask() { 
    echo "$1" 
    read answer 

    while true; do 
     read -p "Is this correct? " yn 
     case $yn in 
      [Yy]*) break;; 
      [Nn]*) exit;; 
      *) break;; 
     esac 
    done 

    eval "$2='$answer'" 
} 

ask "What is your street?" street 
ask "What is the address?" address 
echo "Your address has been set to $address $street" 

Как я уже упоминал в своем комментарии на ваш вопрос, используя goto, на любом языке, как правило, считается плохой форме (потому что это приводит к труднодоступные -debug code, за исключением очень особых обстоятельств) и bash does not have a goto like you find in other languages в любом случае. Если вы обнаружите, что пишете код, который, по вашему мнению, требует goto, пожалуйста, уделите немного времени, откидывайтесь назад от клавиатуры и немного переоцените свое предположение. 99.999% времени, вы обнаружите, что вам это действительно не нужно, и есть подход к структурированному программированию, который будет выполнять то же самое гораздо более аккуратно.

+1

Это не означает, t вызвать приглашение повторить, если пользователь отвечает на 'n'. –

+0

Не используйте 'eval', если вы можете его избежать. Здесь вы можете использовать 'printf -v '$ 2"'% s '"$ answer" '. – chepner

0

Вы могли бы пойти радикальным:

ok=no 
while read -p "What is the street road? " road && 
     read -p "What is the address? " address && 
     echo "Road is set to: $road" && 
     echo "Address has been set as: $address" && 
     read -p "Is this correct? " yn 
do 
    case $yn in 
    ([Yy]*) echo "Great!"; ok=yes; break;; 
    ([Nn]*) echo "OK - then try again";; 
    (*)  echo "Didn't understand that - it did not look like Y or N";; 
    esac 
done 

if [ "$ok" = "yes" ] 
then : OK to use answers 
else : Do not use answers 
fi 

Это использует тот факт, что вы можете иметь произвольный список команд, как «условие» в while цикле. Я приковал команды вместе с &&, чтобы все они преуспели, но у вас могут быть независимые команды, и в этом случае последний будет считаться. Я также использовал нотацию read -p 'prompt' var для начальных значений, а также «Правильно ли это».

Пример диалога:

$ bash prompt.sh 
What is the street road? California 
What is the address? 1189 
Road is set to: California 
Address has been set as: 1189 
Is this correct? n 
OK - then try again 
What is the street road? California Ave 
What is the address? 2291 
Road is set to: California Ave 
Address has been set as: 2291 
Is this correct? y 
Great! 
$ 
3

Я предлагаю вам использовать это с GNU Баш:

#!/bin/bash 

until [[ $yn =~ ^[Yy]$ ]]; do 
    read -p "What is the street road? " road 
    read -p "What is the address ? " address 

    echo "User is set as: $road" 
    echo "Address has been set as: $address" 

    read -p "Is this correct? " yn 
done 

# continue with your code here 
+0

Хорошее использование сравнения регулярных выражений. Вы также должны обрабатывать случай, когда '$ yn' является отрицательным (что в OP приводит к тому, что он полностью выходит из сценария). –

+0

++, но учтите, что термин «GNU bash» является избыточным и запутанным, потому что GNU Bash - это единственный Bash, поэтому он не нуждается в квалификации (особенно, учитывая, что вопрос помечен 'bash'). – mklement0

+0

@ mklement0: Спасибо. Я использую «GNU bash» намеренно. Busybox 'bash отличается от реализации GNU bash. Пример этого: bashbox bash не был уязвим для ошибки Bash [ShellShock] (https://en.wikipedia.org/wiki/Shellshock_%28software_bug%29). – Cyrus

0

Немного нетипичный, но вы можете сделать:

#!/bin/sh 
while 
    read -p 'What is the street road? ' road 
    read -p 'What is the address ? ' address 
    echo "User is set as: $road" 
    echo "Address has been set as: $address" 
    read -p "Is this correct? " yn 
    case $yn in 
     [Yy]*) false;; 
     *) true;; 
    esac 
do 
    : 
done 
echo "User is set as: $road" 
echo "Address has been set as: $address" 
Смежные вопросы