bash交互式菜单,退出空输入

时间:2015-07-02 23:06:26

标签: bash shell scripting

我尝试拼凑一个脚本来列出不同的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[@]}
 }

我认识到我处于一个菜单循环中,我需要验证来自read command =“”的输入或者$ prompt输入是否为null,我假设我从那里打破

1 个答案:

答案 0 :(得分: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"

}

这仍然是不可理解的,但至少它或多或少地起作用。