【问题标题】:bash interactive menu, exit on empty inputbash交互式菜单,空输入退出
【发布时间】:2015-07-02 23:06:25
【问题描述】:

我试图拼凑一个脚本来列出不同的 jws 目录,并允许用户在继续编辑目录中的 jnlp 文件之前选择不同的客户端目录。我的编辑部分正在工作,我的菜单大部分都在工作;做出选择后,我无法弄清楚如何退出循环。

我希望它在没有选择数字的情况下按 ENTER 键退出,然后继续执行脚本的下一部分。

function update_jnlp
{
 while :
  do
 # JNLP update submenu

options=($(ls /tmp/test/ | grep "jws$"))

menu() {
    clear
    echo "Locally installed jnlps:"
    for i in ${!options[@]}; do
       printf "%3d%s) %s\n" $((i+1)) "${choices[i]:- }" "${options[i]}"
    done
    [[ "$msg" ]] && echo "$msg"; :
     }

prompt="Check an option (again to uncheck, ENTER when done): "
    while menu && read -rp "$prompt" num && [[ "$num" ]]; do
       [[ "$num" != *[![:digit:]]* ]] &&
       (( num > 0 && num <= ${#options[@]} )) ||
       { msg="Invalid option: $num"; continue; }
       ((num--)); msg="${options[num]} was ${choices[num]:+un}checked"
       [[ "${choices[num]}" ]] && choices[num]="" || choices[num]="+"
    done
printf "You selected"; msg=" nothing"
    for i in ${!options[@]}; do
       [[ "${choices[i]}" ]] && { printf " %s" "${options[i]}"; msg=""; }
    done
    done
    for i in ${choices[@]}; do
            printf "%s\n" ${choices[@]};
    echo "fun"
        done
        echo "@msg"
# here is the script to edit the files now contained as ${choices[@]}
 }

我意识到我在一个菜单循环中,并且我需要验证来自读取命令 = "" 的输入或 $prompt 输入是否为空,我假设我从那里中断

【问题讨论】:

  • "我意识到我在一个菜单循环中,并且我需要验证来自读取命令 = "" 的输入或 $prompt 输入是否为空,我假设我从那里“你试过吗?
  • 我有,但我想我只是无法正确获取操作顺序或语法。
  • $prompt input is null $prompt 必须为“null”的值是多少?尝试打印它并查看它包含的内容,如果您的意思是未设置,请尝试[ "$prompt" ] || breakread 存储在 $num 中。要查看它是否为空字符串,请使用完全相同的[ "$num" ] || break

标签: bash shell scripting


【解决方案1】:

请格式化您的代码,使其更具可读性。就目前而言,不稳定的缩进使其几乎无法阅读。好吧,缩进结合在另一个函数内部的循环体中定义一个函数,以及我见过的一些更难以理解的循环体。 (我以为我已经看到了很多;显然,我还有一些学习要做。)

代码格式更正统,你有:

function update_jnlp
{
    while :
    do
        # JNLP update submenu
        options=($(ls /tmp/test/ | grep "jws$"))

        menu() {
            clear
            echo "Locally installed jnlps:"
            for i in ${!options[@]}; do
               printf "%3d%s) %s\n" $((i+1)) "${choices[i]:- }" "${options[i]}"
            done
            [[ "$msg" ]] && echo "$msg"; :
        }

        prompt="Check an option (again to uncheck, ENTER when done): "
        while menu && read -rp "$prompt" num && [[ "$num" ]]; do
            [[ "$num" != *[![:digit:]]* ]] &&
            (( num > 0 && num <= ${#options[@]} )) ||
            { msg="Invalid option: $num"; continue; }
            ((num--)); msg="${options[num]} was ${choices[num]:+un}checked"
            [[ "${choices[num]}" ]] && choices[num]="" || choices[num]="+"
        done

        printf "You selected"; msg=" nothing"
        for i in ${!options[@]}; do
            [[ "${choices[i]}" ]] && { printf " %s" "${options[i]}"; msg=""; }
        done

        echo "$msg"    # Added
        break          # Added

    done

    for i in ${choices[@]}; do
        printf "%s\n" ${choices[@]};
        echo "fun"
    done
    echo "@msg"
    # here is the script to edit the files now contained as ${choices[@]}
}

当我运行它时,我选择了 1、3、7,然后按回车键,输出的最后一页如下所示:

Locally installed jnlps:
  1+) abc.jws
  2 ) def.jws
  3+) ghi.jws
  4 ) jkl.jws
  5 ) mno.jws
  6 ) pqr.jws
  7+) stu.jws
  8 ) vwx.jws
  9 ) xyz.jws
stu.jws was checked
Check an option (again to uncheck, ENTER when done): 
You selected abc.jws ghi.jws stu.jws
+
+
+
fun
+
+
+
fun
+
+
+
fun
@msg

如果没有添加break,您将看不到选择了什么,因为外部while : 循环太快地清除屏幕。添加 echo "$msg" 后,您将获得所需的 You selected nothing

while : 主循环之后的材料显然没有最终确定。

事实上,你根本不需要while : 循环,或者不完整的材料。你可以使用:

function update_jnlp
{
    # JNLP update submenu
    options=($(ls /tmp/test/ | grep "jws$"))

    menu() {
        clear
        echo "Locally installed jnlps:"
        for i in ${!options[@]}; do
           printf "%3d%s) %s\n" $((i+1)) "${choices[i]:- }" "${options[i]}"
        done
        [[ "$msg" ]] && echo "$msg"; :
    }

    prompt="Check an option (again to uncheck, ENTER when done): "
    while menu && read -rp "$prompt" num && [[ -n "$num" ]]; do
        [[ "$num" != *[![:digit:]]* ]] &&
        (( num > 0 && num <= ${#options[@]} )) ||
        { msg="Invalid option: $num"; continue; }
        ((num--)); msg="${options[num]} was ${choices[num]:+un}checked"
        [[ "${choices[num]}" ]] && choices[num]="" || choices[num]="+"
    done

    printf "You selected"; msg=" nothing"
    for i in ${!options[@]}; do
        [[ "${choices[i]}" ]] && { printf " %s" "${options[i]}"; msg=""; }
    done
    echo "$msg"

}

这仍然相当难以理解,但至少它或多或少地运作良好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2013-11-21
    • 1970-01-01
    相关资源
    最近更新 更多