Bash脚本,案例陈述和子菜单

时间:2011-01-18 19:46:00

标签: bash

我希望运行一个带有case语句的脚本,从而在脚本之间选择其他选项列表(类似子菜单):

#!/bin/bash

echo "Your choice ?"
echo "1) Foo"
echo "2) Bar"
echo "3) Stuff"
read case;

case $case in

#and this is where I would like to allow 
#(here a simplified example I do not manage to code)

1) What script ?    # may I use another case statement ?
    a) Foo1;;
    b) Foo2;;
2) What script ?    # d°
    a) Bar1;;
    b) Bar2;;
    c) Bar3;;

esac

Foo1,Foo2,Bar1,Bar2和Bar3实际上是bash脚本,我想在脚本中调用,例如sh Foo1。

我该如何进行: 我可以在案例陈述中包含案例陈述(如果选择很多,则优于if陈述)? 如何从另一个脚本中调用脚本?

提前感谢您的帮助

ThG的长度

2 个答案:

答案 0 :(得分:4)

是的,您可以嵌套case语句。您还应该考虑使用select语句而不是所有echoread语句。

options=("Option 1" "Option 2" "Option3" "Quit")
optionsprompt='Please enter your choice: '

sub1=("Option 1 sub 1" "Option 1 sub 2")
sub1prompt='Please enter your choice: '

PS3=$optionsprompt
select opt in "${options[@]}"
do
    case $opt in
        "Option 1")
            echo "you chose choice 1"
            PS3=$sub1prompt
            select sub1opt in "${sub1[@]}"
            do
                case $sub1opt in
                    "Option 1 sub 1")
                        echo "you chose choice 2"
                        ;;
                    "Option 1 sub 2")
                        echo "you chose choice 2"
                        ;;
                 esac
            done
            ;;
        "Option 2")
            echo "you chose choice 2"
            ;;
        "Option 2")
            echo "you chose choice 3"
            ;;
        "Quit")
            break
            ;;
        *) echo invalid option;;
    esac
done

第一级菜单如下所示:

1) Option 1
2) Option 2
3) Option3
4) Quit
Please enter your choice:

然而,这可能会很快变得非常毛茸茸。最好将其分解为内部select/case语句位于单独函数中或被抽象化的函数,以便您可以传递参数来控制它们。

要调用另一个脚本,您可能需要设置一个包含该目录的变量。它看起来像这样:

basedir=/some/path

case ...
...
    $basedir/Foo    # call the script

答案 1 :(得分:4)

Dennis' answer应该做你想做的事。只是为了说明如何使用函数来实现它,以便使脚本更具可读性:

function which_foo {
    local foo_options=("foo1" "foo2" "cancel")
    local PS3="Select foo: "

    select foo in "${foo_options[@]}"
    do
        case $REPLY in
            1) ./foo1.sh
               break ;;

            2) ./foo2.sh
               break ;;

            3) break ;;
        esac
    done
}

ACTIONS=("foo" "bar" "quit")
PS3="Select action: "

select action in "${ACTIONS[@]}"
do
    case $action in
         "foo") which_foo
                break ;;

         "bar") which_bar # Not present in this example
                break ;;

        "quit") break ;;
    esac
done

顺便说一句,请注意:

  • $REPLY case内使用which_foobreak自动设置为用户选择的号码,而不是选项的文字。
  • 在每个case选项中使用select。没有它们,select会让您进入循环,因此系统会要求用户再次输入选项。
  • PS3永远不会为您更改{{1}}的值,因此您必须在菜单的不同级别之间切换时自行完成。