2011-01-18 52 views
2

我想用一个case语句脚本之间导致的选择,其他名单(排序的子菜单)之间选择运行一个脚本: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。

我该如何进行: 我可以在case语句中包含case语句吗(比if语句更好,如果选项很多)? 如何从另一个脚本中调用脚本?

在此先感谢您的帮助

ThG的长度

+0

要从脚本中调用脚本,只需调用其他脚本的名称,就像从命令行执行一样。 – chrisaycock

回答

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 

顺便说一句,注意事项:

  • which_foocase使用$REPLY,这是自动设置为用户选择的号码,而不是选项的文本。
  • 使用break每个case选项。如果没有它们,select会使您处于循环状态,因此用户将被要求再次输入选择。
  • select永远不会改变你的价值PS3,所以你必须自己做,当你的菜单的不同层次之间切换。
+0

也感谢你(请参阅我对丹尼斯的“回答”)......和相同的答案 – ThG

+0

+1表示变化并提供更多细节。你可以在你的函数中使用'local PS3',这样你就不必保存和恢复“全局”的值。你也可以把'FOO_OPTIONS'放在这个函数中,并使它成为'local'。使用'$ REPLY'而不是'select'变量(在你的例子中为'$ action'),但代码的可读性较差。如果你使用'break',你可能仍然希望在它周围放置一个外部'while'来进行一些用途。 –

+0

我不知道'本地PS3'。我已经相应地更新了我的示例。感谢丹尼斯的提示。 – Rodrigue

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 
+0

非常感谢您的快速回答。尽管如此,我还没有“抓住”它;我需要考虑一下(这意味着作为一个学习者,我必须先做一些家庭作业......);我会尽快回复(希望不需要太多时间) – ThG

+0

和@Rodrigue:认为它已经结束了,偶然发现了几次(例如,我忘记了为我的脚本修改X ...),谢谢对你来说,两个终于做到了。再次感谢 – ThG