bash while循环结构不正确

时间:2014-11-02 03:44:58

标签: bash loops while-loop

我有三个不同的用户输入我需要确认,我是通过"这是正确的:是或否"而循环。显然我的代码是错误的,因为虽然第一个循环正确执行,但我执行其他两个循环之前只测试这些循环的脚本完成。见下面的代码。任何见解将不胜感激。

#loop 1
while [ "$answer" != "Yes" ]
do
stuff
read answer
done

#loop 2
while [ "$answer" != "Yes" ]
do
stuff
read answer
done

#loop 3
while [ "$answer" != "Yes" ]
do
stuff
read answer
done

3 个答案:

答案 0 :(得分:3)

$answer包含Yes时,第一个循环结束。然后第二个循环立即执行相同的测试,测试失败,因此循环立即结束。第三个循环也会发生同样的事情。

您应该在循环之间清除$answer

#loop 1
while [ "$answer" != "Yes" ]
do
stuff
read answer
done

answer=

#loop 2
while [ "$answer" != "Yes" ]
do
stuff
read answer
done

answer=

#loop 3
while [ "$answer" != "Yes" ]
do
stuff
read answer
done

答案 1 :(得分:1)

您可能希望对功能使用更结构化的方法(更多DRY)

until_yes () {
    local stuff=$1
    local answer
    until [[ ${answer,,} == yes ]]; do
        $stuff
        read -p "Is this correct? (yes/no) " answer
    done
}

stuff1 () { ... }
stuff2 () { ... }
stuff3 () { ... }

until_yes stuff1
until_yes stuff2
until_yes stuff3

答案 2 :(得分:0)

鉴于我们在评论中的讨论,以下是unsetvar=以及function tesyn的快速示例,其中显示了在回复时可以对测试进行的不同用途用户输入。该函数在0上返回yes(bash true),在1上返回no(bash false),在问题之后允许简单的测试结构。

#!/bin/bash

function testyn {
    local answer
    read answer
    while : ; do
        answer=$(tr 'A-Z' 'a-z' <<<$answer)     # translate answer to lower-case
        case "$answer" in

            yes ) 
                return 0
                ;;
            no  ) 
                return 1
                ;;
            *   )
                printf "    Invalid Input, Enter (yes/no): "
                read answer
                ;;
        esac
    done
}

printf "Continue? (yes/no): " 
while read answer && [ "$answer" != yes ]; do
    printf "  Invalid input, (yes/no): "
done

unset answer

printf "Continue? (yes/no): " 
while read answer && [ "$answer" != yes ]; do
    printf "  Invalid input, (yes/no): "
done

answer=

printf "Continue? (yes/no): " 
while read answer && [ "$answer" != yes ]; do
    printf "  Invalid input, (yes/no): "
done

## call function tesyn after a question, then
#  use any test that tests for 1 or 0 to
#  respond to the answer
printf "\n  Would you like to continue? (y/n): "
testyn || {
    printf "\nanswer was no, exiting...\n\n"
    exit 1
}

printf "\nAnswer must have been 'yes'. All Done!\n\n"

exit 0

使用/输出:

$ bash testyn.sh
Continue? (yes/no): maybe
  Invalid input, (yes/no): yes
Continue? (yes/no): really
  Invalid input, (yes/no): yes
Continue? (yes/no): yes

Would you like to continue? (y/n): of_course
  Invalid Input, Enter (yes/no): ok
  Invalid Input, Enter (yes/no): yes

Answer must have been 'yes'. All Done!