2016-08-17 236 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”的剧本将刚刚退出本身,而是想在这里整理一下,以便它只会重新循环本身。因此,如果用户输入“n”,它只会再次询问他们的道路和地址。

我知道蝙蝠,你可以做 :一 转到:一个 (或者类似的东西!)但是,在猛砸我不知道如何做到这一点?

谢谢大家!

+4

一般来说,如果你发现你在脚本中使用'goto',你在某处做错了什么。 'bash'具有(有限的)功能支持,这将帮助你实现你想要的。 –

+0

请参阅:[bash中是否有“goto”语句?](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代码,但在任何情况下非常特定情况)和bash does not have a goto like you find in other languages。如果您发现自己编写的代码您认为需要goto,请花点时间,从键盘向后靠,然后重新评估您的前提。 99.999%的时间,你会发现你实际上并不需要它,并且有一种结构化编程方法可以更加整洁地完成同样的事情。

+1

这并不是'如果用户回答'n',会导致提示重复。 –

+0

如果可以避免使用'eval',请不要使用'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的bash:

#!/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的实现。一个例子:Busybox'bash不容易受到Bash bug [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"