【问题标题】:zsh - read user input with default value - empty input not empty?zsh - 使用默认值读取用户输入 - 空输入不为空?
【发布时间】:2013-06-07 12:39:24
【问题描述】:

我写了一个要求用户输入的函数,如下所示:

function is_confirmed {

    read -rs -k 1 ans

    if [[ "${ans}" == "n" || "${ans}" == "N" ]]; then
        printf "No\n"
        return 1
    fi

    if [[ "${ans}" == "y" || "${ans}" == "Y" ]]; then
        printf "Yes\n"
        return 0
    fi

    # here is my actual problem!!! this doesnt work when user input is blank!
    if [[ "${ans}" == "" ]]; then
        printf "Yes!\n"
        return 1
    fi

    # Output is Damn!
    printf "Damn"
    return 1
}

到目前为止效果很好,但是,我想将“yes”设置为默认答案,所以当用户什么都不输入并按回车键时,它应该回退到“yes”,所以我尝试使用|| "$ans" == ""但这仍然回到“该死”

怎么来的?当我在函数末尾echo $ans 时它是空的...

编辑 1:

会发生这样的事情:

e_ask "Are you sure you want to install?\nWarning: This may override some files in your home directory."

if is_confirmed; then
    echo "Great!"
else
    e_error "Aborting..."
fi

功能如下:

function e_ask {
    printf "\n$1\n"
    printf "(Y/n): "
}

function e_warn {
    printf "Warning: $1\n"
}

function e_error {
    printf "Error: $1\n"
    exit 1
}

【问题讨论】:

    标签: macos bash shell zsh ksh


    【解决方案1】:

    当您想要考虑许多不同的值和一个默认值时,case 会更好

    功能 is_confirmed {
    
        读 -rs -k 1 ans
    
        案例“${ans}”在
        y|Y|$'\n')
            printf "是\n"
                返回 0
            ;;
    
        *) # 这是默认的
            printf "否\n"
                返回 1
    
        经社理事会
    
    }

    【讨论】:

    • 这不能回答我的问题。当我在 shell 中没有输入任何内容并按回车键时,$ans 应该是一个空字符串,$ans == "" 仍然回退到“该死”。
    • @MartinBroder 对不起,我误会了。如果输入N 或n,是否要打印“No”,如果输入y、Y 或什么都不打印,是否要打印“Yes”?在这种情况下,您只需更改默认大小写或将y|Y 替换为y|Y|""。
    • 没问题,是的,我想在输入为 Y,y 时打印“是”,在输入为 N,n 时打印“否”或其他否则(a,b,c ...)
    • 非常感谢,我更新了我的问题,这正是我的问题。 "" 不起作用。 ://
    • @MartinBroder 它实际上不是一个空字符串,而是一个换行符,我已经更新了答案,现在应该可以了。
    【解决方案2】:

    问题在于您如何使用 [[ 内置函数编写条件。

    您需要将条件更改为:

    function is_confirmed {
    
        read -rs -k 1 ans
    
        if [[ "${ans}" == "n" ]] || [[ "${ans}" == "N" ]]; then
            printf "No\n"
            return 1
        else if [[ "${ans}" == "y" ]] || [[ "${ans}" == "Y" ]]; then
            printf "Yes\n"
            return 0
        else if [[ -z "${ans}" ]]; then
            printf "Empty\n"
        else
            printf "Damn\n"
        fi
    
        return 1
    }
    

    解释一下,[[ 内置函数只测试一个条件,但您可以将[[ 的多个实例与&& 和|| 链接起来。相比之下,您的代码尝试在 [[ 中测试 2 个条件,并使用 || 作为 C/C++ 用法。

    更多详情请见help [[ 或man bash

    【讨论】:

    • 那不是问题 :) 当我将 [[ "$ans" == "" ]] 添加到是的答案时,当用户输入什么都不是时,它会退回到“该死”,我怀疑它会退回到是
    • @MartinBroder 我已经添加了条件,以防$ans 为空且以上都不是。根据需要添加您的作业。
    【解决方案3】:

    只需在函数开头添加默认变量:

    function is_confirmed {
    
        ans="y"
    
        echo "Put your choice:"
        read $ans
    
    
    }
    

    如果没有输入任何内容,将保留默认值。

    【讨论】:

    • 赞成(简洁!),但这有一个严重的缺陷:READ 似乎事先明确了答案。 KEYPATH="$HOME/.ssh/id_rsa.pub" #echo "Path to public key file (leave empty for $KEYPATH)?" read -rt 20 -p "Path to public key file [$KEYPATH]? " KEYPATH [[ -f $KEYPATH ]] || echo "Not a file: $KEYPATH. Exiting." 如果 $KEYPATH 与 read 调用一致,Bash 会抱怨标识符无效。我不得不使用默认符号和另一个变量:DEFAULT_KEYPATH="$HOME/.ssh/id_rsa.pub" read -rt 20 -p "Path to public key file [Enter for $DEFAULT_KEYPATH]? " INPUT KEYPATH=${INPUT:-$DEFAULT_KEYPATH}
    猜你喜欢
    • 2014-04-19
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 2017-09-06
    • 2012-10-01
    • 2020-12-30
    • 1970-01-01
    相关资源
    最近更新 更多