BASH - 提示回答

BASH - Prompting for Answers

我使用以下内容作为基础来询问我的用户一些输入。

while true; do
    echo "Proceed (y/n)"
    read yn
    case $yn in
        [Nn]*) break;;
        [Yy]*)
            while true; do
                echo "name"
                read name

                echo "id"
                read id

                echo "email"
                read email

                echo "location"
                read -i "south" location

                while true; do
                    echo -e "\nIs the above correct ? (y/n)"
                    read res
                    case $res in
                        [Nn]* ) break 1;;
                        [Yy]* )
                            echo -e "\nHere we go."

                            break 3;;
                    esac
                done
            done;;
        *) echo "Please answer yes or no.";;
    esac
done

如果他们对 'Is the above correct' 的回答是“否”,他们将被带回到问题的开头。这很好用,但我如何用他们之前的答案预填答案?

目前,当他们回到开始时,结果默认返回到原始条目,要么是空白,要么是默认选项。

谢谢

如果我明白你想做什么,你想保留并显示用户在选择 "No" 到 "Is the above correct?" 之前输入的最后一个值,那么你需要做什么就是简单的测试一下这个变量是否已经被设置,如果是,就显示原值的提示,如果不是,就直接显示提示。

这仅适用于第一个用户,但从那时起,您有责任根据需要使用变量值,然后在开始之前取消设置值提示下一个人。你是用变量是否为空来判断显示"Prompt only",如果变量是满的,你显示"Prompt with previous answer".

有很多方法可以做到这一点。基于您现有脚本的最简单的方法如下:

name=
id=
email=
south=
location=
while true; do
    echo "Proceed (y/n)"
    read yn
    case $yn in
        [Nn]*) break;;
        [Yy]*)
            while true; do
                [ -n "$name" ] && echo "name: $name" || echo "name: "
                read name

                [ -n "$id"] && echo "id: $id" || echo "id: "
                read id

                [ -n "$email" ] && echo "email: $email" || echo "email: "
                read email

                [ -n "$location" ] && echo "location: $location" || echo "location: "
                read -i "south" location

                while true; do
                    echo -e "\nIs the above correct ? (y/n)"
                    read res
                    case $res in
                        [Nn]* ) break 1;;
                        [Yy]* )
                            echo -e "\nHere we go."
                            ## use vars and then unset for next person
                            break 3;;
                    esac
                done
            done;;
        *) echo "Please answer yes or no.";;
    esac
done

检查一下,让我知道我是否理解正确以及您是否有任何更改。我很乐意进一步提供帮助。

我会更多地使用 -i 选项,用之前读取的值预填充 read 命令的输入。用户可以根据需要编辑该值。您还可以使用 -p 选项将提示直接添加到 read 命令。

location=south
while true; do
    read -p "Proceed (y/n)" yn
    case $yn in
        [Nn]*) break;;
        [Yy]*)
            while true; do
                read -p "Name: " -i "$name" name
                read -p "ID: " -i "$id" id
                read -p "Email: " -i "$email" email
                read -p "Location: " -i "$location" location

                while true; do
                    read -p "Is the above correct ? (y/n)"res
                    case $res in
                        [Nn]* ) break 1;;
                        [Yy]* )
                            echo -e "\nHere we go."

                            break 3;;
                    esac
                done
            done;;
        *) echo "Please answer yes or no.";;
    esac
done

(题外话:我会尽量避免 break 3。)
您可以编写一个函数 readDefault,其中 $1 变量为 display/read 作为默认值,其他参数作为可选提示。

readDefault() {
   varname=
   shift
   if [ $# -eq 0 ]; then
      read -p "${varname} [${!varname}]: " userinput
   else
      read -p "$* [${!varname}]: " userinput
   fi
   printf -v ${varname} "%s" "${userinput:-${!varname}}"
}

# First time defaults outside loop
location="south"
while true; do
    echo "Proceed (y/n)"
    read yn
    case $yn in
        [Nn]*) break;;
        [Yy]*)
            while true; do
                readDefault name "What is your name"
                readDefault id
                readDefault email "Used for sending monthly reports"
                readDefault location

                while true; do
                    echo "Current values: ${name}, ${id}, ${email}, ${location}"
                    echo -e "\nIs the above correct ? (y/n)"
                    read res
                    case $res in
                        [Nn]* ) break 1;;
                        [Yy]* )
                            echo -e "\nHere we go."

                            break 3;;
                    esac
                done
            done;;
        *) echo "Please answer yes or no.";;
    esac