2016-08-17 234 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"